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-25 01:38 AM
I change the offset of the vector table to 0xF000 which is the starting address of the application but maybe I'm wrong.
I give you the first lines of my HEX file : :020000040800F2 :10F0000000C00020052B0108D1F20008DDF2000845 :10F01000E5F20008EDF20008F5F20008000000003B :10F020000000000000000000000000004D2B01085F :10F03000FDF20008000000004D2B01084D2B0108D7 :10F040004D2B01084D2B01084D2B01084D2B0108BC :10F050004D2B01084D2B01084D2B01084D2B0108AC and this is what I have in the flash memory : 0xF000 : 0xF000 <Hex> Address 0 - 3 4 - 7 8 - B C - F 0000F000 00C00020 052B0108 D1F20008 DDF20008 0000F010 E5F20008 EDF20008 F5F20008 00000000 0000F020 00000000 00000000 00000000 4D2B0108 0000F030 FDF20008 00000000 4D2B0108 4D2B0108 0000F040 4D2B0108 4D2B0108 4D2B0108 4D2B0108 0000F050 4D2B0108 4D2B0108 4D2B0108 4D2B0108 0000F060 4D2B0108 4D2B0108 4D2B0108 4D2B0108 0000F070 4D2B0108 4D2B0108 4D2B0108 4D2B0108 0000F080 4D2B0108 4D2B0108 4D2B0108 4D2B0108 I checked the last bytes too and all is okay. I don't know the assembly but I give you the first instructions that should be executed if it can helps : 0800f000: stmia r0!, {} 0800f002: movs r0, #0 0800f004: cmp r3, #5 0800f006: lsrs r1, r0, #32 0800f008: ; <UNDEFINED> instruction: 0xf2d10800 0800f00c: ; <UNDEFINED> instruction: 0xf2dd0800 0800f010: ; <UNDEFINED> instruction: 0xf2e50800 0800f014: ; <UNDEFINED> instruction: 0xf2ed0800 0800f018: ; <UNDEFINED> instruction: 0xf2f50800 0800f01c: movs r0, r0 0800f01e: movs r0, r0 0800f020: movs r0, r0 0800f022: movs r0, r0 0800f024: movs r0, r0 0800f026: movs r0, r0 0800f028: movs r0, r0 0800f02a: movs r0, r0 0800f02c: cmp r3, #77 ; 0x4d 0800f02e: lsrs r1, r0, #32 when the program jumps, it arrives at 0x0800F004 and when I execute the instruction -> Hard fault2012-03-25 08:05 AM
Problem solved!
There was a mistake with the MSP loaded value. Now it works fine. I comment my code and then I publish it, it can be useful to someone else. Many thanks for your help!2012-03-25 09:48 AM
As I said, this is the source and the HEX file of the bootloader (compiled for STM32F103VC). Check main.c for some notes about the bootloader
Hope you'll enjoy it2012-08-09 04:09 AM
clive1
Please tell me why? when I use FLASH_Unlock(); ...........FLASH_Lock(); in Program IAP at address 0x8005000, After I so use it at Program 0x8000000 but not work?2012-08-09 04:54 AM
I'm not sure I understand the question. Could you start a new thread and paste in some example code that explains it more clearly.
2012-08-09 09:27 AM
I use resource AN2557 of ST to Update firmware by FTP Server.
In Bootloader i use algorithm :check Flash address 8004000 ---->
check =*((uint8_t *) Address);
if ( check==0xFF)
{
//connect FTP;
//Down firmware
FLASH_Unlock();
//Wrtite to 0x8005000;
//Write 0x11 to 0x8004000;
FLASH_Lock();
// offset run program application
JumpAddress = *(__IO uint32_t*) (StartAddr + 4);
Jump_To_Application = (pFunction) JumpAddress;
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x5000);
__set_MSP(*(__IO uint32_t*) StartAddr);
Jump_To_Application();
}
else
{
// offset run program application
JumpAddress = *(__IO uint32_t*) (StartAddr + 4);
Jump_To_Application = (pFunction) JumpAddress;
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x5000);
__set_MSP(*(__IO uint32_t*) StartAddr);
Jump_To_Application();
}
In Program Application i use algorithm :
if need update new firmware
{
Addess=0x8004000;
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
FLASH_ErasePage(Addess);
FLASH_Lock();
NVIC_SystemReset();
}
First run : OK
Second run : Can not Erase Old firmware in address 0x8005000 to write new firmware
Can you tell me why please?
Thank you verry much.2012-08-09 09:47 AM
Ok, a couple of additional questions.
What part are you using, and what is the flash page size? Where is the code erasing 0x08004000 situated, ie execution address? What status does FLASH_ErasePage(0x08004000) return? What does the page at 0x08004000 look like post erase? What does the erase code for 0x08005000 .. 0x080XXXXX look like?2012-08-09 07:50 PM
I work with STM32f103VCT6. Flash Page size 2K.
first run,because i load chip byFlash Loader Demo
, so that erase all page flash second run, I erasing:FLASH_Unlock();
StartAddr=0x8005000;
EndAddr =0x800C000;
/* Define the number of page to be erased */
NbrOfPage = (EndAddr - StartAddr) / FLASH_PAGE_SIZE;
/* Clear All pending flags */
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
/* Erase the FLASH pages */
for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
{
FLASHStatus = FLASH_ErasePage(StartAddr + (FLASH_PAGE_SIZE * EraseCounter));
}
In program application i erase page 0x8004000 -> 0x80047FF . OK
hereproblem : If adrress 0x8005000-->0x8 X ==0xFF, i write into flash OK.But it have program, can not write or erase
respect2012-08-09 08:39 PM
FLASH_Unlock();
StartAddr=0x8005000;
EndAddr =0x800C000;
/* Define the number of page to be erased */
NbrOfPage = (EndAddr - StartAddr) / FLASH_PAGE_SIZE; /* watch boundaries, integer count */
/* Clear All pending flags */
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
/* Erase the FLASH pages */
for(EraseCounter=0; EraseCounter<NbrOfPage; EraseCounter++)
{
FLASHStatus = FLASH_ErasePage(StartAddr + (FLASH_PAGE_SIZE * EraseCounter));
if (FLASHStatus != FLASH_COMPLETE)
break;
}
2012-08-09 09:51 PM