cancel
Showing results for 
Search instead for 
Did you mean: 

Custom Bootloader

contact239955_stm1_st
Associate II
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
36 REPLIES 36
GUIRAT.Youssef
Associate III
Posted on September 27, 2016 at 10:45

When I cheked the system control register , there was a register called CFSR in which we have a flag named IMPRECISERR initially set to 0 and switch to 1 when the fault occured. 

Unfortunately, this flag doesn't give any indication about the possible reasons for the fault ! What I find really strange is that the code runs well when debugging it with the tool but when performing the hardware reset  the fault occurs.

What could be the effect of the hardware reset on my data ? 

GUIRAT.Youssef
Associate III
Posted on September 27, 2016 at 18:00

It seems like I have found the cause of the Hardfault. As I mentionned , the error was an IMPRECISERR and by checking these links 

1- https://blog.frankvh.com/2011/12/07/cortex-m3-m4-hard-fault-handler/

2- http://chmorgan.blogspot.de/2013/06/debugging-imprecise-bus-access-fault-on.html

I think that the problem occurs when write operation is attempted to a wrong bus adress because that the PC pointer has just moved before write operation is finished.

Now , what I aim to do is to disable write buffer use meaning that storing to memory is completed before next instruction. 

Is that possible ? Can I do it at the startup code ?

Please need support !! 

Posted on September 27, 2016 at 20:56

Doesn't it mean you just have to look a few instructions earlier in the code flow to identify where the write was initiated?

You need to review the processor registers, and the code at and immediately prior to the address it is pointing to with respect to the fault. Do a ten line disassembly, look for the stores and the addresses (in registers) involved. Look at the C source that created them. Confirm the failure repeatedly occurs in the same spot.

Ignore for a moment that you have two sets of behaviour, focus on the failing behaviour and identify its cause, it is not important to imagine reasons why it works in the debugger.

Present the code (C and Disassembly) and register content (CPU and Fault) for review, this doesn't need to be an exercise in me guessing what's broken.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
GUIRAT.Youssef
Associate III
Posted on September 28, 2016 at 10:15

I did disable the write buffer (SCnSCB->ACTLR |= 0x00000002) and then the error becomes PRECISERR. The BFAR register indicates that the fault address is 0xFFFFFFDC . I know that is an erronous address . I have tried to know the instruction that causes the jump to this address. Unfortunetly, the instruction is not present in the main code of the application. It's located in the function _iar_init_3 before calling the main.

GUIRAT.Youssef
Associate III
Posted on September 29, 2016 at 17:13

Removing optimization from my RTOS application using IAR and clearing the systick config of my IAP application before jumping to my application stored at 0x8003000 solved the issue. 

SS.Sagar
Associate III
Posted on September 30, 2016 at 05:10

do we need to mention application start address in application code as well?

if bootloader is upto 0x08005000 then application start address can be 0x08005800, right? following is linker script i have updated. please correct me if i m wrong.

MEMORY
{
flash : org = 0x0800C000, len = 64k
ram0 : org = 0x20000000, len = 12k
ram1 : org = 0x00000000, len = 0
ram2 : org = 0x00000000, len = 0
ram3 : org = 0x00000000, len = 0
ram4 : org = 0x10000000, len = 4k
ram5 : org = 0x00000000, len = 0
ram6 : org = 0x00000000, len = 0
ram7 : org = 0x00000000, len = 0
}

Posted on September 30, 2016 at 05:32

It helps to be specific about what part exactly we are talking about.

It is possible to use symbols and the linker to manage the address of the vector table, and have the code use that, but by default ST doesn't use that method. You will need to make sure whatever code you have in SystemInit() correctly sets SCB->VTOR to reflect the address of the new Vector Table. By default it resets to zero, and points to the base of FLASH due to how the BOOTx pins were set at reset.

You need to shrink the size of the FLASH region by the same amount as you advance it, your part has a finite amount of space and it starts at 0x08000000. If you have 64K and advance the base by 20KB you now have 44KB to work with.

You mention 0x5000, 0x5800 and 0xC000, you should pick a boundary than matches the flash sectoring, and is adequate for the boot loader now, and potential future iterations. If the loader is now 0x5000-0x57FF in size consider if 0x6000 is more appropriate. Most of the STM32 parts need a vector table on a 512 byte boundary, but this ultimately depends on the maximal size of the table from the silicon's perspective.

The method of using the linker/symbol to automatically set the SCB->VTOR has been described in other threads.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..