IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 涂鸦WIFI模组WBR3之OTA升级 -> 正文阅读

[嵌入式]涂鸦WIFI模组WBR3之OTA升级

一、涂鸦平台

? ? ? ? 涂鸦平台上传固件版本,并设置OTA升级,点击验证升级选中产品的ID号才能下发固件。

二、程序运行流程(本文MCU为STM32F4,flash采用1M)

? ? ? ? 1.程序运行流程参考下图:

? ? ? ?

? ? ? ?程序分区如下:

???????? bootloader:0~0x8020000? ? ?????????????????128KB

? ? ? ? ?app1? ? ? ? :0x8020000~0x8080000? ? ? ? ? 384KB?

? ? ? ? ?app2? ? ? ? :0x8080000~0x80E0000? ? ? ? ? 384KB

? ? ? ? ?FLAG? ? ? ?:0x80E0000~0x8100000? ? ? ? ? 128KB

? ? ? ? 以上偏移地址分区是根据扇区来分的,FLAG是做为标记判断是否需要升级,执行逻辑就是首先接收OTA数据包,存到app2地址中,接收完OTA固件包之后把FLAG标记,然后软件复位,程序就会跳转到bootloader中,bootloader通过判断FLAG决定是否要升级,最后跳转到APP1中。

三、APP部分

? ? ? ? OTA升级部分代码处理如下:

unsigned char mcu_firm_update_handle(const unsigned char value[],unsigned long position,unsigned short length)
{
    u32 nbuff=0x55555555;
    u16 t;
    u16 i=0;
    u16 value_cnt=0;
    u32 temp;
    if(length == 0) //固件数据发送完成    
    {         
        STMFLASH_Write(Upgrade_FlashADDR_Flag,&nbuff,1);
        if(STMFLASH_ReadWord(Upgrade_FlashADDR_Flag) == 0x55555555)
        {
            HAL_GPIO_WritePin(GPIOD, GPIO_PIN_9, GPIO_PIN_RESET);
        }
        NVIC_SystemReset();
    }
    else 
    {        
        for(t=0;t<length;t+=4)
        {
           temp=(u32)value [value_cnt+3]<<24;
            temp|=(u32)value[value_cnt+2]<<16;
            temp|=(u32)value[value_cnt+1]<<8;
            temp|=(u32)value[value_cnt];
            value_cnt+=4;
            iapbuf[i++]=temp;
            if(i==64)
            {                                           
                STMFLASH_Write(fwaddr,iapbuf,64); 
                memset(iapbuf,0,64);
                fwaddr+=256;
                i=0;
                value_cnt=0;
            }
      }
      if((i>0) && (i<64))STMFLASH_Write(fwaddr,iapbuf,i);
    }    
    return tuya_SUCCESS;
}

传参:value-接收的固件包数据,传入的是一个指针,指向串口接收数组wifi_data_process_buf

? ? ? ? ? ?position-第几个数据包

? ? ? ? ? ?length-当前固件包长度(固件包长度为0时,表示固件包发送完成)

固件包是一包一包传输的,每包数据256字节,把接收到的数据包写到app2中,接收完毕数据FLAG做一个标记。写数据时,先擦除才能写,STM32F4的最小到位是扇区,要按扇区擦除,最好是先擦除整个扇区再一个字节一个字节的写数据。部分代码参考如下:(修改的STM32F4库函数)

if((addrx==0x8080000) || (addrx==0x80A0000) || (addrx==0x80C0000) || (addrx==0x80E0000))//每个扇区的首地址
	{
		while(addrx<0x80F0000)		//擦除的地址范围
		{
			if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//有非0XFFFFFFFF的地方,要擦除这个扇区 STMFLASH_ReadWord(addrx)!=0XFFFFFFFF
			{   
				FlashEraseInit.TypeErase=FLASH_TYPEERASE_SECTORS;       //擦除类型,扇区擦除 
				FlashEraseInit.Sector=STMFLASH_GetFlashSector(addrx);   //要擦除的扇区
				FlashEraseInit.NbSectors=1;
                FlashEraseInit.VoltageRange=FLASH_VOLTAGE_RANGE_3;      //电压范围,VCC=2.7~3.6V之间!!
				if(HAL_FLASHEx_Erase(&FlashEraseInit,&SectorError)!=HAL_OK) 
				{
					break;//发生错误了	
				}
			}
            else addrx+=4;
			FLASH_WaitForLastOperation(FLASH_WAITETIME);                //等待上次操作完成
        }
	}                         

OTA固件数据包接收完毕,软件复位跳转到bootloader中。

四、bootloader部分

? ? ? ? bootloader代码处理如下:

void iap_main(void)
{
    u32 nbuff=0xAAAAAAAA;
    
    STMFLASH_Read(Upgrade_FlashADDR_Flag,&read_addr,1);
    if(read_addr == 0x55555555)
    {
        Updata_Firmware(APP1_START_ADDR,APP2_START_ADDR);//固件升级操作
        STMFLASH_Write(Upgrade_FlashADDR_Flag,&nbuff,1);
        NVIC_SystemReset();
    }
    else
    {
        iap_load_app(0x8020000);
    }
}

检测到FLAG位ox55555555时,进入升级操作,把app2的代码复制给app1,然后把改变FLAG,软件复位,再次执行程序就会直接跳转到新接手的固件app1中。

固件升级操作代码如下:

void Updata_Firmware(u32 SourceAddress,u32 TargetAddress)
{
    u16 i=0;
    u32 buffer[64];//1kb
    volatile u32 nk;
    nk = (TargetAddress-SourceAddress-0x20000)/(256);        //计算有几个扇区数据0x40000/256=1024
    for(i=0;i<nk;i++)
    {
        memset(buffer,0,sizeof(buffer)); 
        STMFLASH_Read(TargetAddress+i*256,buffer,64);    //256/4 传入num为32位数据
        STMFLASH_Write(SourceAddress+i*256,buffer,64);   //
    }
}

把app2的代码复制给app1是按固件包读取,读取一个固件包,写一个固件包,注意读写时的位操作,位操作搞错了,会出现奇怪问题。

五、结论

? ? ? ? OTA升级的本质就是IAP,所以,按照IAP升级的方式来做就可以,可以参考原子的IAP例程中的iap_write_appbin(FLASH_APP1_ADDR,USART_RX_BUF,applenth);//更新FLASH代码。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-18 12:52:01  更:2021-08-18 12:52:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 20:35:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码