ROM variable not getting the defined value - c

I'm working on developing a software stack for automotives based on a Renesas RL78 controller. Getting straight into the problem, variables declared const(ROM variables) are not getting initialized with the defined value.
Ex : const uint8 var_test = 1;
On the other hand, global,static variables are getting initialized.
Is this the problem with the startup code? kindly suggest...

Like the other answers, probably your const variable isn't placed into a ROM section.
You need to tell the compiler/linker where to place it.
With an IAR toolchain it's probably something like
#pragma SET_CONST_PAGE(ConstArea)
const int myVariable1=42;
const int myVariable2=4711;
#pragma SET_DEFAULT_CONST_PAGE
But that your debugger doesn't show the correct value is another problem, it's possible that the variable is optimized.
To be sure what happens look into the map file and look (with the debugger) at assembly level what is done.

Usually const isn't enough of a qualifier to allow variables to go in ROM (you could always cast it away). Usually you need to mark the variable with something compiler specific to indicate what you want, or perhaps a compiler flag to indicate your intention. I believe the IAR compiler uses the # symbol to allow you to specify a location for a variable. I'd check its manual :-)

Non-static const variables are not "constant enough" to go into ROM, typically. If you inspect a function using such variables, you'll probably see that the function's preamble has code to initialize the variables on the local stack.
Of course, startup code can't fix this, since it (by definition) can't write the values into ROM.

Const objects are not required by the language to be located in ROM, but merely to be read-only after initialisation, and for reasons of performance on some targets for example a compiler might deliberatly avoid doing so.
The IAR RL78 C/C++ Compiler Reference Guide states :
"Static and global objects declared const and located in far memory are allocated in
ROM. const declared saddr objects are allocated in RAM and initialized by the runtime
system at startup. const declared near objects are allocated according to the option
--near_const_location.
In C++, objects that require runtime initialization cannot be placed in ROM."
Refer to the #pragma location directive or the # operator in the manual, these allow placement at absolute addresses or within named memory segments.

Related

Volatile is not preventing a variable from being optimized

As I know, "volatile" keyword is used to prevent compiler to optimize an unused variable. I am working with an STM32 board and I declare and initialise a variable as follows;
volatile uint32_t errorCallbackCounter = 24 ;
And never use it again.
While debugging, this variable is not seen. I am checking it with STMStudio( a real time variable watcher ) and when I want to import variables, the adress of errorCallbackCounter is seen as 0x0.
But when I use it in anywhere, it becomes visible.
So volatile keyword is not doing its job or -more probably- I know something wrong about it.
Thanks in advance.
Variables that are never used can be dropped by the linker
The volatile keyword affects the code that accesses the variable, preventing the access from being rearranged or dropped by the compiler. The line above is a variable definition with an initializer, that doesn't count as an access, it gets arranged before main() starts. But if it isn't referenced by accessible program code, isn't accessed at all, the linker thinks that it's safe to remove it, no one would notice.
You can however mark the variable as "it's needed no matter what" with
__attribute__((used))
placed at the end of the definition. This works with gcc, other compilers might have another directive for it. There is also a linker option that I can't recall right now to include all unused data sections in the executable.
volatile means the system will load this variable from memory each time it is accessed.
The compiler is not allowed to store the data directly into an register.
The volatile keyword prevents the compiler from performing optimization on code involving volatile objects, thus ensuring that each volatile variable assignment and read has a corresponding memory access. Without the volatile keyword, the compiler knows a variable does not need to be reread from memory at each use, because there should not be any writes to its memory location from any other thread or process.

Can const variables be modified from elsewhere not known at compile time

If const is a compile time construct, it would mean that only the compiler will ensure that for example if a variable is declared as const, this variable is read only and it is not attempted to be modified by the rest of the code being compiled?
What about if a const variable is a global variable in our code, and our code links to a dynamic library at run time which attempts to write to it? , or if an ISR attempts to update it, which was not in our compiled code?
I believe the compiler can mark const variables to be loaded into the read only data section which would prevent any changing of the variable, but what if it doesn't?
Thanks
the compiler will ensure that for example if a variable is declared as const, this variable is read only and it is not attempted to be modified by the rest of the code being compiled?
Yes, as far as the compiler is able to tell. If your code attempts to write to a const-qualified variable, you will get a compiler error. If you dodge type correctness by for example casting away the const qualifier, then all bets are off.
What about if a const variable is a global variable in our code, and our code links to a dynamic library at run time which attempts to write to it? , or if an ISR attempts to update it, which was not in our compiled code?
Then it should not have been const qualified, or the compiler will make strange assumptions and generate incorrect code.
However, there exist cases where a const variable may be updated from the outside world - it could be a read-only hardware register or an EEPROM memory cell etc.
To prevent the compiler from doing strange assumptions in such special cases, you can then combine const and volatile. All variables that may be updated from an external source, such as hardware or an ISR, should therefore always be declared as volatile.

Is a C compiler obligated to always reload const value from memory?

I have a const variable in my embedded C program. It's defined and initialized with 0 in program code. It's placed in a special ROM area via linker script. One can change the content of the special area via special programming procedure, but it cannot be changed during main program execution.
The question is whether I have to declare the constant as volatile. If it's not marked as volatile, is the compiler allowed to replace all references to it with 0? Or is it obligated to load it at least once during program execution?
It looks like your variable is really a constant (i.e. doesn't change during program execution) with a value unknown to the compiler. If this is the case, you can declare it like this:
extern const int variable;
(i.e. without volatile and without an initializer) and let the linker script or other tools set up the correct value.
The compiler will then be permitted to load it and potentially leave it in a register forever, but not replace it by 0 or any other value at compile time.
If marked as volatile the compiler is obliged to load it from memory every time it needs it value.
If not marked as volatile, the compiler may load it once from memory, store it in a register, and use this register instead of loading it again.
A not-optimizing compiler may do this - but it also may, stupidly, load it every time. (As not reloading is in fact an optimization in itself.)
Optimizing compilers may notice the const and decide it can be compiled with its real, literal value; up to a point where the original constant does not appear at all in the .data section of your program. (Or maybe it does but it never gets "read".)
Since you change the value in a linker script, the compiler cannot "know" the value got changed after compiling. In that case, use volatile: the only way to tell the compiler not to trust that the value is known when compiling.

const keyword for a variable(SRAM or On-Chip Flash)?

Variables declared in a code(static or global) are copied to the On-Chip Flash(ROM) first along with the entire application code. Then they are inturn copied to the SRAM.
Static and Global variables are assigned an address in SRAM(not Stack) whereas local variables in a function are assigned on to the stack(part of SRAM).
My doubt: By declaring a variable as "const" type, does it place the variable in On-Chip Flash(ROM), so that i can save SRAM or are const data also copied to the SRAM though their value doesnt change? (LPC17xx Memory Architecture,Keil IDE to code)?
Update: const in ROM- In this link,the answer given by Mike Kleshov confirms that const data is placed in the Onchip Flash(using Keil compiler).
Yes -- on most microcontrollers, declaring a variable as const will cause it to be stored in read-only memory.
You should consult the documentation for your specific compiler and/or linker. There is no requirement in the language definition to locate const in ROM since there is no requirement for ROM.
If in doubt you should use your toolchains specific linker directives to locate data as necessary.
Note that in C++ the semantics of const are somewhat different and it may not be possible to place an non POD object in ROM. On at least one compiler I have used it is necessary in C++ to declare a POD variable as static const to ensure that it is placed in ROM. In some cases a simple const will be placed directly in the code as if it were a literal constant.

Why cant register variables be made global?

While reading from a site a read that you can not make a global variable of type register.Why is it so?
source:
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlcpp8l.doc/language/ref/regdef.htm
In theory, you could allocate a processor register to a global scope variable - that register would simply have to remain allocated to that variable for the whole life of the program.
However, C compilers don't generally get to see the entire program during the compile phase - the C standard was written so that each translation unit (roughly corresponding to each .c file) could be compiled independently of the others (with the compiled objects later linked into a program). This is why global scope register variables aren't allowed - when the compiler is compiling b.c, it has no way to know that there was a global variable allocated to a register in a.c (and that therefore functions in b.c must preserve the value in that register).
Actually, GCC allows this. A declaration in global scope in the form:
register int foo asm ("r12");
Allocates the register "r12" (on x86_64) for the global "foo". This has a number of limitations and the corresponding manual page is probably the best reference to all the hassle global register variables would make:
http://gcc.gnu.org/onlinedocs/gcc/Explicit-Reg-Vars.html
Because it would be senseless. Global variables exist all the time the application is working. There surely is no free processor register for such a long time ;)
The register keyword has a different meaning than what its name seems to indicate, nowadays it has not much to do with a register of the processing environment. (Although it probably once was chosen for this.) The only text that constrains the use of a variable that is declared with register is this
The operand of the unary & operator
shall be either a function designator,
the result of a [] or unary *
operator, or an lvalue that designates
an object that is not a bit-field and
is not declared with the register
storage-class specifier
So it implements a restriction to automatic variables (those that you declare in a function) such that it is an error to take the address of such a variable. The idea then is that the compiler may represent this variable in whatever way pleases, as a register or as an immediate assembler value etc. You as a programmer promise that you wouldn't take an address of it. Usually this makes not much sense for global variables (they have an address, anyhow).
To summarize:
No, the register keyword is not
ignored.
Yes, it can only be used for stack
variables if you want to be standard conformant
Originally, register variables were meant to be stored in processor registers, but global variables have to be stored in the data or the BSS section to be accessible from every function. Today, compilers don't interpret the register storage class strictly, so it remains largely for compatibility reasons.
The register word is used in C/C++ as request to the compiler to use registers of processor like variables. A register is a sort of variable used by CPU, very very fast in access because it isn't located in memory (RAM). The use of a register is limited by the architecture and the size of the register itself (this mean that some could be just like memory pointers, other to load special debug values and so on).
The calling conventions used by C/C++ doesn't use general registers (EAX, EBX and so on in 80x86 Arch) to save parameters (But the returned value is stored in EAX), so you could declare a var like register making code faster.
If you ask to make it global you ask to reserve the register for all the code and all your source. This is impossible, so compiler give you an error, or simply make it a usual var stored in memory.
Some compilers provide a means of dedicating a register permanently to a variable. The register keyword, however, is insufficient. A compiler's decision to allocate the local variables for a routine in registers generally does not require coordination with anything in other source modules (while some development systems do register optimization between routines, it's far more common to simply define the calling convention so that all routines are allowed to freely alter certain registers (so a caller is responsible for saving the contents if they're needed after the function call) but must not alter others (so the called routine is responsible for saving and restoring the contents if the registers are needed in the function). Thus, a linker doesn't need to concern itself with register usage.
Such an approach is fine for local register variables, but useless for global ones. For global register variables to be useful, the programmer must generally tell the compiler which register is to be used for what variable, and make sure that such reservations are known to the compiler when compiling all modules--even those that don't use the register otherwise. This can be useful in embedded systems, especially with variables that are used by interrupts, but there's usually a very limited number (e.g. 2 or so) of such variables allowed in a system.
So do we all agree now? Do we all see that making a global variable a register variable would be a really, really bad idea? If the original C definition did not forbid it, it was probably because nobody thought anyone would actually implement it that way -- as they should not have especially back in CISC days.
Besides: modern optimizing compilers do a better job of deciding when to keep variables in registers than humans can do. If yours can't do it, then you really, REALLY need to get a better compiler.
Because they're in registers. It's a contradiction in terms.

Resources