Dinor 发表于 2022-11-28 14:23:30

分享一个我开源的OTA组件

本帖最后由 Dinor 于 2022-11-28 14:25 编辑

mOTA

一、简介    本开源工程是一款专为 32 位 MCU 开发的 OTA 组件,组件包含了 bootloader 、固件打包器 (Firmware_Packager) 、固件发送器 三部分,并提供了一个基于 STM32F103 和 YModem-1K 协议的案例,因此本案例的固件发送器名为 YModem_Sender 。
二、实现的功能    MCU 设备上的 OTA 升级可理解为 IAP (In Application Programming) 技术, MCU 通过外设接口(如 UART 、 IIC 、 SPI 、 CAN 、 USB 等接口),连接具备联网能力的模块、器件、设备(以下统称上位机)。上位机从服务器上拉取固件包,再将固件包以约定的通讯协议,经由通讯接口发送至 MCU ,由 MCU 负责固件的解析、解密、存储、更新等操作,以完成设备固件更新的功能。需要注意的是, example 提供的示例不基于文件系统,而是通过对 Flash 划分为不同的功能区域完成固件的更新。
本组件实现了以下功能:
[*]固件包完整性检查: 自动检测固件 CRC 值,保证固件数据的可靠性。
[*]固件加密: 支持 AES256 加密算法,提高固件的安全性。
[*]APP 完整性检查: 支持 APP 运行前进行完整性检查,以确认运行的固件无数据缺陷。
[*]断电保护: 当固件更新过程中(含下载、解密、更新等过程),任何一个环节断电,设备再次上电时,依然能确保有可用的固件。(需配置为至少双分区)
[*]固件水印检查: 可检测固件包是否携带了特殊的水印,确认非第三方或非匹配的固件包。
[*]固件自动更新: 当 download 或 factory 分区有可用的固件,且 APP 分区为空或 APP 分区不是最新版本的固件时,可配置为自动开始更新。
[*]恢复出厂设置: factory 分区存放稳定版的固件,当设备需要恢复出厂设置时,该固件会被更新至 APP 分区。
[*]无须 deinit : 我们知道,固件更新完毕后从 bootloader 跳转至 APP 前需要对所用的外设进行 deinit ,恢复至上电时的初始状态。本组件的 bootloader 包含了下载器的功能,当使用复杂的外设收取固件包时, deinit 也将变得复杂,甚至很难排除对 APP 的影响。为此,本组件采用了再入 bootloader 的方式,给 APP 提供一个相当于刚上电的外设环境,免去了 deinit 的代码。
[*]功能可裁剪: 本组件通过功能裁剪可实现单分区、双分区、三分区的方案切换、是否配置解密组件、是否自动更新 APP 、是否检查 APP 完整性、 是否使用 SPI Flash (待实现) 。

暂未实现的功能:
[*]支持将固件存放至 SPI Flash 的功能。


开源链接:mOTA: 一款专为32位MCU开发的OTA组件 (gitee.com)





守望者 发表于 2022-11-28 15:04:37

这个必须得给个大大的赞

eric2013 发表于 2022-11-29 00:26:01

谢谢楼主分享,非常好

guoxiang 发表于 2022-11-29 08:42:32

牛逼PLUS

Eason.XJ 发表于 2022-11-29 08:50:37

我直接好家伙,感谢大佬分享,学习一下

dacongzi 发表于 2022-11-29 09:06:02

cool

blackfire531 发表于 2022-11-29 11:08:54

这个看起来好棒,下载试试看

tomyqg 发表于 2022-11-29 13:52:39

再加上差分就完美了,可用的差分库 https://github.com/sisong/HPatchLite :lol

LSHY 发表于 2022-11-30 09:07:15

感谢大佬的奉献YYDS

西点钟灵毓秀 发表于 2022-11-30 09:46:44


牛逼PLUS

zhang00956 发表于 2022-11-30 09:58:29

tomyqg 发表于 2022-11-29 13:52
再加上差分就完美了,可用的差分库 https://github.com/sisong/HPatchLite

附议,差分OTA非常完美

incarry 发表于 2022-11-30 10:37:23

tomyqg 发表于 2022-11-29 13:52
再加上差分就完美了,可用的差分库 https://github.com/sisong/HPatchLite

请问大神 差分库是啥意思,没看懂 哈哈哈哈

ayuanshop 发表于 2022-11-30 10:38:36

哇哈哈哈哈哈哈哈哈谢谢谢谢

直接无奶白嫖了~~

w1809879 发表于 2022-11-30 11:34:24

大佬牛逼

blueice1108 发表于 2022-11-30 11:50:46

很棒后续白嫖移植视频:lol:lol:lol

banzhangzzw 发表于 2022-11-30 15:45:12

强赞!!加上差分就更好了!

tomasgod 发表于 2022-11-30 20:08:35

多谢分享{:8:}

blackfire531 发表于 2022-12-1 11:03:42

大佬你好,请问用上位机给bootloader下发的时候,提示错误7怎么办?在RTT view里看到收到文件大小了,然后就卡在bootloader不动了,这是什么情况啊?

ssimple 发表于 2022-12-1 14:42:27

大佬 我看你的ymodem上位机源码serial_port.cpp文件里的这段代码connect(_serial_port, &QSerialPort::readyRead, this, &Serial_Port::readyRead);
Serial_Port::readyRead 这个在.h里被声明成信号
这是用connect连接了两个信号吗有啥用啊   

Dinor 发表于 2022-12-2 16:03:28

tomyqg 发表于 2022-11-29 13:52
再加上差分就完美了,可用的差分库 https://github.com/sisong/HPatchLite

谢谢建议,考虑到有些 flash 的 sector 较大,且多数产品的 bin 并不是很大,暂时先完善基本功能,添加更多的 example 。

Dinor 发表于 2022-12-2 16:06:57

blackfire531 发表于 2022-12-1 11:03
大佬你好,请问用上位机给bootloader下发的时候,提示错误7怎么办?在RTT view里看到收到文件大小了,然后 ...

你是否使用了 DMA ?建议把 app.c 中的 _dev_rx_buff 在原有的基础上增加一些,例如:
static uint8_t _dev_rx_buff;

请记得以下代码也要同步修改:
DT_Init(&_data_if, BSP_UART1, _dev_rx_buff, &_dev_rx_len, PP_MSG_BUFF_SIZE + 16);

Dinor 发表于 2022-12-2 16:12:35

ssimple 发表于 2022-12-1 14:42
大佬 我看你的ymodem上位机源码serial_port.cpp文件里的这段代码connect(_serial_port, &QSerialPort::re ...

Qt 是可以信号连接信号的,我忘了之前为什么会引用 serial_port 的一个 readyRead 信号了,现在是没用到的。

blackfire531 发表于 2022-12-2 22:06:57

本帖最后由 blackfire531 于 2022-12-2 22:14 编辑

做了一个F407IG的移植分享给大家,还挺简单的,感觉能用到项目中;期间遇到比较奇怪的问题是Bootloader始终跳转失败,每次跳转程序都会跑飞,后来把AC6的优化等级从O0调整为O1就正常了,感觉略坑啊。

大佬给把全套工具都配齐了,感谢大佬!

大家测试的时候修改LED管脚和UART1的管脚即可。








Dinor 发表于 2022-12-3 17:02:13

blackfire531 发表于 2022-12-2 22:06
做了一个F407IG的移植分享给大家,还挺简单的,感觉能用到项目中;期间遇到比较奇怪的问题是Bootloader始终 ...

谢谢你的分享,这是 semihosting 的问题,我忘记测试 AC6 的 -O0 ,忽略了 semihosting 的问题,感谢提出,在工程中任意一个位置添加以下代码即可解决。另外还是建议开优化,不优化占用的 flash 比较多。

#if __IS_COMPILER_ARM_COMPILER_6__
    __asm(".global __use_no_semihosting");
#elif __IS_COMPILER_ARM_COMPILER_5__
    #pragma import(__use_no_semihosting)
#endif

blackfire531 发表于 2022-12-3 23:21:31

Dinor 发表于 2022-12-3 17:02
谢谢你的分享,这是 semihosting 的问题,我忘记测试 AC6 的 -O0 ,忽略了 semihosting 的问题,感谢提出 ...

是因为semihosting触发了软中断导致跳转异常吗?在网上没有找到详细的描述,而且勾选了MicroLIB之后不是就不再使用半主机了么?
大佬能稍微详细描述一下原理吗?感谢。

Dinor 发表于 2022-12-4 00:48:49

blackfire531 发表于 2022-12-3 23:21
是因为semihosting触发了软中断导致跳转异常吗?在网上没有找到详细的描述,而且勾选了MicroLIB之后不是 ...

抱歉,是我弄错了,不是 semihosting 的问题,是 AC6 -O0 下优化,局部变量会在堆栈中操作,而设置了栈顶指针后,堆栈中的局部变量的值就变为 0 了,此时跳转至地址 0 ,就会触发 hardfault ,硬汉之前也有写过一个帖子说过这个问题。

https://www.armbbs.cn/forum.php?mod=viewthread&tid=116103&highlight=0%BC%B6%D3%C5%BB%AF

还是十分感谢你的提醒,这是一个低级的错误,我会在这之后更新至 gitee 。

icode 发表于 2022-12-4 19:07:12

厉害,楼主这个做得比较赞 :handshake

blackfire531 发表于 2022-12-4 21:08:25

之前确实看到过硬汉的帖子说过AC6的坑,结果只记者标题,忘了内容:L

虾米麻烦 发表于 2022-12-6 11:21:54

大佬,有个特殊的情况想问一下。
就是用户程序中有将flash作为存储少量系统配置的功能,而为了优化空间和擦除时间,将flash空间配置到了flash前段扇区大小比较小的区域,形成了(程序-空扇区-程序)的固件。
然后当程序运行后空扇区会被写入数据,这样会不会导致下次启动时检测到固件发生改变呢。另外就是更新固件的时候,以往用jflash或openocd烧写新固件的时候,软件会自动跳过固件中的空扇区保留其中的内容,而如果使用mOTA是否会将其作为连续空间而一并擦除呢

Dinor 发表于 2022-12-6 13:36:39

虾米麻烦 发表于 2022-12-6 11:21
大佬,有个特殊的情况想问一下。
就是用户程序中有将flash作为存储少量系统配置的功能,而为了优化空间和 ...

你说的这个问题很好解决,假设 bootloader 的地址是 0x0800 0000 ,大小是 32kB ,则 APP 对应的地址是 0x0800 8000 ,假设 APP 分区大小也是 32kB ,如果在 APP 运行时需要往 APP 分区的一块 flash 区域 写入数据,假设是 2kB 。以 mOTA 为例,只需要在 user_config.h 中这样配置:

#define BOOTLOADER_SIZE   ((uint32_t)(32 * 1024))
#define APP_PART_SIZE   ((uint32_t)(30 * 1024))

同时,修改 app_config.h 里的 DOWNLOAD_ADDRESS 宏为:

#define DOWNLOAD_ADDRESS   ((uint32_t)(APP_ADDRESS + APP_PART_SIZE + (2 * 1024)))

如此修改,对于 mOTA 的所有功能都不会有影响,那个 2kB 的区域即不会被擦除,也不会在进行 APP 校验时被判断进去。需要注意的是,这里默认 flash 的擦除粒度是 2kB ,其它 flash 需要按 flash 的 sector 或 page 处理,思路就是这样。

buxinshan 发表于 2022-12-7 09:10:53

混绕视听,OTA概念是啥?这就是IAP,说成是OTA。

wdliming 发表于 2022-12-7 21:17:19

谢谢分享~~~~

koon 发表于 2022-12-15 11:54:38

谢谢分享~ MARK

sy2009 发表于 2022-12-16 10:49:05

谢谢分享~ MARK

跟着硬汉学 发表于 2023-6-9 14:51:39

tomyqg 发表于 2022-11-29 13:52
再加上差分就完美了,可用的差分库 https://github.com/sisong/HPatchLite

您用过这个吗?

小杨同学 发表于 2023-9-12 14:36:59

求移植方法,看源码看懵逼了

小杨同学 发表于 2023-9-12 14:40:43

Dinor 发表于 2022-12-4 00:48
抱歉,是我弄错了,不是 semihosting 的问题,是 AC6 -O0 下优化,局部变量会在堆栈中操作,而设置了栈顶 ...

大佬,如果移植具体要改什么啊,我发文件报错ERR:OX06

小杨同学 发表于 2023-9-12 18:34:20

blackfire531 发表于 2022-12-1 11:03
大佬你好,请问用上位机给bootloader下发的时候,提示错误7怎么办?在RTT view里看到收到文件大小了,然后 ...

你比我好,我是错误6,我文件都没收到

Embedded_Proter 发表于 2024-2-10 20:45:26

小杨同学 发表于 2023-9-12 18:34
你比我好,我是错误6,我文件都没收到

老哥你解决了嘛我也遇到了
页: [1]
查看完整版本: 分享一个我开源的OTA组件