前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于Wi-Fi模块AT指令TCP透传方式,MQTT通信控制升级(含有数据校验)-APP用户程序制作过程

ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于Wi-Fi模块AT指令TCP透传方式,MQTT通信控制升级(含有数据校验)-APP用户程序制作过程

作者头像
杨奉武
发布2019-12-24 14:29:49
4820
发布2019-12-24 14:29:49
举报
文章被收录于专栏:知识分享

前言

  这一节和上一节是搭配的

  给大家鱼,也必须给鱼竿!

  我期望自己封装的代码,无论过了多少年都有应用的价值!

  这节说明一下制作APP用户程序的过程

  咱是用MQTT通信控制模块实现升级,所以首先自己的程序先实现MQTT哈.

协议

代码语言:javascript
复制
注:所有的实现MQTT的软件,统称为MQTT上位机

一,MQTT上位机通过MQTT发送获取设备信息指令
{"data":"updata","cmd":"DeviceInfo"}

//设备接收到回复
{"data":"updata","model":"STM32_MQTT_AT8266_SUM","version":"1.0.2"}//假设现在的型号是 STM32_MQTT_AT8266_SUM,当前设备硬件版本是1.0.2


二,MQTT上位机根据型号使用http访问云端存放的记录更新信息的文件
                                                          "型号"
列如:上位机使用http访问  http://47.92.31.46/hardware/STM32_MQTT_AT8266_SUM/updatainfo.txt

假设updatainfo.txt文件信息是:
{"version":"1.0.45611","SumBin1":219,"SumBin2":103,"details":"1,优化了部分BUG;2,测试升级;3,支持升级STM32程序;4,修改XXXBUG"}

注:版本号最大设置为20字节
后面的  "details":"1,优化了部分BUG;2,测试升级;3,支持升级STM32程序;4,修改XXXBUG"  MQTT上位机可作为升级提示信息,提示给用户



三,MQTT上位机对比版本号,如果不一致,则发送以下指令     
{"data":"updata","cmd":"start"}  注:测试时可直接发送此指令


//设备接收到回复
{"data":"updata","status":"start"}
然后进入BootLoader程序执行升级去了


四,设备连接上MQTT发送的第一条消息为
"{\"data\":\"status\",\"status\":\"online\",\"UpdataStatus\":\"UpdataSuccess\",\"version\":\"1.0.45611\"}"


UpdateStatus_None                  //没有更新
UpdateStatus_DataAddressError      //Flash的高位地址不是0x08 或者 RAM的高位地址不是0x20
UpdateStatus_DataOverflow          //数据接收溢出
UpdateStatus_DownloadTimeout       //程序下载超时
UpdateStatus_MainTimeout           //整个程序运行的时间
UpdateStatus_FlashWriteErr         //Flash 写错误
UpdateStatus_VersionLenErr         //版本号长度错误
UpdateStatus_VersionAlike          //版本号和服务器上面的一致
UpdateStatus_FlashEraseErr         //Flash 擦除失败
UpdateStatus_MissingData           //数据接收不完整
UpdateStatus_SumBinRangeErr        //校验和范围错误(获取的云端的校验和,不在0-255之间)
UpdateStatus_SumCheckErr           //校验和不一致
UpdateStatus_RunAppError           //上次更新的程序没有运行起来



----------------------------------------------------------------
控制指令,查询继电器状态
{"data":"switch","bit":"1","status":"-1"}

设备回复  {"data":"switch","bit":"1","status":"1"}  或者  {"data":"switch","bit":"1","status":"0"}


六,控制指令,控制继电器吸合
{"data":"switch","bit":"1","status":"1"}  设备回复 {"data":"switch","bit":"1","status":"1"}



七,控制指令,控制继电器断开
{"data":"switch","bit":"1","status":"0"}  设备回复 {"data":"switch","bit":"1","status":"0"}

把以下文件放到自己的工程

  stmflash文件直接拷贝的上一节的

  IAP和上一节的不一样,做了很多裁剪.

主函数配置

  1.包含下头文件

  2.调用一个函数  IAPGetUpdateInfo();//获取更新的信息

  这个函数做的工作

    获取云端版本: 这个是在BootLoader里面升级的时候存进去的

    获取设备版本: 当前这个版本还是以前的程序版本,还没切换呢,后面会说在哪里切换的

    获取更新状态: BootLoader里面设置的那些更新状态

  大家可以在用户程序里面 通过 IAPStructValue.UpdateStatusValue的值来知道上次更新的状态

  为了更直观,大家直接可以调用  printf("%s",IAPStructValue.UpdateStatusStr); 打印对应的字符串

  也可以在认为程序没有问题的时候,把这些状态发给上位机,这样就直观的知道更新的状态

处理更新(为什么会有处理更新)

  先说一下哈,处理更新是这个函数

  IAPUpdateDispose();

这个函数主要就是清零更新状态,然后如果判断运行的是新程序,则切换程序版本.

   然后说一下上面函数的妙处

  如果在BootLoader里面程序文件下载成功

  BootLoader下载好程序以后呢,写入状态为:0x01 然后重启了

  重启以后当然还是先运行 BootLoader

  然后 BootLoader 判断是0x01以后 写入 0xFF

  然后运行新的用户程序

  假设用户程序有问题 没有执行函数  IAPUpdateDispose();

  那么就没有把升级状态清零

  那么单片机重启以后又运行 BootLoader,此时BootLoader里面一判断还是0xFF

  便会认为没有正确执行用户程序,就会切换上一份用户程序执行

  然后总的来说就一句话:

  你认为APP用户程序运行没有问题了以后再调用 IAPUpdateDispose();

这节建议这样处理

  在连接上MQTT以后,咱调用下 IAPUpdateDispose();

  然后把升级状态通过MQTT发出去

代码语言:javascript
复制
/**
* @brief  连接上MQTT以后发送一条上线指令
* @param  
* @param  
* @retval 
* @example 
**/
void FunctionSendOnline(void)
{
    IAPUpdateDispose();
    
    //如果不使用自定义的配置
    #ifndef UserCustomConfig //device/Wi-Fi的MAC
        memset(MQTTPublishTopic,NULL,sizeof(MQTTPublishTopic));
        sprintf(MQTTPublishTopic,"%s%s","device/",&MQTTid[0]);//组合发布的主题
    #endif
    MqttPublishTopicStruct.topicName.cstring = MQTTPublishTopic;//设置发布的主题
    MqttPublishTopicStruct.qos = 1;      //消息等级
    MqttPublishTopicStruct.retained = 1; //需要服务器保留消息
    //连接上MQTT以后发送一条上线信息,携带着更新状态,当前设备版本    
    MainLen= sprintf(MainBuffer,"{\"data\":\"status\",\"status\":\"online\",\"UpdataStatus\":\"%s\",\"version\":\"%s\"}",
    IAPStructValue.UpdateStatusStr,//更新的状态
    IAPStructValue.VersionDevice   //当前设备版本
    );//组合发送的数据     
    MainLen = MqttPublish(MqttPublishTopicStruct,MainBuffer,MainLen);//打包MQTT数据
    UsartOutStr(MqttSendData,MainLen);//发送MQTT协议数据
    MqttPublishTopicStruct.retained = 0; //后期的数据不需要服务器保留消息
}

加上处理更新协议

  如果通过MQTT接收到获取设备信息指令

  就返回设备信息(型号,和当前版本号)

  MQTT上位机根据型号,http访问对应的 updatainfo.txt

  然后对比下版本号,如果不一致,就提示给用户有新版本

  然后用户点击升级的时候 再发给模块 开始更新的指令

  模块收到以后设置更新标志

  返回给MQTT 我要升级了   "{\"data\":\"updata\",\"status\":\"start\"}"    嘻嘻嘻

  然后呢 重启就好了

  因为有了升级标志,BootLoader里面就去执行升级去了

先查看一下用户程序的bin文件大小

  咱上一节BootLoader里面设置的

  0x5C00  = 23KB   设置的可以满足

配置生成第一份程序文件

配置生成第二份程序文件

打开计算校验和软件

计算第一份程序文件的校验和

计算第二份程序文件的校验和

把相应的文件放到云服务器

测试放到下一节

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-12-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 协议
  • 把以下文件放到自己的工程
  • 主函数配置
  • 处理更新(为什么会有处理更新)
  • 这节建议这样处理
  • 加上处理更新协议
  • 先查看一下用户程序的bin文件大小
  • 配置生成第一份程序文件
  • 配置生成第二份程序文件
  • 打开计算校验和软件
  • 计算第一份程序文件的校验和
  • 计算第二份程序文件的校验和
  • 把相应的文件放到云服务器
  • 测试放到下一节
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档