Skip to main content
Graduate
August 16, 2024
Solved

Bootloader DFU on STM32F439ZITx

  • August 16, 2024
  • 3 replies
  • 3680 views

Hi everyone, I'm developing a bootloader that works like this. I was inspired by the example: https://github.com/pramodk51/bootloader_for_stm32f4.

 

memory_map.png


I developed this initially on Nucleo F439ZI for the test phase and I managed to implement it with the addition of DFU functionality. The principle was simply to send a program that lights a led per uart that the bootloader would store and then go to this memory location to make it work (2 slots, one for the recent version and the other for the backup).

Note: I didn't develop the whole thing in the same code, I have bootloader code and application code, so 2 linker scripts etc ...

Once the test was functional and robust, I decided to integrate it into my personal project. My application this time is much more complex than turning on a LED, it uses FreeRTOS and is also much larger (but respects the size specified in the slot).

In terms of the application I've reproduced exactly the same operation so that it adapts to the slot automatically with the

 

SCB->VTOR

 

. Obviously the code I generate is adapted to the slot in which it will be placed using the linker script.

So when it comes to restarting, everything should work in the same way as when I carried out my tests on nucleo. However, I'm not getting any results from my tests.

My application program won't launch even though the bootloader redirects to the correct slot and updates the reset handler (check against the .map). But after that I have nothing. I have an IWDG function on the bootloader and the application and at the end of each WDG delay I loop back to the bootloader because nothing happens.

My problem is that I'm reproducing exactly the same pattern as during my configuration tests and the result is different.
I suspect a difference in treatment when using FreeRTOS but I haven't found anything on the subject. Are there any parameters that need to be managed to ensure correct operation?

I apologise in advance for my lack of clarity and information. I don't want to confuse you with too many documents, so I'd rather give you the information you find relevant.

I'll leave it to you while I continue my research and thank the ST community in advance for reading me.

All the best.

 

    This topic has been closed for replies.
    Best answer by Vince18092001

    Hello everyone, here's a little feedback on this topic. Following these exchanges I decided to go back to my problem and I finally found that the solution was in the SystemClockConfig(), a flag error already raised for the clock, most probably due to the fact that I was setting the clock first in the bootloader and then in the application. Thanks to those who tried to help me.

    3 replies

    Super User
    August 16, 2024

    You should be able to run in debug configuration to figure out what "doing nothing" means. The CPU is executing code somewhere, possibly stuck inside an interrupt, or at the wrong interrupt code address. If you don't have a debug context, you can use the PC register to find out what code is being run and the VECTACTIVE field in the SCB registers somewhere to figure out which interrupt it's in, if any. Probably want to disable the watchdogs during the debug process.

    Graduate
    August 16, 2024

    Thank you for your reply.

    I can't debug because it's my bootloader that runs the program and it doesn't show me any Error_Handler() or anything else. I'm still learning, so if there's a way of accessing the debugging of my application code while I'm on my bootloader code, I'm all ears.
    If it's not possible, I don't understand how I can access what you call the ‘PC registry’ and how to view the SCB fields. I'm trying to learn about debugging and its functions as I go along, but I'm the only developer in my company, so I'm forced to develop in a hurry - please excuse my lack of knowledge.

    Graduate II
    August 16, 2024

    Is your header size linker set 1K ? But primary question is how plan you have to load firmwares? 

    Graduate
    August 16, 2024

    Yes, my header is 1K. It worked during my tests on nucleo and the ‘blink’ application. As far as the firmware is concerned, the final aim is to download it via UART (sent by an ESP32). This has already been done and is working on the test version.
    This is what seems strange to me: everything worked perfectly on a ‘blink’ application but with my FreeRTOS application nothing works any more. Attached is my script linker for more information.

    Note: For the integration tests of my RTOS application I put the program myself using ST-Link utility in the right memory location and that's how I realised that it wasn't working and that was to remove any doubt as to the source of the error in the UART update. I'd also like to point out that everything I've mentioned I've already tested with my test application and it worked.

    Graduate II
    August 17, 2024

    Primary when you have ESP32 why not connect next one pin and control BOOT0 pin = use internal systemloader? Here only one app in normal place exist in flash 8000000...

    But ok you try make thing complicated, then your script link seems be ok, but isnt only change required for code work on other place... Seems you use cube IDE then in file system_stm32f4xx.c you require make changes. enable and set ...

    /* Note: Following vector table addresses must be defined in line with linker
     configuration. */
    /*!< Uncomment the following line if you need to relocate the vector table
     anywhere in Flash or Sram, else the vector table is kept at the automatic
     remap of boot address selected */
    #define USER_VECT_TAB_ADDRESS
    
    #if defined(USER_VECT_TAB_ADDRESS)
    /*!< Uncomment the following line if you need to relocate your vector Table
     in Sram else user remap will be done in Flash. */
    /* #define VECT_TAB_SRAM */
    #if defined(VECT_TAB_SRAM)
    #define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field.
     This value must be a multiple of 0x200. */
    #define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
     This value must be a multiple of 0x200. */
    #else
    #define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
     This value must be a multiple of 0x200. */
    #define VECT_TAB_OFFSET 0x00020400U /*!< Vector Table base offset field.
     This value must be a multiple of 0x200. */
    #endif /* VECT_TAB_SRAM */
    #endif /* USER_VECT_TAB_ADDRESS */
    Vince18092001AuthorAnswer
    Graduate
    August 27, 2024

    Hello everyone, here's a little feedback on this topic. Following these exchanges I decided to go back to my problem and I finally found that the solution was in the SystemClockConfig(), a flag error already raised for the clock, most probably due to the fact that I was setting the clock first in the bootloader and then in the application. Thanks to those who tried to help me.