Reputation: 313
I have an uncommon but in my eyes reasonable use case: I have to build two STM32 firmware images: a boot loader and an application (by using the latest Eclipse CDT based IDE from ST Microelectronics, called: "STM32CubeIDE").
Because my constraints are mostly low power consumption and not security, therefore I have only the requirement for data integrity for the DFU (Device Firmware Upgrade) scenario and for this I implemented a CRC32 check over the complete FW images. The tricky part is, that the firmware itself contains its actually size within a C-struct at a fixed offset address 0x200 in the code memory (the benefit for this design is, that not the complete code memory has to be transmitted, but the FW is always protected by the CRC32):
The layout of a firmware is something like this:
<ISR Table> <FW-Header@FixedAddress0x200> <RestFWCode> " + CRC32
For my implementation I need to replace a memory area within the "FW Header" area with the actual FW size (which is only available after the build process).
For this I made a python script which patches the binary "*.bin" file, but it seems, that Eclipse/GDB uses for debugging the ELF-file, which looks for me much more complicated for a custom patch compared to the binary image, since I found no easy way to do this (to replace the actual FW size and append the 4 bytes of the CRC32).
Therefore, I thought the easiest way would be to patch the code memory right after the firmware got loader from the debugger. I tested successfully a command-line tool from ST which can manipulate arbitrary memory even in the code memory (my code memory starts at 0x08000000 + application at offset 0x4000 and FW header at öffset 0x200 -> 0x08004200):
ST-LINK_CLI.exe -c SWD -w32 0x08004200 0xAABBCCDD
(see: https://www.st.com/resource/en/user_manual/cd00262073.pdf)
My Problem is, I don't know how to initiate this simple EXE call right before the debugger got attached to the MCU... I tried the "Debug Configuration"-> "Startup" -> "Run Commands", but without success...
Does anybody know a way how to achieve this?
Upvotes: 0
Views: 701
Reputation: 334
I am going to recommend a different workflow to achieve the same image format:
<ISR Table> <FW-Header@FixedAddress0x200> <RestFWCode> " + CRC32
Once in place, your build process will be:
Note: For STM32CubeIDE, you will want to have your own *.elf
project that includes the STM32CubeMX project as a static library. Otherwise, STM32CubeMX will overwrite your linker script each time it generates new code.
Since each project tends to have a slightly different linker script, I am going to demonstrate using a .test_crc
sector. Insert the following into your *.ld
linker script:
.test_crc :
{
_image_start = .;
BYTE( 0x31)
BYTE( 0x32)
BYTE( 0x33)
BYTE( 0x34)
BYTE( 0x35)
BYTE( 0x36)
BYTE( 0x37)
BYTE( 0x38)
BYTE( 0x39)
/* FW Image Header */
LONG( _image_end - _image_start ) /* Size of FW image */
LONG( _image_start ) /* Base address to load FW image */
/* Place this at the end of the FW image */
_image_end = .;
_IMAGE_CRC = ABSOLUTE(0x0); /* Using CRC-32C (aka zip checksum) */
/*LONG( (-_IMAGE_CRC) - 1 ) /* Uncomment to append value, comment to calculate new value */
} >FLASH
Add the following as a post-build step in STM32CubeIDE (generates the raw binary image):
arm-none-eabi-objcopy -S -O binary -j .test_crc ${ProjName}.elf ${ProjName}.bin
Now your ready to test/evaluate the process:
*.bin
file.*.bin
file0x0
in the following _IMAGE_CRC = ABSOLUTE(0x0)
to match your calculated value. Uncomment the following:LONG( (-_IMAGE_CRC) - 1 ) /* Uncomment to append value, comment to calculate new value */
0xFFFFFFFF
for a CRC-32C value.When you are ready to apply this to your actual FW image, do the following:
arm-none-eabi-objcopy -S -O binary ${ProjName}.elf ${ProjName}.bin
_image_start = .;
in front of your vector table./* FW Image Header */
LONG( _image_end - _image_start ) /* Size of FW image */
LONG( _image_start ) /* Base address to load FW image */
/* Place this at the end of the FW image */
_image_end = .;
_IMAGE_CRC = ABSOLUTE(0x0); /* Using CRC-32C (aka zip checksum) */
/*LONG( (-_IMAGE_CRC) - 1 ) /* Uncomment to append value, comment to calculate new value */
You may find that you actually do not need the CRC value built into the image, and can just append the CRC value to the *.bin
. Then provide the *.bin
to your bootloader. The *.bin
will still contain the load address and size of FW image, +4 bytes for the appended CRC value.
Upvotes: 1
Reputation: 3282
Running a program before starting a debug session can be done using Eclipse's "Launch group" located under Debug Configurations, e.g. top menu -> Run -> Debug Configurations.
However before doing that you should go to project properties -> Builders and add your program invocation there - path to the executable plus its arguments. Make sure it's NOT checked so that it doesn't run when you build your project. Then you can go to the Launch Groups described above and create a group that contains the program you've defined in the project Builders section, then after that your regular debug session which you should already have available on the list.
Upvotes: 1