cancel
Showing results for 
Search instead for 
Did you mean: 

Initialized variable at specific location optimized out?

RAltm
Senior

Hi,

I need to place a initialized variable at the beginning of RAM. This variable won't be read or modified by the application, it's only read by the ST-Link during programming operation.

So I modified the linker script by adding a section PRJINFO (project info):

  /* Initialized data sections goes into RAM, load LMA copy after code */
  .data : 
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    KEEP(*(.PRJINFO*))  /* project information */
    . = 0x20;
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */
 
    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
  } >RAM AT> FLASH

This area is 32 byte in size and the linker shouldn't throw away this section. I created a C file which contains a 32-byte array containing some information:

uint8_t ProjectProgramVersion[32] __attribute__((section(".PRJINFO"), used)) = {
		(PRJ_SW_VER >> 20) & 0xFF,
		(PRJ_SW_VER >> 28) & 0x0F,
		(PRJ_SW_VER >> 12) & 0xFF,
		(PRJ_SW_VER >> 8)  & 0x0F,
		(PRJ_SW_VER)       & 0xFF,
		(PRJ_SW_VER_INDEV) * 0x0E
};

This should place this array in the project info section, optimizing out should be prevented by linker (KEEP keyword) and compiler (attribute used). However, it only works in the debug build. Linking the release build gives garbage when reading out the memory locations.

Any ideas what might go wrong?

Regards

13 REPLIES 13
RAltm
Senior

Hi together,

thank you for your suggestions.

Just an update: currently, it seems that the section, etc. is working also in the release build, but a power cycle is needed. After power cycle, I get the expected results. The power cycle is not needed when downloading the debug build.

Since I'm downloading with the CLI of CubeProgrammer, I've the possibility to apply reset, etc. Interestingly, no combination of connection mode (under reset, hot plug, etc.) and reset mode (software/hardware reset) enables me to get rid of the power cycle. I'd expect that a hardware reset by CLI would have the same effect as a power cycle regarding RAM initialization, etc, but it seems that's not the case.

The difference between the debug and release build (apartof optimization level) is that the release build sets RDP level 1. So, with this level it might be that the MCU core can't be started by the ST-Link and therefore the RAM isn't initialized. Still investigating, maybe it's enough to change the order of the CLI calls.

Regards

> So, with this level it might be that the MCU core can't be started by the ST-Link and therefore the RAM isn't initialized.

RAM is usually initialized in the startup code, somewhere between the reset vector and the call to main.

This startup code is usually a project-specific copy of the toolchain's default startup template code, for easy modification.

Setting RDP to level 1 means that any attempt to connect with a JTAG/SWI programmer causes the CPU to halt. The only remedy is power cycle. So it should be that any time you use the ST-Link to set RDP=1 you will need a power cycle. If instead the release version of your firmware programmed RDP=1 itself, the CPU could then automatically reboot into the protected mode. This is what ST's SBSFU (Secure Boot, Secure Firmware Update) code does.

@Bob S​ 

This is exactly the behaviour I'm observing, the MCU couldn't be started after setting RDP = 1. Thank you for clarification.

The firmware doesn't set the RDP, it's included in the firmware image at the corresponding positions of the option bytes.

Too bad that the reset option of the CLI doesn't allow to let the CPU run after reset.

Changing the order of my CLI calls made it possible to read the right values - not my favourite solution, but it works now.

Regards