zoukankan      html  css  js  c++  java
  • ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于Wi-Fi模块AT指令TCP透传方式,MQTT通信控制升级-APP用户程序制作过程

    前言

      这一节和上一节是搭配的

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

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

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

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

    协议

      

    注:所有的实现MQTT的软件,统称为MQTT上位机
    
    一,MQTT上位机通过MQTT发送获取设备信息指令(用户在APP上点击检查更新时发送此命令)
    {"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字节

    APP检测版本不一致时

    把后面的 "details":"1,优化了部分BUG;2,测试升级;3,支持升级STM32程序;4,修改XXXBUG" 提示给用户
    用户点击更新的时候接着往下看
    三,发送以下指令
    {
    "data":"updata","cmd":"start"} 注:测试时可直接发送此指令

    //设备接收到回复 {"data":"updata","status":"start"}
    然后进入BootLoader程序执行升级去了 为了让APP知道升级的状态 四,设备在执行用户程序连接上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"}

    准备一个工程

    把基础篇的已经实现MQTT通信的工程拷贝过来

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

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

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

      

     注:受内存影响,去掉了OLED部分

    主函数配置

      1.包含下头文件

        

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

        

    处理更新

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

      IAPUpdateDispose();

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

      

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

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

        

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

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

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

      然后运行新的用户程序

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

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

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

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

      

      然后总的来说就一句话:

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

     

    这节建议这样处理

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

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

      

      

    /**
    * @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   设置的可以满足

      

      

    配置生成第一份程序文件

      

      

      

       

    配置生成第二份程序文件

      

      

      

    打开计算校验和软件

      

      

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

      

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

      

     

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

      

      

      

    测试放到下一节

  • 相关阅读:
    linux ---性能监控(工具)
    inux --- 服务器性能监控
    Jmeter——BeanShell PreProcessor的用法
    Jmete ----r默认报告优化
    jmeter --- 基于InfluxDB&Grafana的JMeter实时性能测试数据的监控和展示
    转Jmeter报告优化之New XSL stylesheet
    Jmeter----组件执行顺序与作用域
    Jmeter----属性和变量
    Jmeter----逻辑控制器(Logic Controller)
    Jmeter----HTTP Request Defaults
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/12075412.html
Copyright © 2011-2022 走看看