Hi all. I'm using CortexM3 (STM32F103VB) with Keil uVision3 v.3.85. I've developed my own bootloader allocated between 0x08000000 and 0x08001FFF. 4 bytes from 0x08002000 to 0x08002003 are used for FW checksums. Bytes from 0x080002004 on are used for FW. The bootloader writes the whole FW and checksum area. The FW checks itself against its checksums at startup. The bootloader terminates with the usual (from application notes) sequence:
JumpAddress = *(__IO uint32_t*) (0x08002004 + 4); Jump_To_Application = (pFunction) JumpAddress; __set_MSP(*(__IO uint32_t*) (0x08002004)); Jump_To_Application();
while the fw start with the usual sequence:
SystemInit(); NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x2004);
In the sample fw project target properties, the default memory area starts from 0x08002004 and is 0x1DFFC bytes long, while in the linker tab the "Use Memory Layout from Target dialog" is checked.
The sample fw project decalres the checksum area as
static const CHECKSUMS_ST C_Checksums __attribute__((at(0x08002000)));
PROBLEM: irq are not working in the sample fw (in the sample I only use systick).
If I remove the whole checksums stuff and make the sample project starting from 0x08002000 all is working fine.
Could the problem be caused by the fact the that the linker is told to begin at 0x8002004 and then the firmware access the checksums placed before ?
Do I need a more complicated scatter file to get things working ? (I'm asking mainly because I'm stuck with the unlicensed version at this project stage (and it does not support scatter files, does it ?).
Could the problem be due to another of the unlicensed version limits ?
Inspection with debugger memory windows shows that the flash is correctly written in both cases, The Stack Pointer is set at the same value (in RAM) and the reset vector points to locations that differs of 4 bytes between the two versions. All seems well but... irq is not working (or at least this is what it seems to me by the behavior of the sample fw).
What am I missing ?
I realized that another important test was missing. I left out all the checksum stuff, but left the sample fw at 0x8002004. It doesn't work.
So, the problems of irq not working seems not to be related to memory access to a constant out of linker parameters.
Still need some help
I don't have any experience on ST MCU and ARM Cortex-M.
I did a quick google search, and found something.
#ifdef VECT_TAB_RAM /* Set the Vector Table base location at 0x20000000 */ NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); #else /* VECT_TAB_FLASH */ /* Set the Vector Table base location at 0x08000000 */ NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); #endif
It seems that 0x08000000 is for NVIC_VectTab in FLASH, so can not be used for other purpose.
NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x2004);
Your NVIC Vector table is not properly aligned.
Minimum alignment for the Vector table is 32 words (up to 16 interrupts). STM32 devices have slightly less then 60 external interrupts (+ 16 exceptions) therefore proper alignment is 128 words.
Hi Robert,
you're right, I didn't read the details on NVIC offset, vectors shall be aligned to 0x80 blocks! I moved my FW to 0x08002400, called
NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x2400);
and the application successfully run if I left out all checksum stuff. However if I re-introduce the checksum BEFORE 0x08002400 the execution get lost as soon the bootloader jumps to FW (I've tried placing checksums at 0x08000000, 0x08000080, 0x08000100, 0x08000200 and 0x08000300).
If I move the checsum to "high" pages (after the FW, inside the flash zone delimited by FW project target properties) all is well.
I could consider the problem solved and move checksums to high pages, however I'd like to understand if the problem of placing const data BEFORE the vectors is related to lacking/poor linker settings or something else.
Sorry i meant
0x08002000, 0x08002080, 0x08002100, 0x08002200 and 0x08002300