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

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

Children