STM32 IAP升级固件 + 上位机 例程

本例程实现功能:

1、IAP固件程序实现固件APP搬移,跳转至APP

2、APP固件程序实现自定义功能,接收上位机下发的bin文件

3、上位机加载APPbin文件,分割下发至APP固件程序(本例程使用QT开发)

一、IAP升级简单介绍

基本原理不做赘述,参见:https://blog.csdn.net/wzy15965343032/article/details/88545225

两种方式:

方式1:  IAP固件直接接收上位机下发的程序,将程序写入APP区域,完成后跳转至APP部分。这种方法正点原子有相应的例程;

方式2:

FALSH区域分为4部分:IAP区、APP运行区、APP下载区、参数区域

1、IAP部分检测APP程序是否有更新,有更新需从APP下载区搬运程序至APP运行区,完成后跳转至APP区域;如无更新,直接跳转。

2、APP区域负责运行程序主流程,如是APP升级数据包,则将此包写入APP下载区,同时更新参数区升级标志

3、APP下载区主要存放更新程序

4、参数区域存放升级标志以及其他参数

本例程采用方式二升级

二、固件程序

STM32F103CBT6芯片使用HAL库开发

1、flash区域划分

分区 大小 扇区 地址
IAP 10k 0-9 0x08000000-0x080027FF
APP运行区 58k 10-57 0x08002800-0x08010FFF
APP下载区 58k 58-126 0x08011000-0x0801F7FF
参数区 2k 127-128 0x0801F800-0x0801FFFF

2、IAP程序开发

根据需求,IAP程根据参数区标志位判定是否要升级,只需要完成flash读写即可,为方便调试附带串口打印功能;

跳转APP部分程序一为固定代码,如下程序流程图如下:

STM32 IAP升级固件 + 上位机 例程_第1张图片

程序例程:

//跳转到应用程序段
//ulAddr_App:APP运行区地址.
void IAP_ExecuteApp ( uint32_t ulAddr_App )
{
    pIapFun_TypeDef pJump2App;
    //检查栈顶地址是否合法.
    if ( ( ( * ( __IO uint32_t * ) ulAddr_App ) & 0x2FFE0000 ) == 0x20000000 )    
    {
         pJump2App = ( pIapFun_TypeDef ) * ( __IO uint32_t * ) ( ulAddr_App + 4 );    
         //用户代码区第二个字为程序开始地址(复位地址)        
         MSR_MSP( * ( __IO uint32_t * ) ulAddr_App );
         //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
         pJump2App ();                                                                        
         //跳转到APP.
    }
}       

void IAP_Copy_App(void)
{
    uint8_t i;
    uint8_t buf[2] = {0x96,0x69};
    //擦除App扇区
    Flash_EraseSector(10,67);
    
    for(i = 0;i < 58;i++)
    {
         FLASH_ReadPage(68 + i,FLASH_BUFF);
         HAL_Delay(10);
         FLASH_WritePage(10 + i,FLASH_BUFF);
    }
    
    FLASH_WriteNData(FLASH_APP_UPTADE,buf,2);
}

int main(void)
{

  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */
  /* MCU Configuration----------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */
  /* Configure the system clock */
  SystemClock_Config();
  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART3_UART_Init();
  /* USER CODE BEGIN 2 */
  USER_UART_Init();
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
        HAL_Delay(100);
      printf("IAP start\r\n");    
   while(1){
           uint16_t ret = FLASH_ReadHalfWord(FLASH_APP_UPTADE);
           printf("update = %04x \n",ret);    
       if(ret == UPTADE_FALG)
       {
           printf("Updata App...\r\n");
               IAP_Copy_App();
           printf("Updata App Succeed...\r\n");
       }
       IAP_ExecuteApp(FLASH_APP_START);
     }
  /* USER CODE END 3 */
}

 

3、APP程序开发

APP程序需要:1、flash读写;2、串口接收,发送;3、中断向量表重定义;4、程序重启

程序主流程:串口接收数据包(1024byte)直接写入flash(58扇区开始,往后写),为方便方便理解移植,本demo接收16K文件然后重启。(正式版本可以通过通信协议控制

void IAP_WriteBin(int ii,uint8_t *pBuff,uint32_t Len)
{
    uint8_t buf[2] = {0xAA,0x55};
    //擦除DOWNLOAD扇区
    Flash_EraseSector(68+ii,68+ii+1);
    //写入程序
    FLASH_WritePage(68+ ii,pBuff);
    if (ii > 15){
          //更新标记
          FLASH_WriteNData(FLASH_APP_UPTADE,buf,2);
          //复位单片机
         NVIC_SystemReset();
     }
}


void cmdProcess()
{
    if(g_rx232_end_flag == 1)
    {        
        IAP_WriteBin(current,g_rx232_buffer,g_rx232_len);
              current ++;
                HAL_Delay(10);
              memset(g_rx232_buffer,0,g_rx232_len);/*清接收缓存 */
              g_rx232_len=0;                       /*清除计数 */
        g_rx232_end_flag=0;                  /*清除接收结束标志位*/
        HAL_UART_Receive_DMA(&huart3,g_rx232_buffer,BUFFER_SIZE);/*重新打开DMA接收*/
    }
    
        if(g_rx485_len)
    {        
              IAP_WriteBin(current,g_rx232_buffer,g_rx232_len);
              current ++;
               HAL_Delay(10);
               memset(g_rx485_buffer,0,g_rx485_len);/*清接收缓存 */
              HAL_UART_Receive_DMA(&huart1,g_rx485_buffer,BUFFER_SIZE);
              g_rx485_len = 0;
    }
}

三、上位机程序

使用QT进行开发

1、加载BIN文件

2、串口操作

3、程序分割下载(1024字节bin文件数据包)

void MainWindow::on_pushButton_loadfile_clicked()
{            
       QString fileName=QFileDialog::getOpenFileName(this,QString::fromLocal8Bit("bin file"),qApp->applicationDirPath(),

    QString::fromLocal8Bit("bin File(*.bin)"));//新建文件打开窗口
     if (fileName.isEmpty())//如果未选择文件便确认,即返回
    return;

     QFile file(fileName);
     if(!file.open(QIODevice::ReadOnly)
     ui->label_filepath->setText(file.errorString());//文件打开错误显示错误信息
     arry=file.readAll();//读取文件
     ui->label_filepath->setText(fileName);
     ui->textEdit_3->append(arry.toHex());
     qDebug()<write(partbuff,1024);

         delay_MSec(3000);

         //升级判定返回

         ui->progressBar->setValue(0);

         j = j + 1024;

         string = "\n" + QString::number(i) + "\n" +partbuff.toHex() +ui->textEdit_4->toPlainText();

         ui->textEdit_4->clear();

         ui->textEdit_4->setText(string);

         delay_MSec(100);

     }

 }

STM32 IAP升级固件 + 上位机 例程_第2张图片

本例程源码:

 

你可能感兴趣的:(STM32,stm32,iap,qt,flash)