前言

  这一节和上一节是搭配的

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

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

  这节说明一下制作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":,"SumBin2":,"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":"","status":"-1"} 设备回复 {"data":"switch","bit":"","status":""} 或者 {"data":"switch","bit":"","status":""} 六,控制指令,控制继电器吸合
{"data":"switch","bit":"","status":""} 设备回复 {"data":"switch","bit":"","status":""} 七,控制指令,控制继电器断开
{"data":"switch","bit":"","status":""} 设备回复 {"data":"switch","bit":"","status":""}

准备一个工程

把基础篇的已经实现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[]);//组合发布的主题
#endif
MqttPublishTopicStruct.topicName.cstring = MQTTPublishTopic;//设置发布的主题
MqttPublishTopicStruct.qos = ; //消息等级
MqttPublishTopicStruct.retained = ; //需要服务器保留消息
//连接上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 = ; //后期的数据不需要服务器保留消息
}

加上处理更新协议

  

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

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

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

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

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

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

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

  然后呢 重启就好了

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

  

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

  

  咱上一节BootLoader里面设置的

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

  

  

配置生成第一份程序文件

  

  

  

  

配置生成第二份程序文件

  

  

  

打开计算校验和软件

  

  

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

  

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

  

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

  

  

  

测试放到下一节

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

  1. ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于(Wi-Fi模块AT指令TCP透传方式),MQTT通信控制升级

    实现功能概要 前面的版本都是,定时访问云端的程序版本,如果版本不一致,然后下载最新的升级文件,实现升级. 这一节,在用户程序里面加入MQTT通信,执行用户程序的时候,通过接收MQTT的升级命令实现升级 ...

  2. ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于GPRS模块(Air202,SIM800)AT指令TCP透传方式,MQTT通信控制升级

    实现功能概要 这节和上一节的功能一样(只不过上节是利用Wi-Fi模块,这节是利用GPRS模块) 用户程序里面加入MQTT通信,执行用户程序的时候, 通过接收MQTT的升级命令实现升级. 凡是可以实现M ...

  3. ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于Wi-Fi模块(ESP8266)AT指令TCP透传方式,MQTT通信控制升级(加入数据校验)

    前言 这节演示下,上两节写的利用MQTT来控制STM32控制的程序 测试准备工作(默认访问我的服务器,改为自己的服务器,请看后面说明) 一,下载BootLoader程序(请自行下载) 首先BootLo ...

  4. ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于GPRS模块AT指令TCP透传方式,定时访问升级(含有数据校验)

    实现功能概要 单片机定时使用http访问云端的程序版本,如果版本不一致, 然后通过http下载最新的升级文件,实现远程升级STM32程序. 兼容Air202 ,SIM800 测试准备工作(默认访问我的 ...

  5. ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于(GPRS模块AT指令TCP透传方式),定时访问升级(兼容Air202,SIM800)

    实现功能概要 单片机定时使用http访问云端的程序版本, 如果版本不一致,然后通过http下载最新的升级文件,实现远程升级STM32. 兼容Air202,SIM800 测试准备工作(默认访问我的服务器 ...

  6. ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于WIFI模块AT指令TCP透传方式,定时访问升级(含有数据校验)

    实现功能概要 定时使用http访问云端的程序版本,如果版本不一致,然后通过http下载最新的升级文件,实现升级. 测试准备工作(默认访问我的服务器,改为自己的服务器,请看后面说明) 一,下载BootL ...

  7. ESA2GJK1DH1K升级篇: STM32远程乒乓升级,基于(WIFI模块AT指令TCP透传方式),定时访问升级

    前言 学习此代码所需: 实现功能概要 定时使用http访问云端的程序版本,如果版本不一致,然后通过http下载最新的升级文件,实现升级. 测试准备工作(默认访问我的服务器,改为自己的服务器,请看后面说 ...

  8. ESA2GJK1DH1K升级篇: 移植远程更新程序到STM32F103RET6型号的单片机,基于(GPRS模块AT指令TCP透传方式)

    前言 上节实现远程更新是更新的STM32F103C8T6的单片机 GPRS网络(Air202/SIM800)升级STM32: 测试STM32远程乒乓升级,基于(GPRS模块AT指令TCP透传方式),定 ...

  9. ESA2GJK1DH1K升级篇: STM32远程乒乓升级,升级流程源码详细说明

    前言 1.BootLoader程序,升级简要流程图 2.其实主要的就是把程序文件写入环形队列,然后环形队列取出来数据写入Flash 3.用户程序,简要流程图 下面的读一下,有个印象就可以: 说白了就是 ...

随机推荐

  1. 小程序模板template使用介绍

    template(模板):是可以在wxml中引用的代码,就是在wxml中引用公用的wxml类型的代码,它的作用类似于组件,因此这里简单的说明下template与Component (组件)的区别. t ...

  2. (办公)记事本_Linux常用的目录命令

    参考尚硅谷的谷粒学院:http://www.gulixueyuan.com/course/300/task/7078/show#(免费看,课程很全面,用手机登录一下就行.) .[root@localh ...

  3. 数组类的创建——StaticArray.h

    创建好的基于顺序存储结构的线性表存在两个方面的问题:1)功能上的问题:数组操作符的重载带来的问题,有可能线性表被无用为数组了,线性表被当做数组来使用了.2)效率方面的问题 本篇博客就要解决功能上的问题 ...

  4. 如何解决Sublime text3文件名称中文乱码问题

    在sublime text 3中,Preference, Settings-User,最后加上一行 "dpi_scale": 1.0 { "auto_complete_t ...

  5. 【使用篇二】Quartz自动化配置集成(17)

    出处:https://www.jianshu.com/p/49133c107143 定时任务在企业项目比较常用到,几乎所有的项目都会牵扯该功能模块,定时任务一般会处理指定时间点执行某一些业务逻辑.间隔 ...

  6. Pipe——高性能IO(二)

    Pipelines - .NET中的新IO API指引(一) Pipelines - .NET中的新IO API指引(二) 关于System.IO.Pipelines的一篇说明 System.IO.P ...

  7. IT兄弟连 HTML5教程 CSS3揭秘 CSS3属性4

    7  多列布局属性 通过CSS3,开发人员能够创建多列来对文本进行布局.在CSS2时代,对于多列布局的设计,大多采用浮动布局和绝对定位布局两种方式.浮动布局比较灵活,但是需要编写大量的附加样式代码,而 ...

  8. Unity ugui屏幕适配与世界坐标到ugui屏幕坐标的转换

    我们知道,如今的移动端设备分辨率五花八门,而开发过程中往往只取一种分辨率作为设计参考,例如采用1920*1080分辨率作为参考分辨率. 选定了一种参考分辨率后,美术设计人员就会固定以这样的分辨率来设计 ...

  9. ETCD:与etcd进行交互

    原文地址:Interacting with etcd 与etcd进行交互 用户更多的是通过putting或者是getting从etcd获取一个键对应的值.这一部分描述了如何通过etcdctl做这些工作 ...

  10. MySQL数据以全量和增量方式,同步到ES搜索引擎

    本文源码:GitHub·点这里 || GitEE·点这里 一.配置详解 场景描述:MySQL数据表以全量和增量的方式向ElasticSearch搜索引擎同步. 1.下载内容 elasticsearch ...