This is a dry article about the program online upgrade that I saw on the Internet, and I will learn it with everyone. There are some hyperlinks and source code interspersed in the original text, which cannot be synchronized here. It is recommended to read the original text. For the original text, see the original link of this tweet.
1. Basic knowledge of online upgrade
What is BootLoader?
BootLoader
It can be understood as a boot program, its function is to start the formal App应用程序
. In other words, it BootLoader
is a program, and App is also a program, which BootLoader程序
is used to start App程序
.
Where is the program in STM32?
Under normal circumstances, we write the program are placed in the STM32 chip Flash memory (not consider external expansion Flash). We write the code will eventually become a binary file into Flash, you can check out in Keil
>>> Debug
> Memory
View in >> , the code stored in the Memory window on the right is:
Then you can enter the topic.
Partition
Since the programs we write will become binary files and stored in Flash, then we can further partition our programs. What I use is F103RB-NUCLEO开发板
that his Flash has 128 pages, 1K per page. See the picture below:
It as an example, I divide it into three zones. BootLoader区
, App1区
, App2区(备份区)
Specific division in the following figure:
BootLoader区
Store startup codeApp1区
Store application codeApp2区
Store the temporary upgrade code
Overall flow chart
Execute the
BootLoader
program first , first checkAPP2
whether there is a program in the area, if there is, copy the program in the App2 area (backup area) to itApp1区
, and then jump to the executedApp1
program.Then execute
App1
the program, becauseBootLoader
, andApp1
both programs are not the same as to the scale, so the jump toApp1
after the first step is to go to change the program vector table. Then go execute other applications.The program upgrade part will be added to the application. The main work of this part is to get the upgrade program, and then put them in
App2区(备份区)
, so that theBootLoader
updatedApp1
program can be passed the next time it is started . The flowchart is shown below:
2. About BootLoader
Flow chart analysis
Take the BootLoader of my routine as an example:
I use
App2区
the last byte (0x0801FFFC
) to indicateApp2区
whether there is an upgrade program. After the STM32 is erased, the flash data is stored0xFFFFFFFF
. If there is, we will store this address0xAAAAAAAA
. The specific flowchart is shown in the figure below
Programming and analysis
The required STM32 resources are:
Send USART data and printf redirect
Flash read and write
Program jump instruction: You can refer to the following code:
/* 采用汇编设置栈的值 */
__asm void MSR_MSP (uint32_t ulAddr)
{
MSR MSP, r0 //设置Main Stack的值
BX r14
}
/* 程序跳转函数 */
typedef void (*Jump_Fun)(void);
void IAP_ExecuteApp (uint32_t App_Addr)
{
Jump_Fun JumpToApp;
if ( ( ( * ( __IO uint32_t * ) App_Addr ) & 0x2FFE0000 ) == 0x20000000 ) //检查栈顶地址是否合法.
{
JumpToApp = (Jump_Fun) * ( __IO uint32_t *)(App_Addr + 4); //用户代码区第二个字为程序开始地址(复位地址)
MSR_MSP( * ( __IO uint32_t * ) App_Addr ); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
JumpToApp(); //跳转到APP.
}
}
Just execute this function where you need to jump
IAP_ExecuteApp(Application_1_Addr);
For other codes, please refer to the `BootLoader source code, the source code can be obtained by viewing the original text.
3. About APP
Flow chart analysis
Take my journey App1 as an example:
Modify the vector table first, because this program is jumped over by BootLoader, there will be problems after not modifying the vector table.
Print version information for easy viewing of different App versions
The upgrade program of this example uses the Ymoderm protocol of the serial port to transfer bin files. The specific flowchart is shown in the figure below
Programming and analysis
The required STM32 resources are:
For the use of printf, please refer to: https://blog.csdn.net/weixin_41294615/article/details/86154538
Flash read and write, for details, please refer to: https://blog.csdn.net/weixin_41294615/article/details/87610039
DMA transceiver of the serial port, please refer to https://blog.csdn.net/weixin_41294615/article/details/86218556 for details
YModem protocol related, please refer to https://blog.csdn.net/weixin_41294615/article/details/104652105 for details
Ymodem protocol
Baidu Encyclopedia Ymodem Protocol
For the specific process, you can find relevant documents by yourself, here is an XYmodem.pdf I found.
For the introduction of Ymodem protocol, please refer to this tutorial of mine https://blog.csdn.net/weixin_41294615/article/details/104652105
Code analysis
Most of the code is through the serial port to realize the Ymodem protocol reception, which will not be explained in detail here
I put my source code behind, please refer to my source code for details.
The main function adds instructions to modify the vector table
Print version information and jump instructions
YModem related file receiving part
/**
* @bieaf YModem升级
*
* @param none
* @return none
*/
void ymodem_fun(void)
{
int i;
if(Get_state()==TO_START)
{
send_command(CCC);
HAL_Delay(1000);
}
if(Rx_Flag) // Receive flag
{
Rx_Flag=0; // clean flag
/* 拷贝 */
temp_len = Rx_Len;
for(i = 0; i < temp_len; i++)
{
temp_buf[i] = Rx_Buf[i];
}
switch(temp_buf[0])
{
case SOH:///<数据包开始
{
static unsigned char data_state = 0;
static unsigned int app2_size = 0;
if(Check_CRC(temp_buf, temp_len)==1)///< 通过CRC16校验
{
if((Get_state()==TO_START)&&(temp_buf[1] == 0x00)&&(temp_buf[2] == (unsigned char)(~temp_buf[1])))///< 开始
{
printf("> Receive start...\r\n");
Set_state(TO_RECEIVE_DATA);
data_state = 0x01;
send_command(ACK);
send_command(CCC);
/* 擦除App2 */
Erase_page(Application_2_Addr, 40);
}
else if((Get_state()==TO_RECEIVE_END)&&(temp_buf[1] == 0x00)&&(temp_buf[2] == (unsigned char)(~temp_buf[1])))///< 结束
{
printf("> Receive end...\r\n");
Set_Update_Down();
Set_state(TO_START);
send_command(ACK);
HAL_NVIC_SystemReset();
}
else if((Get_state()==TO_RECEIVE_DATA)&&(temp_buf[1] == data_state)&&(temp_buf[2] == (unsigned char)(~temp_buf[1])))///< 接收数据
{
printf("> Receive data bag:%d byte\r\n",data_state * 128);
/* 烧录程序 */
WriteFlash((Application_2_Addr + (data_state-1) * 128), (uint32_t *)(&temp_buf[3]), 32);
data_state++;
send_command(ACK);
}
}
else
{
printf("> Notpass crc\r\n");
}
}break;
case EOT://数据包开始
{
if(Get_state()==TO_RECEIVE_DATA)
{
printf("> Receive EOT1...\r\n");
Set_state(TO_RECEIVE_EOT2);
send_command(NACK);
}
else if(Get_state()==TO_RECEIVE_EOT2)
{
printf("> Receive EOT2...\r\n");
Set_state(TO_RECEIVE_END);
send_command(ACK);
send_command(CCC);
}
else
{
printf("> Receive EOT, But error...\r\n");
}
}break;
}
}
}
Some of the functions are not shown in the above code. For details, please refer to the source code below (free) and read the original text to get it.
4. Verify the upgrade function
Code download
It can be seen from the figure below that the download areas of the two codes are different
So they download different areas
BootLoader download
The BootLoader code is the first by default, so there is no need to set the download location of the code.
According to the figure below, modify the erasing method as
Erase Sectors
, the size is limited to0X5000
(20K)
Burn code
Run, print output through serial port 1, you will see the following print message
Indicates that BootLoader has successfully run
Download of App1
App1 is a little more complicated, you need to set the starting position of the code to
0x08005000
At the same time, the erasing method must be modified
Erase Sectors
, see the figure below
Burn code
Run, print output through serial port 1, you will see the following print message
Description
BootLoader
has successfully jumped to version 0.0.1App1
Generate App2's .bin file
How Keil generates .bin files, please refer to this blog post How Keil generates .bin files
Modify the code, change the version number to 0.0.2, and compile and generate a .bin file
After the generation is complete, you will get a file ending in .bin, which is the file we will transfer to YModem later
File transfer using Xshell
Open Xshell
In the code, serial port 1 is used for printing debugging information, and serial port 2 is used for YModem upgrade
So use Xshell to open serial port 2 for file transfer, and use serial port 1 to view debugging messages through the serial debugging assistant. The specific process is as follows
You will see that the version of the App has been successfully upgraded to 0.0.2.
If you get to this point.
Congratulations! You are already able to use the online upgrade!
to sum up
Through the tutorials in these sections, you must already be able to use online upgrades. As long as you know the principles, other problems can be solved easily. In addition to using the YModem protocol to transfer .bin files, you can also transfer via Bluetooth, WIFI, and other protocols. As long as the .bin file can be transferred, the other parts of the principle are the same.
Author: IOT mustaches
Original: https://blog.csdn.net/weixin_41294615/article/details/104669766
1. Preview of the exciting content of the GD32 Arm MCU Internet of Things developer online course!
3. RISC-V is actually against the trend!
4. Don't ignore it! Fatal loopholes in embedded code!
5. Extra! LoRa long-distance communication "resident" MCU since then
6. Is technology really neutral?
Disclaimer: This article is reproduced online, and the copyright belongs to the original author. If you are involved in copyright issues, please contact us, we will confirm the copyright based on the copyright certification materials you provide and pay the author's remuneration or delete the content.