Recently, due to project requirements, we need to implement the online upgrade function of STM32, that is, IAP. I will first summarize the learning experience and the specific implementation of IAP in the past few days and share it with you. I hope it will be helpful to those who also implement IAP. At the end of the article, a compressed file named STM32_Update.zip will be uploaded, which contains the source code files of STM32_App, STM32_MyBoot_V1.0 and the upgrade software STM32_UpdateSoftware for your reference. All programs have been tested and can be run directly on the development board of Atom Brother. You can directly open
STM32_Update\STM32_UpdateSoftware\Release\STM32_UpdateSoftware.exe to upgrade the upgrade software of the host computer. If you need to view the source code, please use VS2010 to open the project file.
The final goal is:
the MCU will run the Boot program first every time it is powered on, check the flag bit. If the flag bit is FLAG_TO_APP, it will jump directly to the App program to run. If the flag bit is FLAG_TO_BOOT, it will run the Boot program to prepare for the upgrade. When running the App program, after receiving the upgrade instruction, the upgrade flag FLAG_TO_BOOT will be written somewhere in the FLASH, and the Boot program will be loaded. The Boot program will accept the new program file and store it in the corresponding FLASH space. After the upgrade is completed, FLAG_TO_APP will be written in the flag space, and the new program will be run.
The post includes the following aspects:
1. What is IAP?
2. STM32 boot mode?
3. STM32 FLASH distribution?
4. STM32 program running process?
5. BootLoader program writing (how to realize dynamic program loading)?
6. App program writing?
7. Bin file conversion?
8. Introduction to the host computer serial port upgrade software
--------------------------------------------------------------------------------------------------
1. What is IAP?
The various materials on the Internet about IAP are also quite clear, so I will briefly introduce it here. IAP (In Application Programming) is online application programming, that is, users can use their own programs to burn a certain area of the User Flash of the microcontroller (generally the area where their own programs are stored). In real work, after the product is released, it is very convenient to use the reserved communication interface (serial port, USB, network port, Bluetooth, etc.) to complete the program upgrade, thus avoiding the need to disassemble the machine and use the downloader to burn the program. To realize the IAP function, two parts of code are generally designed. One is the BootLoader program, which is stored in a certain location of the FLASH and is mainly used to guide and upgrade the App program; the other is the App program, which is the functional program for realizing the product. The update and upgrade of the App program is completed through the BootLoader, which is the IAP function.
2. STM32 startup mode
Many beginners do not know much about the startup of STM32. This is also introduced in the "STM32 Reference Manual" and various online materials. Here is a brief introduction:
STM32 has three startup modes, which are mainly controlled by the connection method of the pins BOOT0 and BOOT1, as shown in the figure below. Because we want the program to start from the main memory, we should choose the first method to connect BOOT0 to GND when designing the hardware, and BOOT1 can be pulled high or low.
Note: When STM32 is powered on, it does not directly enter the main function, but first initializes the system. This function is called when the reset interrupt Reset_Handler is executed in the startup file startup_stm32f10x_hd.s (because my microcontroller is STM32F1 03RCT6, a large-capacity chip, so this file is used). The main function will not be entered until the reset interrupt is executed.
3. Distribution of STM32 FLASH
The size and address allocation of FLASH of each type of STM32 microcontroller are introduced in the chip manual. I use the STM32F103RCT6 model, whose FLASH is 256K and belongs to a large-capacity product.
The distribution of FLASH is as follows: The address of the main storage block is from 0x08000000 to 0x0803FFFF, a total of 256K.
When designing the program, we divide FLASH into 3 parts. The first part is from 0x08000000 to 0x0800FFFF, a total of 64K to store the BootLoader program, the second part is from 0x08010000
to 0x0802FFFF, a total of 128K to store the App program, and the third part is from 0x08030000 to 0x803FFFF, a total of 64K to store the flag bits and others of the program running, as shown below:
4. The running process of STM32 program
The running process of STM32 program is also introduced in many materials. Because the STM32F103 microcontroller is based on the Cortex-M3 core, its internal part mainly responds to various interrupts through the interrupt vector table. The starting address of the internal flash memory is 0x08000000, and the starting address of the interrupt vector table is 0x8000004. After the program is started, the reset interrupt vector will be taken out from the "interrupt vector table" to execute the reset interrupt program to complete the startup. When the interrupt comes, the internal hardware mechanism of STM32 will automatically position the PC pointer to the "interrupt vector table" and take out the corresponding interrupt vector according to the interrupt source to execute the corresponding interrupt service program.
As shown in the figure above, the normal startup process of STM32 is:
a. After STM32 is powered on, it will take out the address of the reset interrupt vector from 0x8000004 and jump to execute the reset interrupt service program, as shown in label 1;
b. After the reset interrupt reset program is executed, it will jump to our main function as shown in label 2;
c. The main function is generally an infinite loop. When it receives an interrupt request, STM32 will force the PC pointer to point to the interrupt vector table, as shown in label 3;
d. Query the interrupt vector table and jump to the corresponding interrupt service program according to the interrupt source to execute the corresponding operation; as shown in labels 4 and 5;
e. After executing the interrupt service program, it will return to the main function, as shown in label 6.
The above is the normal operation process of STM32. After adding the IAP program, the operation process is as follows:
After adding IAP, the program runs as follows:
a. After STM32 is reset, it still obtains the address of the interrupt vector table from 0x8000004 and jumps to execute the reset interrupt service program, as shown in label 1;
b. After executing the reset interrupt service program, it calls back to the main function of IAP, as shown in label 2;
c. The IAP process is to receive the program file through a selected communication method (such as serial port) and store it in the specified FLASH space. Then the new program will be loaded, and the
reset interrupt vector starting address of the new program is 0X08000004+N+M. The address of the reset interrupt vector of the new program is taken out, and the reset interrupt service program of the new program is jumped to execute, and then jump
to the main function of the new program, as shown in numbers 3 and 4;
d. At this time, there will be two interrupt vector tables in the FLASH of STM32. During the execution of the main function of the new program, when an interrupt comes, the PC pointer will still jump back to the
interrupt vector table with an address of 0x8000004, instead of the interrupt vector table of the new program. This is determined by the hardware mechanism of STM32, as shown in number 5;
e. Query the interrupt vector table and jump to the new interrupt service program according to the interrupt source to perform the corresponding operation, as shown in number 6;
f. After executing the interrupt service program, it will return to the main function, as shown in numbers 7 and 8.
Note:
From the above, we can know that the new program must be placed in a certain address after the IAP program in FLASH. Here, my program is set to 0x08010000, that is, the offset is 0x10000, and the
interrupt vector table of the new program must also be offset accordingly, and the offset is also 0x10000 (the address setting can be achieved by compiling the software, which will be introduced below).
5. Writing the BootLoader program
The main function of the BootLoader program is to receive the new program and store it in a specific location of the FLASH, and then load the new program to run. Each time the microcontroller is powered on, it will first read a
flag bit, and decide whether to run the APP program or run itself to upgrade based on this flag bit.
flag = STMFLASH_ReadHalfWord(FLASH_ADDR_UPDATE_FLAG); (FLASH_ADDR_UPDATE_FLAG is the address of 0x08030000)
When flag = FLAG_TO_APP, the App program is loaded, otherwise the upgrade program is executed.
In my program, the program bin file is transmitted through the serial port. In order to ensure communication security, a communication protocol is formulated. There are two types of serial port reception:
a. Receiving instructions, the length is 16 bytes, the protocol example is
test[16] = {55, aa, 01, instruction length, command code, 00,00,...00, and check digit}
and check digit = 0 - the sum of the first 15 bytes,
b. Receiving program files, each packet of data is (2048 + 6) bytes, the example is:
test[2054] = {55, aa, 01, packet number, command code, data file 2048 bytes, and check digit}
The reason for setting the above communication protocol is to ensure the correctness of data transmission.
The main function of the Boot program
The main function of the Boot program mainly reads the flag and decides whether to load the existing App program or run its own upgrade program according to the value of the flag. When it is running, it will periodically send the BOOT preparation completion instruction to the host computer software, telling the host computer that I am ready, and run ReceiveUsartData(); according to the flag information in the serial port interrupt to complete the reception of instructions and program files.
int main(void)
{
int flag = 3;
int nCount = 0;
delay_init();
uart_init(115200);
LED_Init();
TIM3_Init(99, 719); //10ms timing
flag = STMFLASH_ReadHalfWord(FLASH_ADDR_UPDATE_FLAG); //Read flag bit
while(1)
{
//FLASH_EraseAllPages(); //Only open when erasing all FLASH
if(flag == FLAG_TO_APP)
{
Iap_Load_App(FLASH_ADDR_APP);
}
else
{
ReceiveUsartData(); //Serial port receiving
if(Flag10MS == 1)
{
Flag10MS = 0;
nCount++;
if(nCount == 10) //100ms
{
nCount = 0;
USARTxSendRespondToServer(USART1, SERIAL_CODE_STM32_UPDATE_PREPAR_BOOT_OK); //Cannot send too fast or there will be dirty data
LED0 = !LED0;
}
}
}
}
}
Serial port initialization program
Use STM32's USART1, set the baud rate to 115200, 8-bit data length, 1 stop bit, and no parity bit.
For specific implementation, see the uart_init() function in the source code.
Serial port interrupt service routine void USART1_IRQHandler(void)
In the serial port interrupt service program, the main function is to receive the data sent by the host computer upgrade software. When UpdateFlag is set to 1, the data of the bin program file is received. When
the count of UsartRxCodeCount is equal to the total number of bytes transmitted per packet USART_RECEIVE_CODE_DATA_SIZE, the reception completion flag UsartReceiveFlag = 1 and NextPageFlag = 1 are set
to jump out of the interrupt to ReceiveUsartData() for processing, and the received data is stored in the specified location of FLASH. The loop continues until all files are received. The receiving method of the upgrade instruction
is the same, see the code for details.
(Note: In the interrupt service function, try not to do other operations, only set the flag, and perform specific operations in the external function.)
Reload code program
In order to realize the jump between Boot and App programs, the new program file must be reloaded after the upgrade is completed, which involves embedding assembly language in C language. The code is as follows:
void MSR_MSP(u32 addr)
{
//asm("MSR MSP, r0"); //Use these two sentences when using Keil embedded assembly
//asm("BX r14");
__ASM("msr msp, r0"); //set Main Stack value Save the main stack address to the MSP register (R13)
__ASM("bx lr"); //Jump to the address stored in lr. bx is a forced jump instruction lr is a connection register, which is R14 of the STM32 microcontroller
}
typedef void (*IapFun)(void); //Define a function type parameter
IapFun JumpToApp;
//Jump to the application AppAddr: the starting address of the user code.
void Iap_Load_App(u32 AppAddr)
{
if(((*(vu32*)AppAddr)&0x2FFE0000)==0x20000000) //Check whether the top address of the stack is legal.
{
JumpToApp = (IapFun)*(vu32*)(AppAddr+4); //The second word in the user code area is the program start address (new program reset address)
MSR_MSP(*(vu32*)AppAddr); //Initialize the APP stack pointer (the first word in the user code area is used to store the top address of the stack)
JumpToApp(); //Set the PC pointer to the address of the new program reset interrupt function and execute downwards
}
}
First, if(((*(vu32*)AppAddr)&0x2FFE0000)==0x20000000) is used to check whether the stack top address is legal. (*(vu32*)AppAddr) removes the data in the first
address , and this data is the stack address of the user code. The stack address points to RAM, and the starting address of RAM is 0x20000000. Therefore, the avoid statement can be used to determine
whether the user's stack address is legal.
After judging that the stack top address is legal, take out the address of the new reset interrupt function, that is, (vu32*)(AppAddr+4), and assign it to the function pointer JumpToApp, then call
the MSR_MSP() function to assign the main stack pointer to the MSP register, and finally call JumpToApp(); to execute the new program.
(This involves the knowledge of function pointers. You must understand that the function name itself is the entry address of the function. Its essence is an address.)
The above involves the knowledge of embedded assembly, which may not be explained very thoroughly. Interested friends can refer to the "Cortex-M3 Authoritative Guide" for more information.
Interrupt vector table setting and start address setting (IAR software)
The method to set the interrupt vector table and the entry address of the program in IAR software is as follows:
1. Open the project, right-click on the project name STM32_BOOT_v1.0--Options
2. Select Linker--Edit.
3. Set the address of the interrupt vector table Vector Table and the value of Memory Regions
6. Writing the App program
The App program is relatively simple. It mainly consists of two parts. One is the main function of the program to be implemented (such as lighting up the LED), which is mainly what you want the App to do; the other is to query the upgrade instruction through the serial port. When the upgrade command is received, the FLAG_TO_BOOT flag bit must be written at the address of FLASH_ADDR_UPDATE_FLAG, and Iap_Load_App()l is called to load and run the BootLoader program to complete the upgrade. For details, please see the source code.
For App programs, the offset of the interrupt vector table should be set through the statement SCB->VTOR = FLASH_BASE | FLASH_VTOR_OFFSET;. The variable FLASH_VTOR_OFFSET in the program is #define FLASH_VTOR_OFFSET ((uint32_t)0x10000) because the storage address of our App program is 0x08010000, and the offset relative to 0x08000000 is 0x10000. In addition, the value of Vector Table and Memory Regions should be set to 0x08010000 when the program is compiled.
7. Conversion of bin files
When upgrading the program, it is best to use bin format files for the compiled program files, because bin files are much smaller than hex files and thus occupy less FLASH. This is a more subjective advantage. When using IAR software to compile, you can output bin format executable files by setting the software. The settings are as follows:
a. Open the Options tab of the project and select Output Converter
b. Select binary format in the Output format option, and at the same time set Override The default output file suffix is changed to .bin, so that
the compiled executable file in bin format can be found in the corresponding project directory (mine is STM32_App\Project\EWARM5\Debug\Exe).
8. Introduction to the host computer upgrade software
My host computer upgrade software is written in C++. The specific coding is not introduced. Friends who want to know can refer to the source code. The dialog interface is as follows:
First set the port number and baud rate, then connect the serial port. After the connection is successful, click "Select the file to upgrade" to implement the upgrade.
After the upgrade is completed, it will prompt "Upgrade completed".
At this point, my IAP implementation introduction is completed. If you have any questions or if you find any bugs in my program, you can raise them and discuss them together. I hope the above content will be helpful for everyone to learn STM32.
Previous article:ARM Linux S3C2440 UART Analysis
Next article:How to transplant mqtt on stm32 in a few steps
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Sn-doped CuO nanostructure-based ethanol gas sensor for real-time drunk driving detection in vehicles
- Design considerations for automotive battery wiring harness
- Do you know all the various motors commonly used in automotive electronics?
- What are the functions of the Internet of Vehicles? What are the uses and benefits of the Internet of Vehicles?
- Power Inverter - A critical safety system for electric vehicles
- Analysis of the information security mechanism of AUTOSAR, the automotive embedded software framework
- Brief Analysis of Automotive Ethernet Test Content and Test Methods
- How haptic technology can enhance driving safety
- Let’s talk about the “Three Musketeers” of radar in autonomous driving
- Why software-defined vehicles transform cars from tools into living spaces
- How to connect unused op amps in the same package?
- Help analyze this small wind power generation circuit
- Lessons learned from transplanting LwIP on C6414
- [NXP Rapid IoT Review] Bluetooth Control RGB
- [National Technology N32G457 Review] Comparison between development board N32G457 and AB32VG1
- I2C pull-up levels
- It’s the middle of the year, how are your 2021 plans/goals going?
- [TI recommended course] #Optimizing system-level design through industrial Ethernet#
- 【SC8905 EVM Review】+My Review Report
- About LD driver and TEC refrigeration chip driver