cancel
Showing results for 
Search instead for 
Did you mean: 

CRC calculation using srec_cat

Ashei.8
Associate II

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

1 ACCEPTED SOLUTION

Accepted Solutions

extern uint32_t *g_pfnVectors[];

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

9 REPLIES 9

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 Venmo
Up vote any posts that you find helpful, it shows what's working..
Ashei.8
Associate II
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

Piranha
Chief II

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

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 Venmo
Up vote any posts that you find helpful, it shows what's working..
  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.

>>just curious, why "_limit_flash - g_pfnVector" is done both in startup and linker files?

Because I wanted to use _flash_size, but the stupid GNU linker doesn't do the relocation/math properly when it binds startup.s, and I wasn't willing to debug the linker.

>>i am trying extern uint32_t __attribute__ ((section(".endof"))) _flash_size ;

It is not a variable with an address, it is a linker symbol, that's why I put the size in a memory location within the vector table.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

well how do i access the vector table from the code? i looked at .map file. it shows this

.isr_vector     0x0000000008000000      0x184
                0x0000000008000000                . = ALIGN (0x4)
 *(.isr_vector)
 .isr_vector    0x0000000008000000      0x184 Startup/startup_stm32f207vetx.o
                0x0000000008000000                g_pfnVectors
                0x0000000008000184                . = ALIGN (0x4)
 
.crc32          0x0000000008010000        0x4
 *(.crc32)
 .crc32         0x0000000008010000        0x4 Src/main.o
                0x0000000008010000                crc_crc32

so i think that my firmware length will be at the top of memory, but

0693W000000VZvYQAW.jpg

none of these values are of firmware size. text + data from :

arm-none-eabi-size   SGW.elf 
arm-none-eabi-objdump -h -S  SGW.elf  > "SGW.list"
arm-none-eabi-objcopy  -O binary  SGW.elf  "SGW.bin"
   text	   data	    bss	    dec	    hex	filename
 191800	    564	 110424	 302788	  49ec4	SGW.elf

what i am doing wrong here?

extern uint32_t *g_pfnVectors[];

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thank you so much. it works.