当前位置:网站首页>How to use IAP to upgrade electronic products

How to use IAP to upgrade electronic products

2020-12-06 11:04:28 Procedural ape without hair loss

Catalog

1、ICP、ISP and IAP The concept of

2、IAP The principle of the upgrade program

3、IAP Upgrade process

4、IAR In the environment IAP The implementation of the

4.1、BootLoader Programming

4.2、User Application Programming

4.3、IAR Address configuration and file output

5、 expand : analysis HEX file


1、ICP、ISP and IAP The concept of

In the process of project development SWD、JTAG And other tools for program burning and simulation , If there are few product nodes, it is more convenient , But when the device node mass production , You need to use IAP Program burning .

Briefly explain a few concepts ICP、ISP and IAP.

ICP In-circuit programmer

ICP: In circuit programming ,MCU There's no need for internal procedures , Power on, you can program the program storage area , For example, we usually use JTAG、SWD Methods such as .

ISP In-system programer

ISP: In system programming , adopt MCU Special serial programming interface for programming ,MCU Need to have external conditions for operation , For example, there is a crystal oscillator .

for example STM32 By setting BOOT Pin setting corresponds to start mode , Then through the serial port and so on to the internal Flash upgrade , It can be said that in this way, the manufacturer has solidified a BootLoader Program .

IAP In-application programer 

IAP: In application programming , Developers design BootLoader Program , Through serial port 、CAN、 Ethernet and other means of communication to achieve program upgrade .

2、IAP The principle of the upgrade program

Usually a piece of MCU chip Of Code( Code ) There is only one user program in the zone , and IAP programme It's the code District Divided into Two parts , Two parts Each region Store a program , One for BootLoader( guide Loader ), For another User Application( user Applications ).

BootLoader stay When it leaves the factory It's fixed , In need of change User Application Only by triggering BootLoader Yes User Application Of Erase and re write in Can finish user Application replacement .

After the program is initialized, it will first enter BootLoader, stay BootLoader It detects whether the condition is triggered ( It can be determined by whether the key is pressed or not 、 Whether the serial port receives specific data 、U Whether the disc is inserted, etc ), If there is one, go ahead with it User Application Erase and rewrite new programs , If not, jump to BootLoader perform User Application.

3、IAP Upgrade process

Suppose the device only has User Application, With STM32F103ZET6 For example , There are three ways to start it : built-in FLASH start-up 、 built-in SRAM start-up 、 System memory ROM start-up . adopt BOOT0 and BOOT1 The setting of pin can choose which way to start , Choose the built-in FLASH start-up ,STM32F103ZET6 FLASH The address for 0x08000000—0x0807FFFF, common 512KB.

Usually STM32 The process of interruption is the following five steps :

1、 Interrupt occurred ( Interrupt request );

2、 Find the interrupt function entry address in the interrupt vector table ;

3、 Jump to interrupt function ;

4、 Execute interrupt function ;

5、 Interrupt return .

in other words ,STM32 Built in Flash There is an interrupt vector table to store the entry address of each interrupt service function , built-in Flash The distribution is shown in the figure below :

So when there's only one program ( have only User Applicatio when ), The trend of program execution is as follows :

Analyze the figure above :

STM32F103ZET6 There's a table of interrupt vectors , The interrupt vector table is stored after the beginning of the code 4 Bytes ( namely 0x08000004), Code start 4 The address of the top of the stack is stored in bytes , When an interrupt occurs, the program obtains the corresponding interrupt service program entry address by looking up the table , Then jump to the corresponding interrupt service program to execute .

After the device is powered on, it will start from 0x08000004 Take out the address of reset interrupt vector , Then jump to the entry of the reset interrupt program ( label ① Shown ), Jump to main Function ( label ② Shown ). In execution main An interrupt occurred in the process of the function , be STM32 Force will PC Pointer back to interrupt vector table ( label ③ Shown ), Find the corresponding interrupt function entry address from the interrupt vector table , Jump to the corresponding interrupt service function ( label ④ Shown ), After executing the interrupt function, return to main Function ( label ⑤ Shown ).

Now let's get to the point .

If the STM32F103ZET6 In the built-in Flash Add inside User Application and BootLoader Program , be Flash The distribution is shown in the figure below :

here ,User Application and BootLoader Each program has an interrupt vector table , hypothesis BootLoader The space occupied by the program is N+M byte , Then the program should go as shown in the figure below :

Analyze the figure above :

The initial power on procedure of the device is still from 0x08000004 Remove the reset interrupt vector address , Execute reset interrupt function and jump to IAP Of main( label ① Shown ), stay IAP Of main After the function is executed ( stay BootLoader It detects whether the condition is triggered ( It can be determined by whether the key is pressed or not 、 Whether the serial port receives specific data 、U Whether the disc is inserted, etc ), If there is one, go ahead with it User Application Erase and rewrite new programs , If not, jump to BootLoader perform User Application) Force jump to 0x08000004+N+M It's about ( label ② Shown ), Finally jump to the new main Function ( label ③ Shown ), When an interrupt request occurs , The program jumps to the new interrupt vector table and takes out the new interrupt function entry address , Then jump to the new interrupt service function to execute ( label ④⑤ Shown ), After executing the interrupt function, return to main Function ( label ⑥ Shown ).

4、IAR In the environment IAP The implementation of the

With IAR Environment, for example , Tell me briefly IAP Implementation steps of . here MCU Huada HC32L130 For example , Because of the use of MCU Different , So the implementation details are inconsistent , But basically, the government will provide Demo routine .

This example Flash The distribution is :BootLoader Address :0x00000000~0x00000DFF,User Application Address :0x00001000~0x0000FFFF.

4.1、BootLoader Programming

The first 1 Step : Design the overall architecture , It contains three function functions : testing BootLoader Marking program 、IAP Configurator and IAP Burning function program .

/**
 *******************************************************************************
 ** \brief  IAP  The main function 
 **
 ** \param  None
 **
 ** \retval int32_t Return value, if needed
 **
 ******************************************************************************/
int32_t main(void)
{
    IAP_UpdateCheck();
    IAP_Init();
    IAP_Main();
}

The first 2 Step : Check BootPara Marked area data value , Determine if you need to upgrade APP Program , If an upgrade is required, it will be executed IAP_Init() and IAP_Main() function , Otherwise, it will jump directly to User Application Program .

/**
 *******************************************************************************
 ** \brief   Check BootPara Marked area data value , Determine if you need to upgrade APP Program .
 **
 ** \param  None
 **
 ** \retval None
 **
 ******************************************************************************/
void IAP_UpdateCheck(void)
{
    uint32_t u32AppFlag;
    
    u32AppFlag = *(__IO uint32_t *)BOOT_PARA_ADDRESS; // read out BootLoader para Zone tag value 
    if (APP_FLAG != u32AppFlag)                       // If the tag value is not equal to APP_FLAG, It means that there is no need to upgrade APP Program 
    {
        IAP_JumpToApp(APP_ADDRESS);                   // Then jump to APP
    }    
}

The first 3 Step :IAP_Init() Implementation of function , It mainly includes peripheral module initialization and IAP Communication protocol flag initialization .

/**
 *******************************************************************************
 ** \brief  IAP  initialization 
 **
 ** \param  [in] None
 **
 ** \retval None
 **
 ******************************************************************************/
void IAP_Init(void)
{
    PreiModule_Init();
    Modem_RamInit();
}

/**
 *******************************************************************************
 ** \brief CPU Peripheral module initialization 
 **
 ** \param [in] None
 **
 ** \retval None
 **
 ******************************************************************************/
void PreiModule_Init(void)
{
    HC32_SetSystemClockToRCH22_12MHz();
    HC32_InitUart();
    HC32_InitCRC();
    HC32_InitTIM();
    HC32_InitFlash(FLASH_CONFIG_FREQ_22_12MHZ);
}

/**
 *******************************************************************************
 ** \brief modem Initialization of related variable parameters in the file 
 **
 ** \param [out] None
 ** \param [in]  None
 **
 ** \retval None
 **
 ******************************************************************************/
void Modem_RamInit(void)
{    
    uint32_t i;
    
    enFrameRecvStatus = FRAME_RECV_IDLE_STATUS;                         // Frame state is initialized to idle state 
    
    for (i=0; i<FRAME_MAX_SIZE; i++)
    {
        u8FrameData[i] = 0;                                             // The frame data cache is initialized to zero 
    }
    
    u32FrameDataIndex = 0;                                              // The framecache array index value is initialized to zero 
}

The first 4 Step :IAP_Main() Implementation of function , It mainly includes to User Application Program update processing .

/**
 *******************************************************************************
 ** \brief  IAP APP Program upgrade main function .
 **
 ** \param  None
 **
 ** \retval None
 **
 ******************************************************************************/
void IAP_Main(void)
{
    en_result_t enRet;

    while (1)
    {
        enRet = Modem_Process();                       //APP Program update processing 
        
        if (Ok == enRet)
        {
            IAP_ResetConfig();                         // Reset all peripheral modules 
            if (Error == IAP_JumpToApp(APP_ADDRESS))   // If the jump fails 
            {
                while(1);
            }
        }
    }
}

/**
 *******************************************************************************
 ** \brief  Host computer data frame analysis and processing 
 **
 ** \param [in] None             
 **
 ** \retval Ok                          APP Program upgrade completed , And receive a jump to APP command 
 ** \retval OperationInProgress          Data processing 
 ** \retval Error                        Communication error 
 **
 ******************************************************************************/
en_result_t Modem_Process(void)
{
    uint8_t  u8Cmd, u8FlashAddrValid, u8Cnt, u8Ret;
    uint16_t u16DataLength, u16PageNum, u16Ret;
    uint32_t u32FlashAddr, u32FlashLength, u32Temp;
    
    if (enFrameRecvStatus == FRAME_RECV_PROC_STATUS)                // There are data frames to be processed , enFrameRecvStatus The value is adjusted in serial port interruption 
    {
        u8Cmd = u8FrameData[PACKET_CMD_INDEX];                      // Get frame instruction code 
        if (PACKET_CMD_TYPE_DATA == u8FrameData[PACKET_TYPE_INDEX]) // If it's a data instruction 
        {
            u8FlashAddrValid = 0u;
            
            u32FlashAddr = u8FrameData[PACKET_ADDRESS_INDEX] +      // Read address value 
                           (u8FrameData[PACKET_ADDRESS_INDEX + 1] << 8)  +
                           (u8FrameData[PACKET_ADDRESS_INDEX + 2] << 16) +
                           (u8FrameData[PACKET_ADDRESS_INDEX + 3] << 24);
            if ((u32FlashAddr >= (FLASH_BASE + BOOT_SIZE)) && (u32FlashAddr < (FLASH_BASE + FLASH_SIZE)))  // If the address value is in a valid range 
            {
                u8FlashAddrValid = 1u;                              // Tag address is valid 
            }
        }
        
        switch (u8Cmd)                                              // According to the instruction code jump execution 
        {
            case  PACKET_CMD_HANDSHAKE    :                         // Handshake frame   Instruction code 
                u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK;   // The return status is : correct 
                Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE);   // Send the response frame to the upper computer 
                break;
            case  PACKET_CMD_ERASE_FLASH  :                         // erase flash  Instruction code 
                if ((u32FlashAddr % FLASH_SECTOR_SIZE) != 0)        // If the erase address is not the top address 
                {
                    u8FlashAddrValid = 0u;                          // Invalid tag address 
                }

                if (1u == u8FlashAddrValid)                         // If the address is valid 
                {
                    u32Temp = u8FrameData[PACKET_DATA_INDEX] +      // Get to be erased flash Size 
                              (u8FrameData[PACKET_DATA_INDEX + 1] << 8)  +
                              (u8FrameData[PACKET_DATA_INDEX + 2] << 16) +
                              (u8FrameData[PACKET_DATA_INDEX + 3] << 24);
                    u16PageNum = FLASH_PageNumber(u32Temp);          // Calculate how many pages to erase 
                    for (u8Cnt=0; u8Cnt<u16PageNum; u8Cnt++)         // Erase the specified number of sectors as needed 
                    {
                        u8Ret = Flash_EraseSector(u32FlashAddr + (u8Cnt * FLASH_SECTOR_SIZE));
                        if (Ok != u8Ret)                             // If erase fails , Feedback host computer error code 
                        {
                            u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_ERROR;
                            break;
                        }
                    }
                    if (Ok == u8Ret)                                 // If all erasures are successful , Feedback host computer success 
                    {
                        u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK;
                    }else                                            // If erase fails , Feedback host computer error timeout sign 
                    {
                        u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_TIMEOUT;
                    }
                }
                else                                                 // Invalid address , Feedback host computer address error 
                {
                    u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_ADDR_ERROR;
                }
                Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE);             // Send the response frame to the upper computer 
                break;
            case  PACKET_CMD_APP_DOWNLOAD :                          // Data download   Instruction code 
                if (1u == u8FlashAddrValid)                          // If the address is valid 
                {
                    u16DataLength = u8FrameData[FRAME_LENGTH_INDEX] + (u8FrameData[FRAME_LENGTH_INDEX + 1] << 8)
                                     - PACKET_INSTRUCT_SEGMENT_SIZE; // Get the data length in the packet ( No instruction code, instruction type, etc )
                    if (u16DataLength > PACKET_DATA_SEGMENT_SIZE)    // If the data length is greater than the maximum length 
                    {
                        u16DataLength = PACKET_DATA_SEGMENT_SIZE;    // Set the maximum data value 
                    }
                    u8Ret = Flash_WriteBytes(u32FlashAddr, (uint8_t *)&u8FrameData[PACKET_DATA_INDEX], u16DataLength); // Write all the data to flash
                    if (Ok != u8Ret)                                 // If you fail to write data        
                    {
                        u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_ERROR;                // Upper computer error feedback   sign 
                    }
                    else                                             // If the data is successfully written 
                    {
                        u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK;                   // Feedback host computer success   sign 
                    }
                }
                else                                                 // If the address is invalid 
                {
                    u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_ADDR_ERROR;               // Feedback host computer address error 
                }
                Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE);             // Send the response frame to the upper computer 
                break;
            case  PACKET_CMD_CRC_FLASH    :                          // Inquire about flash Check value   Instruction code 
                if (1u == u8FlashAddrValid)                          // If the address is valid 
                {
                    u32FlashLength = u8FrameData[PACKET_DATA_INDEX] +                 
                                    (u8FrameData[PACKET_DATA_INDEX + 1] << 8)  +
                                    (u8FrameData[PACKET_DATA_INDEX + 2] << 16) +
                                    (u8FrameData[PACKET_DATA_INDEX + 3] << 24);             // Get to be verified flash size 
                    if ((u32FlashLength + u32FlashAddr) > (FLASH_BASE + FLASH_SIZE))        // If flash The length is beyond the valid range 
                    {
                        u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_FLASH_SIZE_ERROR;     // Upper computer feedback flash Wrong size 
                    }else
                    {
                        u16Ret = Cal_CRC16(((unsigned char *)u32FlashAddr), u32FlashLength);// Read flash Specifies the value of the region and computes crc value 
                        u8FrameData[PACKET_FLASH_CRC_INDEX] = (uint8_t)u16Ret;              // hold crc Values are stored in the reply frame 
                        u8FrameData[PACKET_FLASH_CRC_INDEX+1] = (uint8_t)(u16Ret>>8);
                        u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK;                   // Feedback host computer success   sign 
                    }
                }
                else                                                                        // If the address is invalid 
                {
                    u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_ADDR_ERROR;               // Feedback host computer address error 
                }
                Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE+2);           // Send the response frame to the upper computer 
                break;
            case  PACKET_CMD_JUMP_TO_APP  :                          // Jump to APP  Instruction code 
                Flash_EraseSector(BOOT_PARA_ADDRESS);                // erase BOOT parameter  A sector 
                u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK;    // Feedback host computer success 
                Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE);             // Send the response frame to the upper computer 
                return Ok;                                           //APP Update complete , return OK, Next, execute the jump function , Jump to APP
            case  PACKET_CMD_APP_UPLOAD   :                          // Data upload 
                if (1u == u8FlashAddrValid)                          // If the address is valid 
                {
                    u32Temp = u8FrameData[PACKET_DATA_INDEX] +
                              (u8FrameData[PACKET_DATA_INDEX + 1] << 8)  +
                              (u8FrameData[PACKET_DATA_INDEX + 2] << 16) +
                              (u8FrameData[PACKET_DATA_INDEX + 3] << 24);                   // Read upload data length 
                    if (u32Temp > PACKET_DATA_SEGMENT_SIZE)                                 // If the data length is greater than the maximum 
                    {
                        u32Temp = PACKET_DATA_SEGMENT_SIZE;                                 // Set the data length to the maximum value 
                    }
                    Flash_ReadBytes(u32FlashAddr, (uint8_t *)&u8FrameData[PACKET_DATA_INDEX], u32Temp); // read flash data 
                    u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK;                       // Feedback host computer success   sign 
                    Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE + u32Temp);// Send the response frame to the upper computer 
                }
                else                                                  // If the address is invalid 
                {
                    u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_ADDR_ERROR;               // Feedback host computer address error   sign 
                    Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE);         // Send the response frame to the upper computer 
                }
                break;
            case  PACKET_CMD_START_UPDATE :                           // start-up APP to update ( This command is normally in APP Call in program )
                u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK;     // Feedback host computer success   sign 
                Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE);             // Send the response frame to the upper computer 
                break;
        }
        enFrameRecvStatus = FRAME_RECV_IDLE_STATUS;                   // Frame data processing completed , The frame receiving state returns to the idle state 
    }
    
    return OperationInProgress;                                       // return ,APP Updating ...
}

4.2、User Application Programming

In this example User Application in , Trigger BootLoader The flag of update program is realized in serial port receiving .

//UART0 Interrupt function 
void Uart0_IRQHandler(void)
{
    if(Uart_GetStatus(M0P_UART0, UartRC))         //UART0 Data reception 
    {
        Uart_ClrStatus(M0P_UART0, UartRC);        // Clear interrupt status bit 
        u8RxData[u8RxCnt] = Uart_ReceiveData(M0P_UART0);   // Receive data bytes 
        u8RxCnt++; 
        
        if(u8RxCnt>=18)
        {
            u8RxCnt = 0;
            if ((u8RxData[0]==0x6D)&&(u8RxData[1]==0xAC)&&(u8RxData[6]==0x26)&&(u8RxData[16]==0xA6)&&(u8RxData[17]==0xDA)) // yes APP Update frame 
            {
                for(uint32_t i=0;i<18;i++)
                {
                    Uart_SendDataPoll(M0P_UART0,u8TxData[i]); // Send data by query 
                }
                //boot para Area write tag value , notice BootLoader It's time to update the program 
                Flash_SectorErase(0xF00);
                Flash_WriteWord(0xF00, 0x12345678);
                
		        NVIC_SystemReset();  // Software reset MCU
            }                    
        }
    }
    
    if(Uart_GetStatus(M0P_UART0, UartTC))         //UART0 Data sending 
    {
        Uart_ClrStatus(M0P_UART0, UartTC);        // Clear interrupt status bit 
    }

}

4.3、IAR Address configuration and file output

Finally, we need a brief answer IAR Environmental Science .

The first 1 Step : Determine the output of Linker Configure address , Because you need to modify the address here .

The first 2 Step : find Linker The configuration file , modify BootLoader Program address :0x00000000~0x00000DFF,User Application Program address :0x00001000~0x0000FFFF.

The first 3 Step : find User Application programmatic The configuration file ( The suffix is .s The file of ), Add program Interrupt vector offset length :0x00001000, and BootLoader There are two differences between program configuration files , As shown below :

The first 4 Step : Follow these two procedures ICP The way (SWD、JTAG etc. ) After burning , After that, you can use IAP Through serial port burning HEX File program or BIN Documentation procedure . Output and burn HEX File program or BIN The file program mode is shown in the figure below :

5、 expand : analysis HEX file

HEX Documents can be passed through UltraEdit、Notepad++、 Notepad and other tools open , use Notepad++ After opening, you will see the following data content :

Use Notepad++ After opening, the data with different meanings will have different colors . Each row of data starts with a colon , The following data is provided by : Data length 、 Address 、 identifier 、 Valid data 、 Check data, etc . The first example of the above figure is , To analyze :

The first 1 Bytes 10, Indicates that the line has 0x10 Data , namely 16 Bytes of data ;

The first 2、3 Bytes 3E00, Indicates that the starting address of the line is 0x3E00;

The first 4 Bytes 00, Indicates that the line records data ;

The first 5-20 Bytes , It means valid data ;

The first 21 Bytes EB, Check data that represents the previous data , Verification method :0x100- The sum of the preceding bytes ;

among , The first 4 Bytes have 5 Types :00-05, The meaning is as follows :

Field meaning
00 Indicates that the data is recorded later
01 End of file
02 Represents the extension address
03 Start segment address
04 Represents an extended linear address
05 Indicates the starting linear address

Single chip microcomputer hex Document to 00 Mostly , Are used to represent data .hex The end of the file is shown in the figure below :

On the last line 01 It means the end of the document , final FF It means check data , from 0x100-0x01=0xFF Come to .


Download resources :IAR In the environment STM32+IAP The realization of the plan

版权声明
本文为[Procedural ape without hair loss]所创,转载请带上原文链接,感谢
https://chowdera.com/2020/12/20201206110401611c.html