zoukankan      html  css  js  c++  java
  • STM32 IAP 升级功能

    IAP
    In Application Programming
    可通过USB,CAN,UART,I2C,SPI等接口实现

    IAP流程
    Bootloader程序:接收升级程序,更新到flash指定地址;跳转到指定地址执行
    1
    STM32设置
    ①:为Bootloader预留0x10000空间
    ②:设置APP程序的起始地址
    2
    ③:中断向量表的偏移量设置
    2
    ④:生成bin文件
    详见:https://blog.csdn.net/zhangxuechao
    ⑤:代码更新FLASH固件,执行FLASH代码

    举例

    //appxaddr:应用程序的起始地址
    //appbuf:应用程序CODE.
    //appsize:应用程序大小(字节).
    void iap_write_appbin(u32 appxaddr, u8 *appbuf, u32 appsize)
    {
       u32 t;
       u16 i = 0;
       u32 temp;
       u32 fwaddr = appxaddr; //当前写入的地址
       u8 *dfu = appbuf;
    
       for(t = 0; t < appsize; t += 4)
       {
          temp = (u32)dfu[3] << 24;
          temp |= (u32)dfu[2] << 16;
          temp |= (u32)dfu[1] << 8;
          temp |= (u32)dfu[0];
          dfu += 4; //偏移4个字节
          iapbuf[i++] = temp;
    
          if(i == 512)
          {
             i = 0;
             STMFLASH_Write(fwaddr, iapbuf, 512);
             fwaddr += 2048; //偏移2048  512*4=2048
          }
       }
    
       if(i)
       {
          STMFLASH_Write(fwaddr, iapbuf, i);   //将最后的一些内容字节写进去.
       }
    }
    
    //跳转到应用程序段
    //appxaddr:用户代码起始地址.
    void iap_load_app(u32 appxaddr)
    {
       if(((*(vu32 *)appxaddr) & 0x2FFE0000) == 0x20000000)	//检查栈顶地址是否合法.
       {
          jump2app = (iapfun) * (vu32 *)(appxaddr + 4);		//用户代码区第二个字为程序开始地址(复位地址)
          MSR_MSP(*(vu32 *)appxaddr);					//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
          jump2app();									//跳转到APP.
       }
       else
       {
          printf("iap_load_app error 0x%x
    ", *(vu32 *)appxaddr);
       }
    }
    
    //执行FLASH代码
    void iap_load_flash(void)
    {
       if((*(vu32 *)(FLASH_APP_ADDR + 4) & 0xFF000000) == 0x08000000) //判断是否为0X08XXXXXX.
       {
          iap_load_app(FLASH_APP_ADDR);//执行FLASH APP代码
       }
       else
       {
          printf("iap_load_flash error 0x%x
    ", *(vu32 *)FLASH_APP_ADDR);
       }
    }
    
    //更新FLASH固件
    void update_flash(u8 *appbuf, u32 appsize)
    {
       if(appbuf == NULL)
       {
          return;
       }
    
       if((*(vu32 *)(appbuf + 4) & 0xFF000000) == 0x08000000) //判断是否为0X08XXXXXX.
       {
          iap_write_appbin(FLASH_APP_ADDR, appbuf, appsize); //更新FLASH代码
          printf("固件更新完成!
    ");
       }
       else
       {
          printf("update_flash error 0x%x
    ", *(vu32 *)appbuf);
       }
    }
    
  • 相关阅读:
    VS2008 Ajax Toolkit 控件(修正后转载)
    AD操作类[修改版]
    java中使用Rhino执行js文件中的function
    XSTL中单引号的问题
    [转]ADSearch User Property Attributes
    2008我的健身计划
    spring执行定时任务
    分页存储过程,支持多表查询,效率还行
    今天写一个读卡器程序,操作AD时的一个Exception:The authentication mechanism is unknown
    httpclient模拟windows认证
  • 原文地址:https://www.cnblogs.com/zhangxuechao/p/11709283.html
Copyright © 2011-2022 走看看