Hello,
I am looking for help regarding uVision IDE and Toolchain with regards to finding the end of firmware.
What I want to do: 1) Create a BIN file using hex2bin 2) Replace the dummy CRC (ulProgramCrc) at the end of the file with an own written tool 3) Load BIN file into STM32F2 4) Calculate CRC with the "CRC calculation unit" and compare with the image CRC
I tried so fare:
EndOfFirmware.c
#pragma push #pragma Ono_remove_unused_constdata // Dieser Wert muss sich am Ende des BIN-Files befinden (Scatterloading) und wird durch ein AfterBuild Tool durch die richtige CRC ersetzt. // Zum Prüfen wird die interne STM32 CRC calculation unit verwendet. const unsigned long ulProgramCrc __attribute__((section("FlashEnd"))) = 0xAABBCCDD; #pragma pop
And the scatter file:
LR_IROM1 0x08020000 0x00020000 { ; load region size_region ER_IROM1 0x08020000 0x00020000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x20000000 0x00018000 { ; RW data .ANY (+RW +ZI) } ; ER_IROM2 AlignExpr(ImageLimit(ER_IROM1), 4) { ; CRC at the end of the image ; ER_IROM2 0x803FFFC 0x00000004 { ; CRC at the end of ; ER_IROM2 AlignExpr(ImageLimit(ER_IROM1), 4) { ; CRC at the end of the image ER_IROM2 +0 0x00020000 { ; CRC at the end of the image endoffirmware.o ("FlashEnd", +Last) } }
With these settings the ulProgramCrc variable is placed at the end of the bin file, but when I start the debugger &ulProgramCrc is a ram address. I need the flash address, so I know the end of the image!
The other way ... = Image$$ER_IROM1$$Length; ... = Image$$RW_IRAM1$$RW$$Length; doesn't work. I always get 0xFFFFFFFF.
I'm not familar with scatter files, so please help. Thx very much
0) Add image length and Base address to known unused interrupt vector locations in STM3210x.s
IMPORT ||Load$$LR$$LR_IROM1$$Length|| IMPORT ||Load$$LR$$LR_IROM1$$Base|| DCD ||Load$$LR$$LR_IROM1$$Base||; Expected image location in memory DCD ||Load$$LR$$LR_IROM1$$Length||; Image Length
1) Create a BIN file using fromelf 2) Add a CRC to the end of the file using external program(use 4 bytes even if you only do a 16-bit CRC) 3) Create HEX file from new bin file using hex2bin.exe 4) Load Hex file into STM32F2
Hi
Thanks for your help and it works!!
Do know why
extern unsigned int Load$$LR$$LR_IROM1$$Length; extern unsigned int Load$$LR$$LR_IROM1$$Base[];
doesn't do the same?
And do you know the syntax when I don't use the scatter file - with this solution it isn't needed anymore
Do know why ... doesn't do the same?
Maybe I know the answer to this one. As we know, the linker calculates addresses of variables and functions and inserts them into code. Perhaps that's why in order to access linker-generated symbols you have to use the address operator:
int len = &Load$$LR$$LR_IROM1$$Length;
Note that the type (unsigned int) used in the declaration of Load$$LR$$LR_IROM1$$Length is irrelevant. It could be char or float or whatever.
I could be wrong, but I think uVision implicitly creates a scatter file during the build process. You can inspect it, write down the relevant load region name and use it in your code.
Hi - thanks again!!!
ASM Code:
LDR R0, =||Load$$LR$$LR_IROM1$$Length|| ; Image Length
Disasm:
0x08022B68 480A LDR r0,[pc,#40] ; @0x08022B94
Address 0x08022B94 is OK
C Code:
extern unsigned int Load$$LR$$LR_IROM1$$Length; ulImageLength = (unsigned int)&Load$$LR$$LR_IROM1$$Length;
0x080215A8 F8DF81DC LDR.W r8,[pc,#476] ; @0x08021788
Address 0x08021788 is wrong! Any idea?
I put a lot of critical information into the same area as the vector table (including code location and sizes). The layout for the project is fixed, therefore the address of the information is all fixed. I then access those values via pointers.
For example:
IMPORT ||Load$LR$LR_IROM1$Length|| IMPORT ||Load$LR$LR_IROM1$Base|| DCD ||Load$LR$LR_IROM1$Base|| ; Vector Offset 10h DCD ||Load$LR$LR_IROM1$Length|| ; Vector Offset 11h
In the 'C' for example:
unsigned long Base; unsigned long Length; Base = (unsigned long *)(((unsigned long *)0)[0x10]); // Get base address Length = (unsigned long *)(((unsigned long *)0)[0x11]); // Get length // etc
DJR
View all questions in Keil forum