赞
踩
在实现且熟悉运用了前面几种远程升级的方法之后,最后项目选择了在小米IoT平台上开发,直接通过米家APP云端升级固件程序~~~
那么本篇文章就主要记录一下我在使用小米IoT平台和米家APP直接实现STM32F103代码更新的过程(此次只更改了WiFi模块,主控不变)。
注册小米账号——>成为平台的开发者——>创建产品(即在小米平台上添加相关硬件),具体可见小米IoT平台简介。
此次采用的WiFi模块是——ESP-WROOM-02D 小米研发的智能模组中的WiFi-Fi单模。(小米智能模组是由小米研发的、为设备提供Wi-Fi或蓝牙连接能力的芯片模组。当前有Wi-Fi单模模组、Wi-Fi蓝牙双模模组、蓝牙单模模组)
ESP-WROOM-02 模组是基于 ESP8266EX 芯片设计开发的物联网无线模组。它集成了 TCP/IP 网络协议栈,32 位低功耗 MCU,10 比特精度 ADC,并带有 HSPI、UART、PWM、I2C 和 I2S 等接口,并且可以在低功耗连接模式下工作。
小米智能模组中的MIIO芯片提供一套可读的串口文本命令,供外部芯片调用,一般适用于MIIO模块不是主控芯片的情况,即 MIIO芯片只负责网络通讯,而不关心业务逻辑。
通过阅读小米IoT 开发平台的——>开发引导 可知发送给WiFi模块的每一条串口命令都要以“\r”为结束标识,并且我们发送的每一条命令WiFi模块都会给我们返回相应的结果或错误提示,具体的串口指令可以看小米IoT平台的开发手册WiFi模组的串口命令手册。
在上述的准备工作做好了之后,进入小米 开发平台 我们能看见已经添加好的硬件,选择 开发 进入小米开发的后台管理,如图一所示。
通过 固件管理 这里就可以上传我们的固件同时配置相关功能函数(关联功能到固件),这里的固件指的是我们的主应用程序,注意和Bootloader区分开来。
这里需要注意的是,上传的固件首先需要 尾部添加CRC 后再上传,可以直接使用小米提供的工具自行添加(甚至可以集成到编译脚本里面)。同时上传的固件版本,版本号要遵循小米平台规定的保持在四位数,我们可以选择从 0001 开始逐个递增,上传成功之后还需要将固件版本设置为 白名单测试 显示状态为测试中,如图二所示,这样作为白名单上开发人员的你才能使用。
在首次升级程序且扩展程序还未开发出来的时候(这里所说的扩展程序是我们将我们的硬件添加到米家APP上之后需要上传的属于我们设备的应用程序,从而来完成对我们的设备功能控制)完成了第二步的上传固件之后,我们通过上图一中的 功能调试 进入在线调试界面,前提是你已经在你的手机上的米家APP中添加了你的设备,并且设备已经连接上了网络,如图三所示,只有连接上了网络的设备才会出现调试字样,否则就会显示为离线状态。
进入调试之后,我们需要测试OTA指令的可行性。即我们在下方的发送指令部分,选择 miio(公共功能) ,选择 milO.ota测试方法,选择相应指令,然后将第二步上传的固件的链接复制到指令中的 mcu_url 处,这里的下载链接直接通过如图二上传好了的固件中的 查看详情 处获取。最后我们发送指令,当收到返回结果为 ok 便表示发送成功。
这时我们通过米家APP的 我的——>设置——>检查更新 便可以看到我们刚上传的相应的固件,点击更新,当显示更新完成即表示我们的固件更新完毕。当完成了相应的软件扩展程序之后我们也可以直接选择在我们自己的扩展程序里更新固件。
在后续的使用中,上传了固件之后一般不用再通过发送 milO.ota 指令来手动向米家APP上传我们的固件,一般在上传完成之后的5~10分钟进入米家APP就能检查出刚上传的新版本。
另外,小米平台提供的这个在线调试功能还可以在我们的扩展程序未开发完成时,下位机直接通过在线调试模拟上位机给我们发送指令,例如我们可以定义好一个开机的自定义功能,然后通过平台调试这里向WiFi模组发送开机指令,WiFi模组收到指令之后再传回给MCU,从而MCU进行相关操作。
当然要完成上述的云端更新固件最重要的还是在于我们的Bootloader的实现上。
小米IoT开发者平台上的MCU OTA协议有将升级的流程和相关注意事项一一列出,从它的使用手册上我们可以知道它用的文件传输协议是Xmodem,所以要实现符合小米平台的Bootloader程序只需要将之前已经实现过的基于Xmodem远程升级的Bootloader程序通信部分改为小米智能WiFi模组通信的操作命令即可。这里我考虑了两种情况。
对于还未有应用程序的板子来说,我采用的方法是,在bootloader中上传WiFi部分的模板号和固件版本号,即相当于初始化WiFi模块(注意:小米WiFi模组在使用前必须通过这两步进行相关初始化)。
串口发送:model xxxxxx\r 收到ok 表示模板号初始化成功
串口发送:mcu_version 0000\r 收到ok 表示固件版本号初始化成功
串口发送:get_down\r 收到down_none / down update_fw / down xxx
串口发送:result "ready"\r 收到ok 调用函数 Xmodem_Receive(CHECK_CRC)
注意:发送给WiFi模块的每一条串口命令都要以\r为结束标识
在WiFi模组初始化完成之后,我通过不停的使用“get_down”命令获取从云端下发的指令(小米平台推荐 get_down 指令循环周期为200ms),在bootloader里面我只对接受到的 update_fw 指令进行了相关应答,即当串口收到 down update_fw,立即向串口回复 result "ready" 。注意云端发送下发的指令只给了我们下位机1S的处理时间,所以在下位机已经做好升级的准备的时候需要立即回复。在上传了result "ready" 之后串口正常情况下会收到返回的ok,收到ok之后我们就可以直接调用之前实现的Xmodem接收函数进行文件接收即可。
在这里实现的Bootloader中,我采取了先将收到的固件程序片段写入Flash的备份区,待文件接收完毕之后再写入预定的应用区,这样可以避免升级过程中,出现中途断电或断网而直接导致应用区程序写入失败。
首先我选用了两个不同的地址作为存储新旧固件版本的地址,在应用程序开始运行时,就将Flash区的新旧固件版本号统一写成当前固件版本号,并且初始化WiFi模组(即向云端发送当前WiF的模板号以及固件版本号)。
然后以200ms为周期循环向云端发送get_down指令,获取到down update_fw指令之后,立即向云端回复result "ready",然后将Flash中的新版本号+1,再重启进入Bootloader程序中。
在Bootloader程序中实现了运行开始就检查Flash中新旧固件版本号是否一致,若不一致,则开启Xmodem接收进行固件升级。
在实际使用的过程中,有可能会出现升级烧写应用程序烧写到部分的情况下就断电,从而导致应用程序烧写损坏。而采用先写入备份区的方法只能解决在断网的情况下烧写应用区程序能够正常进行。
这里我通过仔细反复阅读小米开发者平台上的开发引导中的串口OTA MCU协议找到了小米平台提供的一种,当应用程序烧写失败之后可以通过下位机向云端发起指令update_me来主动请求升级。
但是目前通过我的测试,向云端发起了update_me之后,云端返回的结果是todo,并不是ok/error。同时,云端也并没有在接收到这句指令之后向我发起update_fw指令。
所以,目前我采用的方法是,当应用程序烧写损坏,程序将会跳转到硬故障异常函数中运行(即HardFault_Handler函数),在这个函数里我将Flash中写入的新旧固件版本号都归0且将应用程序区域代码擦除,恢复到没有应用程序的情况,再重新更新固件即可。
本篇博客都是我在实际项目开发中的过程,若是文章中有写错的地方,欢迎各位指出,收到消息核查之后便会及时更改。最后关于update_me这条指令的使用之处可能存在错误的理解,欢迎广大网友指点。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。