Study notes on implementing IAP function in STM32

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

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.


Keywords:STM32 Reference address:Study notes on implementing IAP function in STM32

Previous article:ARM Linux S3C2440 UART Analysis
Next article:How to transplant mqtt on stm32 in a few steps

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号