Analysis of stm32 serial port IAP routine

Routine acquisition

Sample codes and application notes can be obtained by visiting the official website www.st.com
Sample code: x-cube-iap-usart
Application note: an4657

At the same time, all the materials involved in this article can be downloaded here:
Link: https://pan.baidu.com/s/19nKPc_oOyRZCTfaNKTNHbw
Extraction code: q0ge

Project file structure

There are mainly two folders: Drivers and Projects, the former is the driver file of the HAL library and the sample development board BSP package, the latter is the sample project, there are examples of the three series of single-chip development boards F1, L0, and L4, but unfortunately there is no one for me. The routine of the stm32g412dicovery development board at hand, so it needs to be manually transplanted later. Bootloader mainly uses USART and CRC peripherals, the former is used for user interaction and file transfer, and the latter is used for file verification. Projects contains two folders: IAP_Main and IAP_Binary_Template, the former is the implementation of the bootloader (the main research object), and the latter is the user app template.
IAP_Main contains the main implementation files of the bootloader and the project adapted to the IDE. There is nothing to say about the project files. The main source code files that need to be analyzed are as follows:

  • main.c main.h : Main function entry, initialize peripherals and HAL library, call bootloader or jump to user program;
  • menu.c menu.h : command line menu implementation
  • ymodem.c ymodem.h : ymodem file transfer protocol implementation
  • flash_if.c flash_if.h : FLASH read and write functions
  • common.c common.h : Some common functions and macro definitions, mainly called in menu.c and ymodem.c

The call relationship between files is roughly as follows:

insert image description here

Ported to stm32g412discovery development board

I refer to the routine of STM32L476G_EVAL for transplantation. It turns out that it is more convenient to use another routine project of the same F series for transplantation.

  1. Directly use STM32CubeMX to generate an initialization project of stm32f412zgt6, using the internal clock. Add the main files mentioned above to the project
    insert image description here

  2. Enable the CRC and UART modules in the stm32f4xx_hal_conf.c file, and add the corresponding .c file to the project; replace the header file, replace stm32l4xx.h with stm32f4xx.h;

  3. COPY the contents of mian.c and main.h and modify the adaptation development board; re-implement the BSP_PB_Init and BSP_PB_GetState in the main function to initialize the button detection and obtain the button state. Here I directly use the official stm32412g development board. The BSP package has been changed; modify the IAP_Init function according to the situation. This function is mainly used to initialize the serial port and CRC peripherals. Here I initialize the serial port to UART2 according to the development board to use the virtual serial port of the onboard stlink. At the same time, due to the CRC of the stm32F4 series The peripheral does not support the CRC16 check calculation used by the Ymodem protocol, here you can remove the relevant initialization code, and use the software check later in the check;

  4. Modify other files according to the error information. The situation I encountered here is that common.c/.h files have a small amount of error reports, and flash_if.c/.h files have many errors. After all, the models are different, and the partitioning methods of the internal flash are very different. The left side of the figure below is the FLASH distribution of stm32l4xx, and the right side is the FLASH distribution of stm32f412.
    insert image description here
    Here is a suggestion. It is suggested to refer to the STM3210C_EVAL project in the routine when modifying the interface in flash_if.c. It should be transplanted based on this project at the beginning, which is really a miscalculation.
    When modifying the Option bytes read and write functions in flash_if.c, there is a place that confuses me. According to the printed information, the system should reset after updating the Option bytes settings, but it does not, and the demo does not modify the Option bytes. Re-read the update (maybe the demo writer thinks that the system will reset so there is no need to update it?), resulting in a discrepancy between the displayed menu and the actual situation. After executing the corresponding function in menu.c, add an update statement to solve this problem, as shown in the figure below .
    insert image description here
    There is another point to note. The original FLASH writing function FLASH_If_Write of the demo uses the DOUBLEWORD mode when writing to the FLASH. I don’t know why it is very easy to cause a write error to return HAL_ERROR on the F412. After changing the write mode to WORD mode This problem is solved, but it also leads to a decrease in writing speed. The modified and compared code is as follows:
    insert image description here
    After the transplantation is completed, the internal controls of FLASH are allocated as follows:
    Sector0~Sector1: bootloader space
    Sector2~Sector10: user program space
    Sector11: Free and unused (can be used for user programs to store some configuration information, etc.)

  5. Finally, you need to modify the ReceivePacket function in the Ymodem.c file, and replace the part that uses hardware to calculate CRC with software calculation. The routine has provided a calculation function Cal_CRC16, just call it directly.
    insert image description here

Instructions

There are two points to pay attention to when compiling user programs:

  1. Adjust the link address when linking according to the starting address of the user program set in flash_if.h. It can be set directly when using IAR and Keil. When using GCC, you need to directly modify the link file. Not to mention the method, there are a lot of them on the Internet;
  2. Modify the offset of the interrupt vector table, otherwise there will be problems with the interrupt jump. If the HAL library is used, modify the macro definition VECT_TAB_OFFSET in system_stmf4xx.c.

Regarding command interaction:

  1. The terminal tool recommended in the official application note AN4657 is Tera Term. It is too difficult to use after trying it. I used SecureCRT in my own test, and the usage method is similar. Just refer to the application note. Note that the transferred file is a binary file ending in .bin. It is not acceptable to transfer a .hex file. Generally, IDEs have the option to generate a .bin file.

Key Code Analysis

user program jump

insert image description here

The above is the jump code of the user program in the demo. According to the structure of the stm32 program, the start address of the program is the start address of the SP stack. Since the stack of the stm32 is located in the SRAM starting at address 0x20000000, the size of the SRAM is For the 128K STM32L476, the possible value of the SP start address is 0x20000000 to 0x2001FFFF. The comparison statement in the if is to compare whether the start address of the SP stack stored in the start address of the program is within the address range of the SRAM, so as to determine whether the user program is exist. The value of 0x2FFE0000 is obtained from 0x2FFFFFFF-0x2001FFFF, so this value should also be modified according to the actual SRAM memory size.

The jump in if is relatively simple. The address of the system reset vector is stored in the 4-byte offset of the program start address, which is the address of the first instruction to be executed. Call __set_MSP to set the MSP stack pointer After that, just jump to the first instruction and execute it just like calling a function. In fact, the PC pointer is pointed here.

User program download process

The user selects 1 in the menu to download the program. When the user makes a selection, the function call chain inside the program is as follows:
insert image description here

In the end, the function Ymodem_Receive actually performs the receiving work of the program data packet. As long as there is no error in the data transmission and the file has not been received, it will continuously call the function ReceivePacket to receive and analyze the data packet transmitted by the Ymodem protocol, and respond according to the processing result.

The overall Ymodem communication process during the user program download process is shown below. Here, only the normal process is given, and abnormal processing processes such as verification errors and FLASH writing errors are removed.
insert image description here

A blog is given to further understand Ymodem. Of course, if you have time and want to have a comprehensive understanding, it is better to read the official document
blog: https://blog.csdn.net/huangdenan/article/details/103611081

User program upload process

Temporarily unused, no analysis. At present, there is a problem with the upload function after transplantation. After simply reading the code, this demo will upload all the contents of the user area when uploading the user program, instead of uploading the actual program size. Don't worry about it, I will come back to make up this chapter someday when I use it.

epilogue

How to say the official demo, it can't be considered very well written, it is not satisfactory, I seriously doubt whether Cheng is outsourced. This routine can be used for learning, program transmission, FLASH programming, jumping, the basic functions of the bootloader are available, but if you really want to use it at work, it is more reliable to write a set by yourself. After all, the amount of code is not large. It doesn't take long to get up. I decided to take the time to write one myself anyway.
There are some other aspects of the bootloader that are worth investigating:

  • Transfer user programs through other interfaces (USB, CAN, etc.) other than the serial port
  • Handling of user program upgrade failures (the user area is divided into AB areas to ensure that a normal user program is available at all times)
  • Upgrade of bootloader itself
  • 。。。。。。

Guess you like

Origin blog.csdn.net/lczdk/article/details/123341840