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
Yes, you need to specify "volatile" in the declaration in the header. This is the only way other modules know that the variable should be treated as volatile. If the header does not so inform them, then when code is generated for those other modules, it will not treat the variable as volatile. (Although Keil does do some whole-program analysis, C is traditionally a "separately compiled" language; one .c file doesn't really know what's going on inside another.)
The main effect of declaring a variable "volatile" is on the optimizer.
"Volatile" tells the compiler that it cannot safely assume that the value of the variable does not change when the current code isn't reading or writing it. That is, the variable may represent a register where the hardware changes the value, it may represent an address where the actual read/write bus cycles are important to trigger activity and thus all of which must appear on the bus. Or it may be that an interrupt handler or another task shares the value and can change the variable by interrupting the current function.
In short, "volatile" forces the compiler always to write back to the variable or read from it, rather than using common optimizations such as realizing that the value is already in a register, and using that value instead of the actual variable.
Given that, it's easy to see why changing the declarations as "volatile" affects the code size. The compiler has to generate more reads and writes to volatile variables than normal ones.