Skip to main content
Ashei.8
Associate II
April 7, 2020
Solved

CRC calculation using srec_cat

  • April 7, 2020
  • 3 replies
  • 9365 views

I am using STM32F207. The project that im working on will later on will be used by a bootloader. I am, therefore, trying to add crc information in the hex file so that bootloader will be able to validate its correctness.

I am using srec_cat to calculate the crc in postbuild using this example

with a modification that i use obj_copy to fill the memory gaps rather than srec_cat. (--gap-fill 0xFF)

I have added a section in linker file, with the same address as that the one used by srec_cat,

/* Sections */
SECTIONS
{
 /* The startup code into "FLASH" Rom type memory */
 .isr_vector :
 {
 . = ALIGN(4);
 KEEP(*(.isr_vector)) /* Startup code */
 . = ALIGN(4);
 } >FLASH
 
 /*placing section for crc */
 .crc32 0x08010000:		
 {
 KEEP(*(.crc32)) /*keep my variable even if not referenced*/
 } >FLASH
 
 /* The program code and other data into "FLASH" Rom type memory */
 .text :
 {
 . = ALIGN(4);
 *(.text) /* .text sections (code) */
 
.....

and

const uint32_t __attribute__ ((section(".crc32"))) crc_crc32;

problems:

  1. Srec_cat generates error of contradictory bytes on memory address. If i set it to warning only, then it overwrites the crc. i am working around it using exclude, but then it rightly points out that there are holes in memory. What do you guys suggest i should do?
  2. as i am not appending the crc to the end of the file, and do not want the hex file to be bloated (hence using objcopy fill), i failed miserably to calculate the firmware size, so that bootloader would be able to use it. i know that _etext, and _edata from linker sections could be used, but im not able to calculate it.
  3. since i would have to jump over the memory location on which the crc is, i am using HAL_CRC_calculate along with accumulate, is this the right way of doing it?

Ples help

This topic has been closed for replies.
Best answer by Tesla DeLorean

extern uint32_t *g_pfnVectors[];

printf("%p %p\n",g_pfnVectors[0], g_pfnVectors[1]);

3 replies

Tesla DeLorean
Guru
April 7, 2020

Who is Ples?

>>since i would have to jump over the memory location on which the crc is, i am using HAL_CRC_calculate along with accumulate, is this the right way of doing it?

Show the code, show an example of the values written in the file vs computed

What's the exact batch file?

The one cited does 0x08000000 thru 0x08007FFB with the CRC at 0x08007FFC, and not 0x08000000..0x0800FFFF, 0x08010000

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Ashei.8
Ashei.8Author
Associate II
April 8, 2020
C:\ST\STM32CubeIDE_1.0.0\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610\tools\arm-none-eabi\bin\objcopy.exe --gap-fill 0xFF -O ihex SGW.elf "SGW.hex"
..\srec_cat.exe SGW.hex -Intel -exclude 0x8010000 0x8010004 -STM32 0x08010000 -o SGW_crc.hex -Intel --contradictory-bytes=error

batch file

Couldn't calculate the crc, as i have no buffer length to pass to HAL_CRC_Accumulate but i think it would be something like this

	HAL_CRC_Calculate(&hcrc, (uint32_t*) 0x08000000, (0x08010000 - 0x08000000) / 4;);
 
	crc_cal = HAL_CRC_Accumulate(&hcrc, (uint32_t*) 0x08010004, (firmwareLength - 0x08010004) / 4);

and then comparing the result of crc_cal and crc_crc32(see the original question on how i think i would be able to have the value at this variable

Tesla DeLorean
Guru
April 8, 2020

Not sure I understand why you have a hole in the middle to accommodate the CRC.

I would generally let the linker determine the image length, and have it stored in an unused vector in the vector table, and place the CRC at the end.

The nature of the math would be if you run the check over the image and appended CRC, the resultant CRC would be ZERO

linker.ld

...

/* End section */

 . = ALIGN(4);

 .endof :

 {

 /* This is used by the startup in order to find the end */

 _limit_flash = .;   /* define a global symbol at the end of flash */

_flash_size = _limit_flash - g_pfnVectors; /* compute length based on beginning and ending points */

 } >FLASH

...

startup.s

...

.word UsageFault_Handler

.word _limit_flash - g_pfnVectors /* compute size */

.word 0

.word 0

...

https://community.st.com/s/question/0D50X00009Xkhp1SAB/flash-crc-integrity

https://community.st.com/s/question/0D50X0000Awa25q/generated-binary-file-size-in-stm32l4

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Ashei.8
Ashei.8Author
Associate II
April 8, 2020
  1. I have a hole in the middle, because whenever i tried to use srec_cat and it had to overwrite on the location of crc variable, it threw an error. it would be better to have crc appended at the end, but then srec_cat should know of the location where to write it..
  2. just curious, why "_limit_flash - g_pfnVector" is done both in startup and linker files?
  3. How would i refer to _flash_size in c code?

i am trying

extern uint32_t __attribute__ ((section(".endof"))) _flash_size ;

but the compiler says undefined reference.

Piranha
Principal III
April 8, 2020

Also think about another option - introducing 512 byte (because of VTOR alignment requirement) header before the firmware. There you can put CRC, SHA, digital signature, symmetric encryption key (encrypted by asymmetric encryption), product ID, hardware and software version numbers, actual firmware address and other things you need.

As for an actual bootloader design... Do not follow the ST's dumb examples and read my post there:

https://community.st.com/s/question/0D50X0000AFpTmUSQV/using-nvicsystemreset-in-bootloaderapplication-jumps