Our Latest News

STM32 microcontroller Bootloader implementation

In the previous article, we introduced the STM32 boot process and the allocation of the main memory space, and this article will build on the previous article to explain the STM32 bootloader implementation.

STM32 memory division

The STM32 starts at address 0x08000000 after power-up, so if we want to make the STM32 go directly into the Bootloader at power-up, then its memory must start at address 0x08000000. This step is determined by the hardware of the microcontroller and cannot be intervened by software.

This image has an empty alt attribute; its file name is image-137.png

Therefore, when we use Keil software to design the STM32 Bootloader, we must set this address in the Keil project. Of course, it does not matter if you do not set it, because Keil compiles the microcontroller’s software to this address by default. This is shown in Figure 1.

poYBAGO-gO-AC07PAAJNeEMhWsU765.png

Figure 1 Setting the Keil power-up start address

Another point is that we need to pay attention to the size to the right of the start address, because this parameter affects the subsequent memory space allocation.

Okay, let’s assume we have a chip with 64KB of Flash and let’s divide the memory space for it. Let’s calculate what its address range is.

The starting address, without further ado, is 0x08000000.

How should we calculate the 64K address space? This is actually a binary conversion problem, we know that in decimal, 1KB = 1024 bytes, and a byte in our computer is an address unit, so as long as you want to use 64KB * 1024 can be derived from the number of (decimal) address units. Note that the above 0x10000 refers to the address space, indicating that there are 0x10000 bytes of memory cells in 64K Flash, and our memory addresses start from 0. Therefore, the final address range is 0x08000000~0x08010000.

After calculating the above address range, we need to divide it into functional areas, first assume that our Bootloader does not come with OTA (On The Air) upgrade function, so the entire memory space should be divided into at least two parts, the first part is the Bootloader area starting from 0x08000000, assuming the length of X, the second part is The second part is the application area immediately following (or of course not only following) the Bootloader area, whose address range is 0x08000000 + X and whose length is Y.

This address division can now be dynamically changed according to the size of the final compilation of the Bootloader, but it should be noted that the STM32 memory division should be half a page as the minimum unit, because when programming the Flash, are erased according to half a page, so if your program is not aligned according to half a page, then the erasure will be very awkward, half a page = 32 words = 128 bytes.

For the above reasons, we tentatively decide that in STM32, the first 10K addresses hold the Bootloader program, and the addresses after that, hold the application, as shown in Figure 2.

pYYBAGO-gSGAYznOAAFC_NOAORw301.png

Figure 2 STM32 memory partitioning

Bootloader code design

The bootloader is something that is a special program for us, but for the computer it is no different from millions of ordinary programs, so we need to initialize this program as well, you can set the clock, set the serial port or CAN bus resources, etc.. These are all necessary, and we will not discuss them in the text.

A more important point that needs to be discussed is the jump program, because the Bootloader, in addition to completing some additional work that is not suitable for completion in the application, the most important point is the program jump, that is, “JampToApp()”. The so-called program jump, so how to achieve the program jump?

Think about it, the jump is ultimately jumped to the APP address through Bootloader, in C language and jump is directly related to the pointer, so can guarantee both jump to a certain address, but also to ensure that it is similar to the function can be run, only the “pointer to the function” this item. Yes, the Bootloader’s “JampToApp()” operation is a function pointer, and it only needs to know the address of the APP area to make the jump.

In the previous section, we specified that the address of APP is 0x08002800, so is it enough to jump to this address? The answer is of course no, because as we said before, the starting 4 byte address of the STM32 memory space holds the stack top pointer, so we need to jump to the address 0x08002800+4.

In the process of jumping, it is also necessary to turn off interrupts, etc. The specific code is shown in Figure 3.

poYBAGO-gS6AGOD6AAIVWCRubCQ426.png

Figure 3 Bootloader Jumpers

In the above code, there is a custom “TYP_drcPtr” type, which starts as a void type.

typedef void (*TYP_drcPtr)(void); //Define the jump pointer

The jump problem is solved, the next question is when to jump?

I recommend that you judge and jump before initializing the Systemclock at the beginning of the program, because if you initialize the Systemclock in the Bootloader and then go to the APP area to initialize it, it will cause a hardware error, so I recommend that when you design the Bootloader, the program should start by checking whether the jump is satisfied. Therefore, I suggest that when you design the Bootloader, the program should start by detecting whether the jump conditions can be met, and jump immediately if they are met, and then execute the hardware initialization procedure if they are not met. As shown in Figure 4.

poYBAGO-gUOAEkh8AAL-sBQqKhQ840.png

Figure 4 STM32 jump timing

Well, the last word, “Talk is easy, show me your code”, I have debugged the successful bootloader please git yourself.

    GET A FREE QUOTE

    FPGA IC & FULL BOM LIST

    We'd love to

    hear from you

    Highlight multiple sections with this eye-catching call to action style.

      Contact Us

      Exhibition Bay South Squre, Fuhai Bao’an Shenzhen China

      • Sales@ebics.com
      • +86.755.27389663