打印
[应用相关]

【转】STM32F769DK 云端固件升级例程使用说明

[复制链接]
605|28
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
1.前言
对于一个物联网应用,远程监控设备状态、 远程更新设备固件都是其要包含的典型基本功能。 本示例在百度天工 IoT 平台和
STM32F769 探索板上实现了上述功能, 并有以下特性:
 支持 MQTT, HTTP 协议
 支持安全传输( TLS) 支持应用数据的 Json 格式解析
 后台下载固件(不影响前台应用程序运行)
 断点续传
 固件完整性检查
支持一键恢复出厂默认固件在本示例中, STM32F769DK 板可以通过板载以太网接口或者外接的 WIFI 模块连接到百度天工
IoT 平台, 与其建立 MQTT 连接: 将板上的 LED 灯状态、 软件版本等信息上传到云端, 并可接收云端下发的 LED 控制命令、
新固件版本和下载地址。根据接收到新固件下载地址,通过 HTTP 协议从对应的服务器下载新固件。 下载完成后程序通过
LCD 屏向用户提示可用的新版本信息, 用户可以通过用户按键启动新固件的升级。下载和升级过程支持固件完整性校验。
在此例程中, 我们用到了百度 IoT 平台和对象存储(BOS)服务。首先需要在 IoT 平台上创建 MQTT 服务,百度 IoT 平台相当于
MQTT 服务器, STM32F769DK 板相当 MQTT 客户端。 在本示例中, 还用到了一个 PC 端工具 MQTT.fx, 作为另一个 MQTT
客户端来向 STM32F769DK 板推送固件升级消息, 接收 STM32F769DK 板发送到云端的消息并进行显示。
远程下载的固件需要保存在百度云 BOS 服务器上, 然后就可以获取到对应的下载链接。 这个下载地址信息,通过 PC 上的
MQTT 客户端 MQTT.fx 进行推送, STM32F769DK 板收到消息后, 从百度的 BOS 服务器下载新固件。
本例程提供了 IAR 的工程 。

使用特权

评论回复
沙发
我想看大海|  楼主 | 2022-5-5 14:00 | 只看该作者
2.系统框图  

使用特权

评论回复
板凳
我想看大海|  楼主 | 2022-5-5 14:01 | 只看该作者
3.存储区域划分
本示例用外部 QSPI Flash 保存从云端接收到的新固件和程序运行的状态。 QSPI Flash 的功能区域划分如下:
地址 0 开始的 64K 字节: Info 区域, 用来保存程序运行的状态以及接收到的固件下载地址和版本号等。
地址 0x00010000 开始的 4M 字节: Default Firmware 区域,用来保存默认的应用程序固件。 通常可以将第一版稳定
的应用程序,烧写到
Default 区域中, 用作“ 恢复板子出厂设置” 。
地址 0x00410000 开始的 4M 字节: Download Firmware 区域, 用来保存在 OTA 过程中从云端下载的当前新固件。
STM32F769 MCU 的内部 Flash 分为两部分:
地址 0x08000000 开始是 Bootloader 程序: 板子复位后,先执行的是 Bootloader 的程序, 之后再跳转到应用程序。
bootloader 程序会根据用户操作决定是否将 QSPI Flash 中的固件更新到 MCU 内部 Flash 中。
地址 0x08010000 开始,保存用户应用程序: 它除了用户自己的功能程序之外,还包括与云端通信,以及从云端下
载新固件的程序。
  

使用特权

评论回复
地板
我想看大海|  楼主 | 2022-5-5 14:02 | 只看该作者
4.运行环境
4.1 硬件连接部分
需要的硬件:
一块 STM32F769I-DISCO 开发板, 一根 micro USB 线
使用以太网有线连接时: 一根网线, 一个可以连上互联网的网口
使用 wifi 无线连接时: 一个 WIFI 热点, 一个 ESP-01 模块
一台可以上网的电脑( 运行 MQTT.fx
硬件连接:
  


使用特权

评论回复
5
我想看大海|  楼主 | 2022-5-5 14:02 | 只看该作者
4.2 需要的固件、工具软件及云端服务:
 STM32F769 云端固件升级的软件包(包括 Bootloader 程序项目工程和应用程序项目工程)
 IAR Embedded Workbench for ARM
 ST-Link Utility(烧写 STM32F769I-DISCO 板子上的 QSPI Flash)
 FOTABinConverter(用来转换 bin 文件格式, 随例程软件包一起提供)
 MQTT.fx (免费的 MQTT 客户端, 下载链接 http://mqttfx.bceapp.com/)
 百度天工 IOT 物管理服务(提供 MQTT 相关服务) 和 BOS 服务(存放待下载的 MCU 新固件)  

使用特权

评论回复
6
我想看大海|  楼主 | 2022-5-5 14:04 | 只看该作者
5.云端的操作
运行本示例之前,需要先在百度天工 IoT 平台上建立好对应的服务,以及将 需要下载的固件上传到百度云的 BOS 服务器上。
下面将具体介绍如何在百度云上进行操作。
5.1 建立云端的 MQTT 服务
1. 注册并登录百度云平台: https://cloud.baidu.com/
2. 登录成功后, 导航栏选择“ 产品服务>物联网服务>物接入 IoT Hub ”  


使用特权

评论回复
7
我想看大海|  楼主 | 2022-5-5 14:05 | 只看该作者
3. 物管理的配置
创建项目, 输入“ 项目名称” , 选择项目类型为“ 设备型” , 并提交  


在项目列表里点击新建项目的名称,进入物模型和物影子创建页面:
物模型由一个或多个属性构成,可以用来它表示一类设备。
物影子是物理世界的“ 物” 在云端的影子,这个“ 物” 的属性可以从物模型中继承过来。 运行时, “ 物” 将状态值上报
给物影子,物影子会给这个“ 物” 做一个状态暂存, 百度天工其他产品可以直接使用;与此同时, 用户也可以通过操作
物影子来控制“ 物” 。


使用特权

评论回复
8
我想看大海|  楼主 | 2022-5-5 14:05 | 只看该作者
1)创建物模型
点击左侧导航栏的“物模型“, 进到物模型的页面。 输入物模型的名称,然后点击“添加属性”, 为物模型添加属性。
在添加属性的页面,输入要添加的属性名称、 类型等, 然后提交。 回到物模型的页面,可以看到刚刚创建的属性。 点击
“添加属性”可以继续添加其他属性。
最后点击“创建”按钮, 物模型就创建好了。 如下图  


使用特权

评论回复
9
我想看大海|  楼主 | 2022-5-5 14:06 | 只看该作者
2)创建物影子
点击左侧导航栏的“物影子“, 进到物影子的页面,点击“新建物影子”开始创建。 在接下来跳出的页面中,输入物影子的名
称,以及选择要使用的物模型( Sensor_node) 。然后点击“创建”  


创建成功。 系统显示与服务器进行连接的相关信息( host 地址, MQTT 连接的用户名和密码等) 。 请下载并保存这些
信息, 这是后面需要更新到 STM32 固件代码里的内容。

在 STM32F769 的程序中, 将上行消息发布到主题$baidu/iot/shadow/{deviceName}/update, 可以将设备状态更新到云端的设
备影子。
订阅主题$baidu/iot/shadow/{deviceName}/update/accepted, 可以获取设备影子更新状态的情况。
这里的 deviceName 就是前面建立的物影子的名称( STM32F769DK_001) 。
请注意, 填写到代码中去的 host 地址, 要去掉前面的“tcp://”和“ssl://”。


使用特权

评论回复
10
我想看大海|  楼主 | 2022-5-5 14:08 | 只看该作者
5.2 上传固件
预先将需要远程下载的固件放到百度的 BOS 上。 所以要先开通百度的 BOS 服务。 在导航栏选择“ 对象存储 BOS”  
在 Bucket 管理页面,新建 Bucket。 Bucket 的属性应该选择“公开读”, 如果选择“私有”的话,后面就没有办法通过
STM32F769 开发板进行下载。
建好 Bucket 后, 点击创建好的 Bucket 名称,进到 Object 管理页面。 点击“上传文件”, 就可以上传固件了。

文件上传好后,点击右边的“获取地址”, 可以获得文件下载的地址。
在本示例中, 保存在云端的固件文件并不是 bin 文件, 而是通过 FOTABinConverter 工具转换过的 cvt 文件。它在原始 bin 文
件基础上添加了固件版本, 分片大小,校验码等信息,为下载过程中提供代码分片检查完整性的便利。 FOTABinConverter 的
使用请参见第 7 节。
  



使用特权

评论回复
11
我想看大海|  楼主 | 2022-5-5 14:09 | 只看该作者
6.修改代码, 生成默认版本( v1.1)和更新版本( v2.1.1)的用户程序
建立好云端 MQTT 服务后, 我们得到了云端 MQTT 服务器的地址, MQTT 连接的用户名和密码,以及主题的名称。 这些内
容,需要写到代码里面。
在 baidu_iotclient_conf.h 文件中修改以下内容:  


MQTT_CLIENT_ID 用户自己定义就可以,保证在同一个实例下没有重复就行。
我们还需要另一个可以与 MCU 中烧录的用于应用程序区别开的程序作为新版本固件,来演示远程固件更新的功能。
示例应用代码里已经做了一个简单的开关: 只要定义宏 OTATEST_VERSION, 重新再编译一遍。 新的程序就会增加一个点灯
的操作,并且将软件版本从 1.1 改为 2.2.1。修改后的程序运行时, 还可以看到 LED2 一直在闪烁。

配置 Toolchain,生成 bin 格式的新版本固件程序, 通过下一节的工具 FOTABinConverter 进行格式转换。


使用特权

评论回复
12
我想看大海|  楼主 | 2022-5-5 14:10 | 只看该作者
7.使用 FOTABinConverter 转换 Bin 文件格式
FOTABinConverter 需要在 Dos 命令行下执行。 将需要转换的 bin 文件也拷贝到该路径下。
打开 Dos 命令框, 切到 FOTABinConverter.exe 所在的路径, 输入如下命令:
FOTABinConverter.exe -filename_orig STM32F769DK_OTA_APP.bin -file_version 2.1.1.0 -split_size 4096  


FOTABinConverter.exe 命令后面跟了三个参数:
-filename_orig: 固件的 bin 文件名( STM32F769DK_OTA_APP.bin)
-file_version:固件版本, 要与代码中的版本信息一致, 工具会把此参数信息写到转换后 cvt 文件的头部。工具接收的版本信
息格式为 major.minor.candidate.patch, 如果代码实际版本没有这么细分,末尾填零即可( 例如本例中的 2.1.1.0)
-split_size: bin 文件分块的大小, 工具会由此将 bin 文件分成多个数据块。 这个大小的值,最好根据所使用的 QSPI FLASH
的最小可擦写大小来定义(本示例所采用 QSPI Flash MX25L512G, page size=4K)
转换成功后会在相同的路径下生成 cvt 后缀的文件, STM32F769DK_OTA_APP.cvt, 文件名相同,仅后缀不同。 该 cvt 文件就
是要上传到云端的文件。 按照前面“5.2 上传固件” 部分的介绍,将这个程序上传到百度的 BOS 上,获得它的下载地址。我
们会在后面运行示例时,通过 MQTT 来推送这个下载地址给板子。


使用特权

评论回复
13
我想看大海|  楼主 | 2022-5-5 14:11 | 只看该作者
8.运行 DEMO
回顾已经完成的操作:建立好了云端的 MQTT 服务, 云端访问参数已经适配到固件代码中, 新版本固件( v 2.1.1) 生成并经
过格式转换后上传到百度云端的
BOS 服务器。 接下来我们还要对板子做一个初始化的准备工作:使用 PC 端工具 ST-LINK
Utility 烧写 MCU 片上 flash’和片外的板载 QSPI Flash。关于 ST-LINK Utility 的用法,参考《UM0892: STM32 ST-LINK utility
software description》。  

使用特权

评论回复
14
我想看大海|  楼主 | 2022-5-5 14:12 | 只看该作者
8.1 初始化 STM32F769DK 板子
Step1:全片擦除 MCU 片上 Flash 和 QSPI Flash  
从 memory 窗口可以看到全 0xff:  


Step2: 将出厂默认用户程序(v1.1) 烧写到 QSPI Flash 的默认固件区域( QSPI Flash 0x00010000 起始的位置, remap 到
STM32 的地址空间是 0x90010000) 。 用户从操作界面的 bin 文件 tab 和烧录 log 窗口可以获得该 bin 文件的大小和校验和。
Step3: 将默认用户程序( v1.1) 的大小和校验和的值,写到 QSPI FLASH INFO 区( QSPI Flash 0x0 起始的位置, remap 到
STM32 的地址空间是 0x90000000)。 这两个值在用户恢复出厂设置, 即把默认用户程序烧写回片上 MCU flash 时,用来检
查存储在 QSPI Flash 上程序的完整性。
程序大小( 4 字节) ----> 0x90000028( QSPI Flash remap 后的地址)开始的位置
校验和( 4 字节) ---->0x9000002C( QSPI Flash remap 后的地址)开始的位置
步骤 2 和步骤 3 的操作截图如下:
  
Step4: 将用户程序烧( v1.1) 烧写到 MCU flash 的 APP 区域( 0x08010000 起始位置)
Step5: 烧写 bootloader 程序到 MCU Flash 地址 0x08000000 位置
现在 STM32F769DK 板子部分的初始化工作已经完成,上电复位运行程序。



使用特权

评论回复
15
我想看大海|  楼主 | 2022-5-5 14:15 | 只看该作者
8.2 功能演示
功能一: 发送板子状态到云端
Step1:
上电复位运行程序( Bootloader 程序先运行, 然后自动跳转到用户程序);
程序会自动获取
IP 地址,连接百度云成功后, 周期性地向云端发送状态。包括: LED 的状态,软件版本和运行状态。
下面分别是以太网连接和
wifi 连接两种方式下运行的 log 信息:  

例程支持两种 log 信息打印的方式:
通过板载 STLINK-V2 自带的 USB 转串口,把 log 信息打印在 PC 的超级终端上
通过板载 LCD,把 log 信息输出到 LCD 屏幕上。以下为了截屏方便,采取第一种方式。
两种方式通过 LCD_LOG 宏切换

如果在项目全局宏使能了 LCD_LOG, 需要打开对 lcd_log.c 的编译。下文是基于串口打印 log 信息的方式,因此在项目全局
宏中不要定义 LCD_LOG, 并且关闭对 lcd_log.c 的编译。
  
另外使用 wifi 连接时, 用户还要修改代码, 在<wifi_net.c>填上所用 AP 热点的用户名和密码
  
Step2:
在 PC 机上, 打开 MQTT.fx 软件, 连接到 demo 对应的 MQTTserver。
MQTT.fx 中配置新连接的界面如下:
根据云端给出的服务器地址等信息进行配置。

配置好连接的参数后, 点击“连接”。
连接到服务器后在 Subscribe 页面订阅下面的主题: $baidu/iot/shadow/{deviceName}/update/accepted
然后就可以看到 STM32F769DK 板子发送的状态信息了。
  
如果 MQTT.fx 在 Subscribe 页面订阅的是$baidu/iot/shadow/{deviceName}/delta 主题,则表示只有板子上传的消息
有变化时, broker 才转发给 MQTT.fx 这个客户端。 由于板子上传的信息( LED 状态、 软件版本、 板子工作状态) 固
定写死了,没有变化,则 MQTT.fx 收不到 delta 主题下的消息。



使用特权

评论回复
16
我想看大海|  楼主 | 2022-5-5 14:18 | 只看该作者
功能二: 远程控制板上 LED 的状态
保持 STM32F769DK 板正常运行,并已连接到百度 IOT 服务器。
在 MQTT.fx 的 publish 窗口发布以下 Json 格式的消息到$baidu/iot/shadow/{deviceName}/update 主题, 就可以远程控制打开
板上 LED。  


由于板子有订阅【 delta】 主题, 则任何 MQTT 客户端(板子本身、 MQTT.fx) 发布到【 update】 主题的消息, 如有变化就会
推送给板子。 这里 LED 这个 key 的 value 从 off 变到了 on,因此会把此消息推送给板子。下图是板子的串口打印信息


7422262736bf3d8c2a.png (44.83 KB )

7422262736bf3d8c2a.png

使用特权

评论回复
17
我想看大海|  楼主 | 2022-5-5 14:20 | 只看该作者
功能三: 远程更新板子固件
我们前面已经预先在百度的 BOS 上放了新的固件, 并且获得了固件下载的地址是: XXXXXXX
保持 STM32F769DK 板正常运行, 并已连接到百度 IOT 服务器
MQTT.fx publish 窗口,发布新固件信息到主题: $baidu/iot/shadow/{deviceName}/update
比如,推送信息如下:
{
“desired”: {
“sw_version”:”00030300”,
“downloading_link” : “https://xxxxxxxxxxxxxxxxxxxxx.xxxxx_APP_v0_3_3.cvt”
}
}
“sw_version”, 就是要下载的固件的版本。版本格式为:主版本号:+副版本号+测试版本号+00, 应该和 version.h 中的版本对
应。比如:有一个软件版本如下:
#define FW_VERSION_MAJOR 1
#define FW_VERSION_MINOR 1
#define FW_VERSION_PATCH 0
那么在推送信息中的版本号应该写: “01010000” 。

STM32F769DK 板子收到推送的新固件信息后,进行解析, 并与当前 QSPI 中的版本进行比较。如果比当前 QSPI 中的版本
新,则自动进行下载。

下载完成后,提示当前有新版本可用。如果需要更新 MCU, 请按蓝色 USER 按键。

用户按下蓝色 USER 按键后,程序复位。开始执行 bootloader 程序。
在 bootloader 程序中会将新的固件从 QSPI FLASH 烧写到 MCU 片上的 FLASH 中。 然后跳转执行。
在烧写固件前, 程序会检查固件的完整性。如果发现固件被损坏,则不烧写。直接跳转执行老的程序,并且会在 QSPI 的
INFO 区做相应记录。 重新从云端下载好的固件来覆盖已被损坏的固件。



使用特权

评论回复
18
我想看大海|  楼主 | 2022-5-5 14:21 | 只看该作者
功能四: 一键恢复出厂固件
该例程还提供了一键恢复出厂固件的功能。
上电复位,程序在执行 bootloader 时,立刻按下蓝色 USER 键,就选择了恢复出厂固件。程序会从 QSPI FLASH 的
0x00010000 位置将预先烧录好的默认固件烧写到 MCU 中。然后跳转执行。 同样在烧写固件前, 程序会检查固件的完整性。
如果发现固件被损坏,则不烧写。直接跳转执行老的程序,并且会在 QSPI 的 INFO 区做相应记录。 重新从云端下载好的固件
来覆盖已被损坏的固件。  

使用特权

评论回复
19
Uriah| | 2022-10-7 08:14 | 只看该作者

使用Optional简化if判空

使用特权

评论回复
20
Bblythe| | 2022-10-7 11:13 | 只看该作者

通过对判断条件取反,代码在逻辑表达上会更加清晰

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

30

主题

252

帖子

0

粉丝