This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problem using "#pragma small" and the volatile dilemna

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

Parents
  • 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

Reply
  • 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

Children
  • 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 ?

    Regards
    Aman

  • 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

    Regards
    Aman

  • 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

    Regards
    Aman