We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello,
While porting legacy code from an LPC2103 to a LPC1765 Cortex processor within the Keil environment I came accross the need to implement the linker zero_init attribute for a single byte variable as described by the following links:
(1) infocenter.arm.com/.../index.jsp (2) http://www.keil.com/support/docs/3480.htm
The purpose of this variable was to be read on a system reset to determine whether the reset event was intentional or not and execute additional code if the reset event was intentional (ie: go into the ISP bootloader). As debugging shows, system reset causes RW variables to be zeroed when performing the BX from statup .asm code into application main().
However, when I implemented the change within a 'C' file as follows:
UINT8 Startup_Flags __attribute__( ( section( "NoInit"), zero_init) );
and linker scatter file as follows:
RW_IRAM1 0x10000000 UNINIT 0x00000100 { ;no init section *(NoInit) }
I was getting inconsistent results with the variable every time the reset event occurred, even though it was placed in the declared UNINIT memory region according to the memory map:
Startup_Flags 0x10000000 Data 1 main.o(NoInit) SystemFrequency 0x10000100 Data 4 system_lpc17xx.o(.data)
As the region was declared to be a size of 256, I decided to add a dummy declaration along with the original to troubleshoot the issue further, as follows:
// Zero initialization section UINT8 Startup_Flags __attribute__( ( section( "NoInit"), zero_init) ); UINT8 NoInitUnused[255] __attribute__( ( section( "NoInit"), zero_init) );
This initially showed promise until it too failed periodically (the variable Startup_Flags was located at 0x10000000 according to the memory map).
Startup_Flags 0x10000000 Data 1 main.o(NoInit) NoInitUnused 0x100000ff Data 255 main.o(NoInit)
I then tried swapping the declarations in order to move the location of the variable to the LAST entry in the region (ie: 0x100000FF) as follows:
// Zero initialization section UINT8 NoInitUnused[255] __attribute__( ( section( "NoInit"), zero_init) ); UINT8 Startup_Flags __attribute__( ( section( "NoInit"), zero_init) );
NoInitUnused 0x10000000 Data 255 main.o(NoInit) Startup_Flags 0x100000ff Data 1 main.o(NoInit)
Now the results I am getting are consistently correct (so far) and I can invoke the ISP bootloader whenever the variable has the proper bit flag set.
The caveat seems to be that this zero_init command CAN be used and function properly, but under certain undocumented? conditions (ie: MUST have 8 declared bytes within the region and declaration order seems to be important). Has anyone else run into this issue? If so, how was it corrected? Or am I just misreading the documentation contained within the posted links? Thank you.