Hi everybody,
I would like to force some RAM variables to be saved by compiler in spefic address range (for example from 0x100h to 0x200h).
I know it is possible to use
#pragma address
directive, but this means I have to calculate all the address for the variables.
I'm looking a solution like using
#pragma section
directive but I'm struggling how to setup the "C/C++ Build->Settings->Tool Settings->Linker->Section" linker menu in e2studio.
I tried the following test
#pragma section SafetyRAM uint16_t a = 0x0000U; uint16_t b = 0xFFFFU; #pragma section
And I added a section in linker option with name "SafetyRAM" and address 0x100. Compiler gives me a warning:
W0561100:Cannot find "SafetyRAM" specified in option "start"
How can I solve? Thanks
There are 2 solutions to put variables and constants on a specific location. The first option is with the pragma address, use as follow:
#pragma address a=0x0100 uint16_t a; main(){ a = 0; }
The drawback is that you need to initialise the variable yourself. The compiler doesn’t generate code for this. And you need to manually calculate the address if you have multiple variables, but you can solve this by using a struct.
The second option is with the pragma section. For this you need to add a section entry in the linker section viewer "C/C++ Build->Settings->Tool Settings->Linker->Section" like JanekD shows. Set the address and your section name. Add a ‘*’ after the name If you don’t know the size or have multiple variables withe different width. For example, use “SafetyRAM_D*”. The compiler will then generate the necessary sections SafetyRAM_D_1 (8-bit), SafetyRAM_D_2 (16-bit) and/or SafetyRAM_D (32-bit) to put the variables in properly aligned sections.
The section that yo need to create depends on how the variable is initialised. If the variable has no value assigned on definition, then you must create a B section in RAM. If the variable has a value assigned on definition (like your case), then you need to create an R section in RAM and a D section in ROM.If the D section in ROM doesn't need a specific address, then just leave it blank, the compiler will put it it right after the previous section. And for a constant you need to define a C section in ROM.
In your case add SafetyRAM_R* in RAM and SafetyRAM_D* in ROM
If you defined a D section then you also need to add a symbol link to link the D and R section. For this goto "C/C++ Build->Settings->Tool Settings->Linker->Section->Symbol file" and scroll down to the "ROM to RAM mapped section" . In your case you need to add the lines:SafetyRAM_D=SafetyRAM_R, SafetyRAM_D_1=SafetyRAM_R_1 and SafetyRAM_D_2=SafetyRAM_R_2.
A *_8 section is only needed if you use double variables on a RXv3 with DFPU.
Now we must also change the startup code to properly initialise the variables on startup. Open the "dbsct.c" file in the generate directory and search for "_DTBL[]" table and changed it to:
#pragma section C C$DSEC extern const struct { _UBYTE *rom_s; /* Start address of the initialized data section in ROM */ _UBYTE *rom_e; /* End address of the initialized data section in ROM */ _UBYTE *ram_s; /* Start address of the initialized data section in RAM */ } _DTBL[] = { { __sectop("D_8"), __secend("D_8"), __sectop("R_8") }, { __sectop("D"), __secend("D"), __sectop("R") }, { __sectop("D_2"), __secend("D_2"), __sectop("R_2") }, { __sectop("D_1"), __secend("D_1"), __sectop("R_1") }, { __sectop("SafetyRAM_D"), __secend("SafetyRAM_D"), __sectop("SafetyRAM_R") }, { __sectop("SafetyRAM_D_1"), __secend("SafetyRAM_D_1"), __sectop("SafetyRAM_R_1") }, { __sectop("SafetyRAM_D_2"), __secend("SafetyRAM_D_2"), __sectop("SafetyRAM_R_2") } };
If you created a B section then you need to add the sections to the "_BTBL[]" table.
Now add the variable definition like this in your code, don't forget the 'D'. This tells the compiler that the "D" section is altered to the "SafetyRAM_D" section.
#pragma section D SafetyRAM_D //alter D section to SafetyRAM unsigned short a = 0x0000U; unsigned short b = 0xFFFFU; #pragma section //restore all sections to default name
Just watch out that the order of multiple variables in a section is not guaranteed. Use a single struct if yo want a fixed order.
It takes some time to properly setup new sections. But once they are correct you can add multiple variables across several source files.
Hello NGE,
Thank you for complete explanation. I will review your description step-by-step. Meanwhile, I'm studying the CCRX manual in order to have a better understand of the various sections.
For sure I have both unitialized and initialized RAM variable so I need both B and D sections.