Hi,
in my current project at work we see a strange behavior when flashing the controller with the Segger J-Link, as it erases (or writes 0xFF) to memory area(s) which aren't defined to be programmed in the flashed Intel Hex-file.
Target processor is STM32 F407IGT6.
We have a minimal software (called backup-firmware in the memory layout graph) which basically manages entry to the controller's bootloader, CRC-check and some other small things.
Also there's a block Main SW (main application) and an update marker section, which stores a 4-byte magic word for interaction between Backup-FW and Main-SW.
The hex file for the Backup-FW flashes the whole memory area with 0xFF to ensure a complete blank initial state and writes the update marker to NORMAL_STARTUP = 0x00000000. This will be later done in factory before writing production data.
The hex file for the Main-SW flashes only the Main-SW area (along with a pre-calculated CRC-32 by srec_cat).
Flashing the Main-SW, regardless if using the ST Cube IDE, Segger JFlashLiteExe or Segger JLinkExe (Linux-Environment Ubuntu 20.04, JLink_Linux_V722b utilities)
overwrites the update marker at 0x080F F800, which it shouldn't.
Googling around, I found the following threads here in forum
[SOLVED] J-link base without erase
[SOLVED] JFlash overwrites incorrect pages
which lead to playing around with the RMW threshold as described in
wiki.segger.com/J-Link_Command…#SetFlashDLNoRMWThreshold.
Setting in CubeIDE (*) the threshold to 0xFFFF which should write every blocks < 64 kB with Read-Modify-Write (as I understood) didn't change anything unfortunately although I'm pretty sure the option got accepted by the GDB server:
(* Debug profile -> Startup -> Initialization Commands: monitor exec SetFlashDLNoRMWThreshold 0xFFFF)
Display All
Interesting fact is, I've also a ST-Link v2 ISOL debugger here with which I did some experiments:
It
- behaves the same as the J-Link when flashing via CubeIDE
- behaves the same using STM32 CubeProgrammer with default settings
- behaves differently, meaning it preserves the update marker value at 0x080F F800 if the download option 'Skip flash erase before programming' is activate
I also thought it may be associated somehow with the flash page size, which is AFAIK 2 kB for our controller, but the memory layout is aligned to 2 kB blocks.
To be honest I'm completely lost at the moment, as I'm unable to tell why the J-Link (and ST-Link in CubeIDE) deletes/writes memory it shouldn't.
Is there some kind of GDB-option or other setting I'm missing?
There has to be some kind error in configuration and/or in the hex file(s) or everyone writing a booloader/application like software structure would have this problem, or am I wrong?
Unfortunately, I'm not allowed by my company to upload the hex files here, but I'll attach screenshots of Segger J-Flash showing the affected memory area below
Thanks a lot in advance for answers!
Best regards
Markus
Backup-FW: Defining 0x080F F800 as 0x0000 0000
MainSW: Defining only memory area of 0x0801 0000 to 0x080F F7FF
in my current project at work we see a strange behavior when flashing the controller with the Segger J-Link, as it erases (or writes 0xFF) to memory area(s) which aren't defined to be programmed in the flashed Intel Hex-file.
Target processor is STM32 F407IGT6.
We have a minimal software (called backup-firmware in the memory layout graph) which basically manages entry to the controller's bootloader, CRC-check and some other small things.
Also there's a block Main SW (main application) and an update marker section, which stores a 4-byte magic word for interaction between Backup-FW and Main-SW.
The hex file for the Backup-FW flashes the whole memory area with 0xFF to ensure a complete blank initial state and writes the update marker to NORMAL_STARTUP = 0x00000000. This will be later done in factory before writing production data.
The hex file for the Main-SW flashes only the Main-SW area (along with a pre-calculated CRC-32 by srec_cat).
Flashing the Main-SW, regardless if using the ST Cube IDE, Segger JFlashLiteExe or Segger JLinkExe (Linux-Environment Ubuntu 20.04, JLink_Linux_V722b utilities)
overwrites the update marker at 0x080F F800, which it shouldn't.
Googling around, I found the following threads here in forum
[SOLVED] J-link base without erase
[SOLVED] JFlash overwrites incorrect pages
which lead to playing around with the RMW threshold as described in
wiki.segger.com/J-Link_Command…#SetFlashDLNoRMWThreshold.
Setting in CubeIDE (*) the threshold to 0xFFFF which should write every blocks < 64 kB with Read-Modify-Write (as I understood) didn't change anything unfortunately although I'm pretty sure the option got accepted by the GDB server:
(* Debug profile -> Startup -> Initialization Commands: monitor exec SetFlashDLNoRMWThreshold 0xFFFF)
Source Code
- SEGGER J-Link GDB Server V6.94c Command Line Version
- JLinkARM.dll V6.94c (DLL compiled Feb 5 2021 17:38:32)
- Command line: -port 2331 -s -device STM32F407IG -endian little -speed 4000 -if swd -vd
- -----GDB Server start settings-----
- GDBInit file: none
- GDB Server Listening port: 2331
- SWO raw output listening port: 2332
- Terminal I/O port: 2333
- Accept remote connection: yes
- Generate logfile: off
- Verify download: on
- Init regs on start: off
- Silent mode: off
- Single run mode: on
- Target connection timeout: 0 ms
- ------J-Link related settings------
- J-Link Host interface: USB
- J-Link script: none
- J-Link settings file: none
- ------Target related settings------
- Target device: STM32F407IG
- Target interface: SWD
- Target interface speed: 4000kHz
- Target endian: little
- Connecting to J-Link...
- J-Link is connected.
- Firmware: J-Link V10 compiled Jun 17 2021 16:40:36
- Hardware: V10.00
- S/N: 50000899
- Feature(s): GDB
- Checking target voltage...
- Target voltage: 3.30 V
- Listening on TCP/IP port 2331
- Connecting to target...
- Connected to target
- Waiting for GDB connection...Connected to 127.0.0.1
- Reading all registers
- Read 4 bytes @ address 0x08000AFC (Data = 0xD0FA2B00)
- Read 2 bytes @ address 0x08000AFC (Data = 0x2B00)
- Connected to 127.0.0.1
- Reading all registers
- Read 4 bytes @ address 0x08000AFC (Data = 0xD0FA2B00)
- Read 2 bytes @ address 0x08000AFC (Data = 0x2B00)
- Received monitor command: WriteDP 0x2 0xF0
- O.K.
- Received monitor command: ReadAP 0x2
- O.K.:0xE00FF003
- Reading 32 bytes @ address 0xE00FFFD0
- Received monitor command: reset
- Resetting target
- Received monitor command: exec SetFlashDLNoRMWThreshold 0xFFFF
- Executed SetFlashDLNoRMWThreshold 0xFFFF
- Downloading 15840 bytes @ address 0x08010000 - Verified OK
- Downloading 16032 bytes @ address 0x08013DE0 - Verified OK
It
- behaves the same as the J-Link when flashing via CubeIDE
- behaves the same using STM32 CubeProgrammer with default settings
- behaves differently, meaning it preserves the update marker value at 0x080F F800 if the download option 'Skip flash erase before programming' is activate
I also thought it may be associated somehow with the flash page size, which is AFAIK 2 kB for our controller, but the memory layout is aligned to 2 kB blocks.
To be honest I'm completely lost at the moment, as I'm unable to tell why the J-Link (and ST-Link in CubeIDE) deletes/writes memory it shouldn't.
Is there some kind of GDB-option or other setting I'm missing?
There has to be some kind error in configuration and/or in the hex file(s) or everyone writing a booloader/application like software structure would have this problem, or am I wrong?
Unfortunately, I'm not allowed by my company to upload the hex files here, but I'll attach screenshots of Segger J-Flash showing the affected memory area below
Thanks a lot in advance for answers!
Best regards
Markus
Backup-FW: Defining 0x080F F800 as 0x0000 0000
MainSW: Defining only memory area of 0x0801 0000 to 0x080F F7FF