This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

STM32 custom bootloader fail

Hello everybody,

I'm working on a custom bootloader for STM32F407/F411. It start at 0x08000000 and works in a ordinary way, loading Intel-Hex files through the UART, interprets the file and programs the FLASH. Then it sets the MSP and jumps to the loaded code (the code is linked i.e. at 0x08008000 and there the VTOR is relocated). Everything is just fine. The problem begins, when I want the loaded code to invoce a new flashing (from outside the bootloader). I'm setting a function handler, pointing at my flashing function (with propper aguments ofcourse) and jump there (the address of my flashing function I read out from my *.map file from the bootloader code). When I call the flashing function, after FLASH sector erasing the core jumps to 0xFFFFFFFE. I don't know what is happening. The prefetch and I/D caches in the FLASH ACR register are disabled. Please help.

  • VTOR or something else isn't properly set back to their initial state.

    Consider doing a wdog reset or similar to return back to the boot loader. Then you know the processor is in a known state.

  • In the loaded application I use SysTick to generate time intervals (the bootloader doesn't use it). In the "systemInitialize()" in my loaded app, the VTOR register is updated to the propper value. I don't understand why the program crashes between setting the SER in FLASH->CR and setting the STRT bit. When I inserted a for(i = 0; i < 10000; i++) between those two, it worked. Strange... My core runs @ 16 MHz, with no FLASH latency.

  • Is the address you're jumping to ODD?

    If it's EVEN then it's going to Hard Fault, if the erased flash behind the vector table contains 0xFFFFFFFF, then it will appear to go to 0xFFFFFFFE. Similarly if you have interrupts firing, and the table, or the things it jumps to, are erased, then you're going to experience faults/failures.

    You'll need to provide a better break down of the code, especially the erasing code, and the addresses and transition code sequences.

    Do you wait for the erase to complete? Some of the F4 sector can take multiple seconds to erase. The 16KB ones between 200-800 ms can be expected. You should track the status in the flash controller rather than use software delay loops.

  • The address is ODD for shure. When my debugged bootloader launches the loaded application, the debugger loses track of the code flow, but when I enter the flashing function, is shows up again. For the act of flashing I use the busy flag in FLASH->SR. There is no HardFault lauched - the processor seems to be stuck at 0xFFFFFFFE address which is wierd. I discovered that this problem appears between setting the SER and STRT bit. I looks like this:

    while(FLASH->SR & FLASH_SR_BSY);
    
    FLASH->CR = (FLASH_CR_SER | (number << 3) | FLASH_CR_PSIZE_1);
    
    // here is where the processor "jumps" to 0xFFFFFFFE
    
    FLASH->CR |= FLASH_CR_STRT;
    


    when I add a simple loop between those:

    while(FLASH->SR & FLASH_SR_BSY);
    
    FLASH->CR = (FLASH_CR_SER | (number << 3) | FLASH_CR_PSIZE_1);
    
    while(i--);
    
    FLASH->CR |= FLASH_CR_STRT;
    


    It works fine. Anybody got an idea whats going on?

  • Yes, that does seem a bit perplexing. Not sure I can do anything with out "hands on".

    You could try doing this in a very simple configuration and confirm if the problem exists there or not.

    ST tends to AND/OR bits into the registers rather that explicitly write values to them. You might want to look at the libraries, or where some additional latency is caused by subroutine call/return overheads which you're dealing with by inserting a delay. Does equivalent library code malfunction?

    Look carefully at the generated assembler, see if there is anything odd there, and that the accesses are done as if the peripheral registers are volatile.

  • I have to keep my schedule, so I must leave it as it is. After that strange patch it works just fine every time.
    It is worth to notice, that the problem appeared only, when calling the flasher function from outside the bootloader.

    Thanks for help :)