STM32 A method to call the Bootloader in the system memory from the user code

Publisher:CaptivatingGazeLatest update time:2017-11-07 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Preface
As we all know, any STM32 contains a system memory, which stores the internal boot code Bootloader. Different
STM32 models support different communication ports for upgrading code, and you need to refer to the application note AN2606. However, there is a problem that cannot be avoided, that is,
how to enter the System Memory to execute the Bootloader? The usual way is to configure BOOT1 and BOOT0: BOOT0 is pulled high and BOOT1 is pulled low
(some models of BOOT1 are controlled by the option byte nBOOT1). However, in some products, due to the requirements of appearance, it is often inconvenient to open the outside to
place buttons or jumpers to change the level of the BOOT pin. Moreover, users do not want to write IAP code by themselves, which is troublesome. Especially for some products, USB DFU is needed
for code upgrade, but USB is not used in the product function. Users will feel that if they want to write
IAP for the function of code upgrade through USB, they need to be familiar with USB code, which is troublesome, and these USB codes also occupy the user's program space. For these users, they really
hope to be able to call the Bootloader of System Memory in STM32 without paying attention to the BOOT pin to complete the code upgrade function.

Problem
A customer used STM32F411 in the design of his product. Due to the requirements of the product appearance, the BOOT pin cannot be controlled externally, and only the
USB interface is left outside in appearance, so USB DFU is needed for upgrade. Moreover, the USB interface is only used for code upgrade and has no other functions, so the customer does not want to touch
the USB code and hopes to directly use the Bootloader in System Memory for code upgrade.

Research
1. Determine its feasibility
First, open the application note AN2606 "STM32 microcontroller system memory boot mode", turn to the
end of section 3.1 Bootloader activation, and you can see the following information:
STM32 A method to call the Bootloader in the system memory from the user code 

What this means is that users can execute the Bootloader by jumping from user code to system memory. However, before jumping to the Bootloader,
several things must be done:
1) Turn off the clocks of all peripherals
2) Turn off the used PLL
3) Disable all interrupts
4) Clear all pending interrupt flags
Finally, you can execute the user code by leaving the Bootloader activation condition and generating a hardware reset or directly using the Go command.
So, how do you jump from user code to System Memory? This is not difficult. If you have written IAP or read
the reference code in the application notes about IAP , such as the application note AN3965 "STM32F40x/STM32F41x in-application programming using the USART" and its reference
code STSW-STM32067, you should know that the startup code of IAP executes the user code by resetting the main stack pointer and jumping to the user code. In the same
way, as long as you know the address of the System Memory, you can also execute
the Bootloader from the user code by resetting the main stack pointer and jumping to the System Memory. The System Memory address can be obtained from the reference manual. For example, looking at the reference manual RM0383 of the STM32F411, you can find the following
table:
STM32 A method to call the Bootloader in the system memory from the user code 
You can know that the System memory address of the STM32F411 starts from 0x1FFF0000.

Then many people will ask, my code is very complicated, using many peripherals and opening many interrupts, but to jump to the Bootloader in System Memory, it is necessary to turn off
the clocks of all peripherals, turn off the PLL, turn off all interrupts, disable all interrupts, and clear all pending interrupts. This is a very huge
task! So here, we need a simpler thing to complete this huge task. In fact, there is such a simple method-reset! This can
be achieved through software reset. However, after the reset, how do you know that you still remember that we want to upgrade the code? This requires another feature of STM32,
that is, the backup data registers will retain their values ​​after the software reset, which gives us the opportunity to make a mark before and after the reset.
In this way, after verification, the customer's needs are feasible. The next thing to do is to sort out the ideas.

2. Software flowHere
, we use the 32F411EDISCOVERY board to design a reference routine: design a user program to make LED3 flash; when the user button is pressed, an
EXTI interrupt is generated, and the backup data register RTC_BKP0R is selected in the interrupt, and the value 0x32F2 is written, and then a software reset is generated; after the software reset,
RTC_BKP0R is judged at the beginning of the running code. If its value is not 0x32F2, the user code is run directly. If its value is 0x32F2, it is necessary to jump to
the Bootloader for code upgrade, and RTC_BKP0R is cleared before the jump. In this way, after entering the Bootloader, after the customer performs a USB DFU upgrade, he
will not mistakenly enter the Bootloader in the future due to a reset that does not require an upgrade code. Let
's look at the software flow chart, first look at the flow chart of the main program:
STM32 A method to call the Bootloader in the system memory from the user code 

Then look at the flow chart of the EXTI interrupt:
STM32 A method to call the Bootloader in the system memory from the user code 

3. The main code
uses the STM32F4Cube library to develop this routine. Let's first look at the main function in main.c:
STM32 A method to call the Bootloader in the system memory from the user code 
The main function is very simple. It configures the system clock, initializes the LEDs used, and then configures the EXTI interrupt of the user's button, and then enters the main loop. As mentioned
earlier , to implement the user's function program for LED3 flashing, we did not see it in the main loop because SysTick is used in the Cube library, so
the flashing of LED3 is placed in the interrupt code of SysTick. Check stm32f4xx_it.c, as follows:
STM32 A method to call the Bootloader in the system memory from the user code 
From the first comment of the main function, we know that before jumping into the main function, the startup_stm32f411xe.s has already called and executed the
SystemInit function in system_stm32f4xx.c. SystemInit function mainly performs
functions such as Since we want to enter System Memory in the most original state, we put the jump to System Memory at the beginning of this function,
as follows:
STM32 A method to call the Bootloader in the system memory from the user code 

As you can see, RTC_BKP_DR0 is judged at the beginning of the function. If its value is 0x32F2, the access timing of the backup domain is started first, as
described in 5.1.2 Battery backup domain in RM0383:
STM32 A method to call the Bootloader in the system memory from the user code 

Then RTC_BKP_DR0 is cleared, and then the clock turned on for this operation is turned off.
The initial value of the main stack pointer MSP is located at the offset 0x00 of the vector table, and the reset value is located at the offset 0x04 of the vector table. For
STM32F411, when executing the Bootloader in System Memeory, the initial value of MSP is at 0x1FFF0000, and Reset is at
0x1FFF0004. So in the program, use __set_MSP(*(__IO uint32_t*) 0x1FFF0000); to reset the main stack pointer, and then jump to
0x1FFF0004 to execute the Bootloader.

Let's look at the EXTI interrupt program in stm32f4xx_it.c:
STM32 A method to call the Bootloader in the system memory from the user code 

and its Callback function in main.c:
STM32 A method to call the Bootloader in the system memory from the user code 

When it is determined that the user button is pressed and the user code needs to be upgraded, the access sequence of the backup domain is started first, and the value of RTC_BKP_DR0 is written to 0x32F2. Then read it
back to determine whether the write is successful, so as to facilitate debugging. If the write is successful, call HAL_NVIC_SystemReset() to reset the software. After resetting,
you can enter the System Memory.

4. Experiment
Use 32F411EDISCOVERY to do the experiment.
1) Compile the program and download it to the 32F411EDISCOVERY board. You can see LED3 flashing.
STM32 A method to call the Bootloader in the system memory from the user code 

2) Press the User button, LED3 turns off, and the system memory has entered the Bootloader.
3) Open the DfuSeDemo software. There is no display in Available DFU Devices.
STM32 A method to call the Bootloader in the system memory from the user code 

4) Insert a USB Micro cable into CN5 of the 32F411EDISCOVERY board. LED7 lights up and the USB is connected.
STM32 A method to call the Bootloader in the system memory from the user code 

5) After the driver is completed, you can check DfuSeDemo again. Available DFU Devices is displayed as "STM Device in DFU Mode",
which means it has been successfully driven and works normally. 6) After that, it is the normal process of upgrading the code. Click the "Choose" button to select the code to be updated. Here is a demo program of the 32F411EDISCOVERY board. The file 32f411ediscovery.dfu generated by the Dfu file manager software
STM32 A method to call the Bootloader in the system memory from the user code 

is prepared . Import it . 7) Click the "Upgrade" button to upgrade, and select Yes in the pop-up dialog box. Then the upgrade is successful. 8) Click "Leave DFU mode" again, and the progress bar will show "Successfully left DFU mode!", then you can enter the updated user code, and you can see that the 4 LED lights are scrolling and flashing normally and happily... Note that this routine is only for verifying its feasibility. In actual application, there are some imperfections that please be improved by the user. In addition, there are a few points to note: 1) This Demo code is based on STM32Cube_FW_F4_V1.11.0. After decompression, you can put it into \STM32Cube_FW_F4_V1.11.0\Projects\STM32F411E-Discovery\Templates to replace the original source code file, and then compile and run. 2) This program uses key press as a condition to trigger the software code upgrade. Users can modify the trigger condition according to their own situation, such as pressing multiple keys at the same time, etc. 3) If the RTC is used in the user application, the RTC clock source cannot be modified once it is selected unless the backup domain is reset. It is mentioned in the description of RCC_BDCR in RM0383: 4) For how to use Dfu file manager to generate .dfu files, please refer to UM0412 "Getting started with DfuSe USB device firmware upgrade" or practical experience "Using USB DFU to implement IAP function". 5) For the USB DFU protocol used in the Bootloader, please refer to AN3156 "USB DFU protocol used in the STM32 bootloader". Document and code download address: http://www.stmcu.org/document/detail/index/id-217309 http://www.stmcu.org/document/download/index/id-212785 Practical experience summary: http://www.stmcu.org/module/forum/thread-606863-1-1.html

STM32 A method to call the Bootloader in the system memory from the user code 


STM32 A method to call the Bootloader in the system memory from the user code 



STM32 A method to call the Bootloader in the system memory from the user code 










STM32 A method to call the Bootloader in the system memory from the user code 









Keywords:STM32 Reference address:STM32 A method to call the Bootloader in the system memory from the user code

Previous article:stm32 HardFault_Handler debugging and problem finding method
Next article:STM32 uses BSRR and BRR registers to quickly operate GPIO ports

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号