2012-03-23 09:54 AM
Hi everybody!
I'm trying to make a bootloader that fetch a program from an SD card. I finally manage to parse the HEX file correctly and write the content in the flash memory but when I try to jump to the program, a Hard Fault is generated and I don't know why.
There's my Flash related code :FLASH_Unlock();
...
FLASH_ErasePage(ApplicationAddress + (n-1) * PAGE_SIZE);
FLASH_PageWrite(ApplicationAddress + (n-1) * PAGE_SIZE, page32);
...
uint32_t startAddress = *(__IO uint32_t*)(ApplicationAddress + 4);
pFunction Start = (pFunction)startAddress;
__set_MSP(*(__IO uint32_t*)ApplicationAddress);
Start();
Where 'n'
is the page number to be written, page32 a pointer to the page content in RAM and 'FLASH_PageWrite()' a custom function to write an entire page by successive calls to 'FLASH_ProgramWord()'
ApplicationAddress = 0x800F000 (My bootloader uses pages up to 0x800A800) Thanks #iap #bootloader #flash2012-03-23 10:07 AM
I'm trying to make a bootloader that fetch a program from an SD card. I finally manage to parse the HEX file correctly and write the content in the flash memory but when I try to jump to the program, a Hard Fault is generated and I don't know why.
If you had a reasonable hard fault handler you could determine what code is causing the failure. You might want to double check the address for which you've compiled the code, and that the code you're about to execute looks corrects, by dumping some of it out. You could also just use a debugger, breakpoint the transition code and step into it. Shouldn't be too hard to see where it goes pear shaped.
2012-03-23 10:34 AM
what do you mean by ''You might want to double check the address for which you've compiled the code'', I'm sorry I'm not really fluent in English.
I'm using the debugger, the hard fault is generated just after the Start() line. If there something specific that I have to do with the program I load?2012-03-23 12:12 PM
What address did you tell the compiler/IDE to build the application code at?
Look at the .MAP file, it should give you an idea where it's situated. Look at where the .HEX records are pointing. The processor expects to see valid code, loaded at the correct address, failing this it will crash. If it is crashing after Start(), then perhaps you should be looking at in a disassembler mode, and seeing what registers contain. If startAddress contains some stupid/invalid address you'll will crash the processor. Consider also the value of the stack pointer. Try printing out some basic data before the call, ie the values of SP and PC, and the data at the ApplicationAddress. The core state within the hard fault handler should help pin point the problem. Try taking a look a Joseph Yiu's book, or a Cortex-M3 technical manual.2012-03-23 08:00 PM
When developing the IAP code, i follow following practice.
1. Check in the debugger window the Flash is erased after erase function i used IAR so, open memory window and see put address of flash 2. Take care that Erasing and programming page size can be different. Erasing for STM32L=256B and Writing = 128B 3. CHeck HALFPAGE after programming, again in memory window 3. Once the Programmming is complete, verify byte-by-byte the programmed code and the code for programming. 4. The Interrupt vector table...If you are using 2 independent code in 2 segments. See the ICF file is correctly configured. 5. I started from AN on IAP using UART example..2012-03-24 08:25 AM
Thanks for your help.
Indeed, I had to change my application starting address (0x08000000 -> 0x0800F000) and now it jumps properly but I still have one big problem... I just noticed that the flash writes fail, the function 'FLASH_ProgramWord()' returns FLASH_ERROR_PG and of course I don't know why. It's my first application using the flash programming feature so I have a lot of things to learn. When the bootloader starts, I have two lines :FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP| FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); and after that, erasing pages works well but not writing words. I'm sure that I have to add some little things but don't know what. An idea?2012-03-24 08:42 AM
Programming errors typically occur because the flash cell is not blank, or you're not waiting for things to complete properly. There can be issues with power, and clocks, but these tend to be secondary to basic coding/sequencing issues.
Try programming half words, 16-bit, and making sure the value is 0xFFFF prior to a programming attempt, and not bothering to program cells to 0xFFFF. 32-bit programming expects you will write 32-bit words, on 32-bit boundaries. HEX files may also contain sparse, odd or unaligned data, you can't go back, or write over a cell you have previously programmed.2012-03-24 11:30 AM
As you suggested to me, I program the memory with half words and after some bug fixes, the flash memory looks correctly filled (the first values are the same as the HEX file ones) but after the jump, the µC executes the instruction at the address 0x0800F004 (cmp r3, #1) and then goes in the Hard Fault interrupt
Maybe I still have to do some modifications to the application program? For now, the only difference with a standard application is the starting address. Thanks again for your help! I hope that after the next answer it will works. If it's the case, I'll be glad to share this bootloader to the community2012-03-24 06:24 PM
Could you share a few of the hex records, or a binary?
If you try jumping to an even address the Cortex-M3 will hard fault, as it will assume you are trying to execute 32-bit ARM code.2012-03-24 06:56 PM
Where is the location of your interrupt vector table in the Application FW which you programmed ? Hope you modified it correctly....