Skip to main content
contact239955_stm1_st
Associate II
March 23, 2012
Question

Custom Bootloader

  • March 23, 2012
  • 36 replies
  • 6265 views
Posted on March 23, 2012 at 17:54

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 wh

y.

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 #flash
This topic has been closed for replies.

36 replies

Tesla DeLorean
Guru
March 23, 2012
Posted on March 23, 2012 at 18:07

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.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
contact239955_stm1_st
Associate II
March 23, 2012
Posted on March 23, 2012 at 18:34

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?

Tesla DeLorean
Guru
March 23, 2012
Posted on March 23, 2012 at 20:12

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.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
alok472
Associate
March 24, 2012
Posted on March 24, 2012 at 04:00

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..

contact239955_stm1_st
Associate II
March 24, 2012
Posted on March 24, 2012 at 16:25

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?
Tesla DeLorean
Guru
March 24, 2012
Posted on March 24, 2012 at 16:42

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.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
contact239955_stm1_st
Associate II
March 24, 2012
Posted on March 24, 2012 at 19:30

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 community
Tesla DeLorean
Guru
March 25, 2012
Posted on March 25, 2012 at 03:24

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.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
alok472
Associate
March 25, 2012
Posted on March 25, 2012 at 03:56

Where is the location of your interrupt vector table in the Application FW which you programmed ? Hope you modified it correctly....

contact239955_stm1_st
Associate II
March 25, 2012
Posted on March 25, 2012 at 10:38

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 fault