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.