We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello gurus!
I am developing code for an 8051 variant with 2K of on-chip XDATA and 32K of flash.
Question 1:
I have compiled the entire project with memory model as "large". I am trying to see the effect of using "small" memory model for a specific file. What I have learned from Keil's help is, and I quote "These directives apply to the entire source file and may be specified only once on the command line or at the beginning of the source file using the #pragma statement. They may not be used more than once in a source file. "
I am trying to use #pragma small at the top of my C file, but it gives the error:
ACTION: PARSING INVOKE-/#PRAGMA-LINE LINE: #pragma SMALL ERROR: RESPECIFIED OR CONFLICTING CONTROL
I have even tried specifying "small" in the individual options for the file (under C51 tab), but to no avail. What is my mistake ? What is the correct method ?
Question 2:
I have about 1.9KB of variables in XDATA, which have been declared as "volatile unsigned char xdata bla_bla;". In order to use them in other files, their respective "extern" declarations are written in a header file and included in all C files, e.g.:
"extern volatile unsigned char xdata bla_bla;"
Is there a need to specify "volatile" keyword in the extern declaration as well ? If I remove the "volatile" keyword from the "extern" declaration, I save about 400 bytes of source code. When "volatile" has been specified as part of the actual definition, why does "volatile" in extern affect the code size ?
Hoping a quick response from all the gurus....
Regards Aman
and then explicitly add LARGE for those files that should have it
a much better idea: "and then explicitly add xdata for those variables that should have it".
for instance a process like for (index = 0; index < 333; index++) { ... xdata = ....
will run a whole lot faster than model LARGE for (index = 0; index < 333; index++) { ... = ....
because 'index' stay in DATA in the first example
Erik
Thanks for the advice Erik.
BTW, won't the IDE give me the same problem if I select "small" as the memory model and try to give "large" for a specific file ?
Hi All,
What is the meaning of "You may, however, specify which memory model to use for a single function by including the small, compact, or large function attribute in the function declaration." (extracted from the C51.pdf by Keil)
Question regarding #pragma regparms: I have one more question regarding the large memory model. When the large model is selected, then by default all function parameters are passed on XDATA. Is it that if I have the large memory model selected, I cannot use "#pragma regparms" to pass parameters in registers for a particular function ? I am somehow unable to do it. I encapsulated my function like this:
#pragma save #pragma regparms void foo (unsigned char var) { bla bla } #pragma restore
However, when I check the map file, the location of variable has not changed, it is still passing on xdata. Where am I wrong ?
Question regarding overlaying:
"The total stack space of the classic 8051 is limited: only 256 bytes maximum. Rather than consume stack space with function parameters or arguments, The Cx51 compiler assigns a fixed memory location for each function parameter. When a function is called, the caller must copy the arguments into the assigned memory locations before transferring control to the desired function."
Now, the question is, is there any linker option where same memory location (in XDATA or IDATA) can be used for passing parameters to two or more functions IF I am sure that they can NEVER be called at the same time (through ISR or whatever) and the MCU does have an OS running on it ?
One problem has been solved. I had been using "small" model for many functions, but just could not see it. Its easy:
void foo (unsigned char) small;
void foo (unsigned char) small {
}
This is what I was looking for, i.e. small model function in a large model project
Overlaying problem also solved. Linker has now started to overlay variables in DATA. I did not do anything except that I used "small" with some functions. For some functions it did by itself.
Only REGPARMS mystery remains to be solved