从IAP升级到涂鸦OTA升级介绍 (下)

仅作为个人学习笔记使用

下篇

OTA--Over-the-Air 即空中下载技术,通过远程网络为设备更新或者升级 

Wifi通用串口协议支持MCU OTA功能。通过使用涂鸦iot平台,需要将更新好的固件上传至涂鸦服务器上,Wifi模组通过涂鸦协议对文件进行分包传输,最后MCU接收升级包并写入FLASH中,至此完成整个OTA升级过程

一、升级流程及协议

升级流程如下图

1) OTA启动后,模组首先发送0A指令(启动升级指令)告诉MCU升级包的大小,MCU需要返回固件分包的大小

2) 此后模组通过发送0B指令(升级包传出指令)按包传输固件给MCU,MCU需要在5S内予以回复,若未予以回复 在连续发送三次后显示升级失败

3) 模组发送完最后一包数据后,会发送01指令(查询产品信息指令) MCU需要在1min内回复升级后的版本号,如果上报的版本号与云端之前设定的版本号一致则表明升级成功

详细串口协议请参考WIFI协议MCU升级

二、SDK部分解析

在这里就不做过多的SDK移植方面的介绍 直奔主题

在上一篇文章从IAP升级到涂鸦OTA升级介绍(上)中我们主要介绍IAP升级的原理和具体实现,采用的方式是直接将队列接收的数据直接写入FLASH指定位置中 再通过BootLoader程序引导进入APP中 从而完成程序更新。而在这里采用wifi模组通过涂鸦协议对文件进行分包下发传输,此时需要分包接收 为了分包接收的数据的准确性需要去检测校验位或者标志位。整个OTA升级思路如下

代码部分分为BootLoader、APP、OTA三个代码区域。使用BootLoader引导代码,通过识别标志位来判断是直接跳转到APP还是OTA数据。在APP中,如果收到OTA升级数据,将存储到FLASH的OTA区域中 并将在接收完整个OTA数据后 将OTA升级标志位置1,此后重启MCU。重启MCU后,由BootLoader将OTA部分搬运到FLASH的APP中,搬运完后跳转到APP中执行。至此整个OTA升级过程结束

1)首先要在protocol.h中 更改对应pid和要升级的版本信息

2)打开SUPPORT_MCU_FIRM_UPDATE这个宏定义 开启固件升级,其次选择传输包的大小

3)对串口接受缓存进行修改 根据实际固件大小来决定

这里建议使用环形队列的方式接收处理数据,具体好处在上一篇中有提到

4)在protocol.c中完成固件升级代码,将接收到的升级包依次写入MCU FLASH

OTA升级部分

前面说到了平台通过协议将升级包分包发送进行升级,那传输过成中校验数据的准确定性是重中之重。OTA升级包每包都由固定大小数据组成,需要根据每包数据偏移量 将数据包按FLAS页的大小进行组合,并写入FLASH 直到最后一包数据完成。此后将OTA升级标志位置1 并对MCU进行重启

这里Tuya SDK已将协议解析部分写好了,主要完成mcu_firm_update函数功能

unsigned char mcu_firm_update_handle(const unsigned char value[],unsigned long position,unsigned short length)
{
//  #error "请自行完成MCU固件升级代码,完成后请删除该行"
  unsigned long addr;
 
  if(length == 0)
  {
#ifdef ENABLE_BOOT
    //固件数据发送完成
    FlashBuffer.magic_code = FIREWARE_UPDATE_FLAG;
    
    if(Earse_Flash(PARA_ADDR) == ERROR)
      return ERROR;
    
    //写入升级标志
    if(Write_Flash(PARA_ADDR,(unsigned char *)&FlashBuffer,sizeof(FlashBuffer)) == ERROR)
      return ERROR;
    
    Reset();
#endif
  }
  else
  {
    //固件数据处理
    addr = FIREWARE_ADDR_H;
     
    if(position % 1024 == 0)
    {
      if(Earse_Flash(addr + position) == ERROR)
        return ERROR;
    }
    
    if(Write_Flash(addr + position,(unsigned char *)value,length) == ERROR)
      return ERROR;
  }

  return SUCCESS;
}

BootLoader部分

程序启动后 先判断OTA升级标志位是否置1,如果没有 那么将跳转到APP中执行;如果有 将OTA部分代码搬运到APP中,搬运结束后 清除OTA升级标志位 最后跳转到APP中

void main (void)
{
  /*
  //解锁(必须运行在RAM状态下)
  FLASH_Unlock();
  FLASH_ReadOutProtection(DISABLE); 
  */
  uint32_t magic_code;
  uint32_t app_address;
  
  RCC_Configuration();
  
  NVIC_Configuration();
  
  //
  Read_Flash((unsigned char *)&magic_code,PARA_ADDR,4);
    
  if(magic_code == FIREWARE_UPDATE_FLAG)
  {
    if(update_firmware() != SUCCESS)
    {
      Reset();
    }
  }  
  
  //判断程序是否存在
  app_address = FIREWARE_ADDR_L;

  if(Exist_MainProgram((uint32_t *)app_address) == 1)
  {
    JumpToApp(app_address); 
  }

  while(1)
  {

  }
}

这里最后提示一下:1)接收 OTA 数据包的时候,要对包偏移进行检测,防止串口通信异常导致重发和漏发

2)MCU 建议加上 OTA 数据接收超时检测,以免模块或网络异常导致 OTA 失败时,MCU 无法退出,不能重新进行 OTA

这样软件部分就完成了,开始在平台上上传固件吧

三、Tuya IOT平台使用

请参考链接平台配置

四、升级失败的原因分析

以MCU升级到1.0.2为例,成功升级后在涂鸦智能APP面板上显示如图

正常流程下的后台日志信息如图,MCU升级 通道9 当前版本1.0.0 目标版本1.0.2

当然 在出现升级超时时别慌!稳住!先学会自查 打开后台日志输入你的设备id

1)先检查升级的通道号是否正确 以常用的为例:MCU升级->通道9;固件升级->通道0

2)检查要升级的版本是否正确

3)设备网络问题 可以更换一个网络环境下重新进行

4)在涂鸦调试助手上 根据通信协议对升级过程中交互数据进行分析

5)如果MCU OTA到98% 那也不一定是失败。看一下是不是后面有模组的重启日志 大多模组供电由MCU 控制,当MCU OTA时 最后会重启,重启阶段模组无法得到正常工作,后续版本号上报的流程终止。看最后是不是版本号正常更新了就可以了

具体的还是得监控一下MCU OTA流程

6)设备上报的固件key与配置的升级固件key不一致导致

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值