RT-Thread 官方推出了 STM32 系列单片机的通用 bootloader, 在其网站可以通过网页配置就可以生成 bootloader 的烧录文件,使广大嵌入式工程师不用编写一行代码,就能够轻松完成自己产品的 bootloader 功能。但是由于 RTT 官方的 bootloader 软件 RT-OTA 是商用性质,不公开源码,不仅仅限制了在其他平台的移植,而且也不方便加入产品的特定功能。本人软件水平有限,但是基于对开源精神的崇拜和 RTT 多年的感情,蒙发出利用业余时间编写一款开源的且基于 RTT 系统 bootloader 通用软件,贡献给大家。
由于 RTT 官方推出的 bootloader 名字叫 RT-OTA,因此为了蹭点 RTT 的流量,我这个 bootloader 名字就叫 RT-FOTA。
【RT-FOTA 的需求分析】
开发基于 RTOS 的 bootloader 软件,网上很多牛人会说 bootloader 最好是裸机程序编写,就像 u-boot 一样稳定和可靠。但我个人认为目前 32 位单片机资源丰富,RT-Thread 的稳定和可靠性不言而喻,加之 RTT 的组件丰富,后续功能拓展方便(比如加入网络和 USB 功能)。因此我使用 RT-Thread 的阉割版本 rtt-nano 实现。
兼容 RTT 官方的 rbl 文件:使用 RTT 官方的打包软件生成下载文件,可以实现加密压缩功能。由于个人水平问题,只能做到尽可能的兼容,比如 RBL 文件里面的 HASH_CODE 我就不知道怎么计算出来的。
移植方便:由于 RT-FOTA 基于 RT-Thread 开发,因此只要你的平台被 RT-Thread 支持,就可以很方便的移植到。
【RT-FOTA 主要的功能】
软件开发目录参照 RTT 的目录形式,如下图所示:
我原本计划添加 SCONS 进行编译,但目前对 SCONS 的使用还不熟悉,下次再实现,因此暂时使用 MDK 完成。
可以看到我并未按照 RTT 官方推荐的使用 MDK 或 cube 生成 rtt-nano 的工程,原因是我有强迫症,感觉 IDE 生成的目录很不爽。
RT-FOTA 的软件配置仍然集中在 rtconfig.h 中,其中一些. c 文件中有一些默认的配置宏,但可以根据需求进行修改。
/* RT-Thread config file */ #ifndef RT_CONFIG_H__ #define RT_CONFIG_H__ #define RT_THREAD_PRIORITY_MAX 8 #define RT_TICK_PER_SECOND 1000 #define RT_ALIGN_SIZE 4 #define RT_NAME_MAX 8 /* Kernel Device Object */ #define RT_USING_DEVICE #define RT_USING_CONSOLE #define RT_CONSOLEBUF_SIZE 512 #define RT_CONSOLE_DEVICE_NAME "uart1" #define RT_VER_NUM 0x30102 #define RT_USING_CPU_FFS /* RT-Thread Components */ #define RT_USING_COMPONENTS_INIT #define RT_USING_USER_MAIN #define RT_DEBUG_INIT 0 #define RT_USING_OVERFLOW_CHECK // #define RT_USING_HOOK // #define RT_USING_IDLE_HOOK /* Software timers Configuration */ #define RT_USING_TIMER_SOFT 0 #if RT_USING_TIMER_SOFT == 0 #undef RT_USING_TIMER_SOFT #endif #define RT_TIMER_THREAD_PRIO 4 #define RT_TIMER_THREAD_STACK_SIZE 512 #define RT_TIMER_TICK_PER_SECOND 100 /* IPC(Inter-process communication) Configuration */ #define RT_USING_SEMAPHORE #define RT_USING_MUTEX //#define RT_USING_EVENT //#define RT_USING_MAILBOX //#define RT_USING_MESSAGEQUEUE /* Memory Management Configuration */ #define RT_USING_HEAP #define RT_USING_MEMHEAP #define RT_USING_SMALL_MEM /* Finsh Configuration */ #define RT_USING_FINSH #define FINSH_USING_MSH #define FINSH_USING_MSH_ONLY #define __FINSH_THREAD_PRIORITY 5 #define FINSH_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX / 8 * __FINSH_THREAD_PRIORITY + 1) #define FINSH_THREAD_STACK_SIZE 2048 #define FINSH_USING_HISTORY #define FINSH_HISTORY_LINES 5 #define FINSH_USING_SYMTAB #define FINSH_USING_AUTH /* 可配置 FINSH 的 authencation 功能, 防止随意使用 FINSH */ #define FINSH_DEFAULT_PASSWORD "radiation" #define FINSH_PASSWORD_MIN 6 #define FINSH_PASSWORD_MAX 16 /* Device Drivers */ #define RT_USING_PIN #define RT_USING_SERIAL // #define RT_SERIAL_USING_DMA #define RT_USING_RTC #define RT_USING_SPI #define RT_USING_SFUD #define RT_SFUD_USING_SFDP #define RT_SFUD_USING_FLASH_INFO_TABLE #define RT_USING_WDT /* RTT 组件配置 */ /* fal package */ #define PKG_USING_FAL #define FAL_DEBUG_CONFIG #define FAL_DEBUG 0 #define FAL_PART_HAS_TABLE_CFG #define FAL_USING_SFUD_PORT #define FAL_USING_NOR_FLASH_DEV_NAME "nor_flash0" #define PKG_USING_FAL_LATEST_VERSION #define PKG_FAL_VER_NUM 0x99999 /* Tinycrypt package */ #define TINY_CRYPT_AES /* Compress package */ #define QLZ_COMPRESSION_LEVEL 3 /* Hardware Drivers Config */ #define SOC_FAMILY_STM32 #define SOC_SERIES_STM32F4 #define SOC_STM32F407ZE /* On-chip Peripheral Drivers */ #define BSP_USING_GPIO #define BSP_USING_ON_CHIP_FLASH #define BSP_USING_ONCHIP_RTC #define BSP_USING_UART #define BSP_USING_UART1 #define BSP_USING_SPI #define BSP_USING_SPI1 /* Onboard Peripheral Drivers */ #define BSP_DATAFALSH_CS_PIN 30 /* Board extended module Drivers */ #define BSP_RS485_DIR_PIN 52 /* RT-FOTA module define */ #define RT_FOTA_SW_VERSION "1.0.0" /* Enable Ymodem OTA */ #define PKG_USING_YMODEM_OTA /* 分区名字可以根据自己的需求而定 */ /* FOTA application partition name */ #ifndef RT_FOTA_APP_PART_NAME #define RT_FOTA_APP_PART_NAME "app" #endif /* FOTA download partition name */ #ifndef RT_FOTA_FM_PART_NAME #define RT_FOTA_FM_PART_NAME "fm_area" #endif /* FOTA default partition name */ #ifndef RT_FOTA_DF_PART_NAME #define RT_FOTA_DF_PART_NAME "df_area" #endif /* 此两项密码必须与 RTT 的打包软件设置一致 */ /* AES256 encryption algorithm option */ #define RT_FOTA_ALGO_AES_IV "0123456789ABCDEF" #define RT_FOTA_ALGO_AES_KEY "0123456789ABCDEF0123456789ABCDEF" #endif
使用过 RTT 官方的 RT-OTA 组件的朋友都知道,下载的不是 bin 文件,而是需要通过 RTT 打包软件 “装饰” 成 rbl 文件之后,才能被 RT-OTA 识别。
RTT 的打包软件可以设置代码加密和压缩,其配置信息都存在 rbl 文件前 96 字节中:
rt-fota />fota show fm_area 0 96 00000000: 52 42 4C 00 00 02 00 00 5E A9 A4 5D 61 70 70 00 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 31 2E 30 2E 00000020: 36 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000030: 00 00 00 00 31 2E 30 2E 36 00 00 00 00 00 00 00 00000040: 00 00 00 00 00 00 00 00 00 00 00 00 43 33 29 0A 00000050: 47 08 F6 DA 84 BB 00 00 1C 84 00 00 C4 3D E3 B5
其具体含义如下:
typedef struct { char type[4]; /* RBL 字符头 */ rt_uint16_t fota_algo; /* 算法配置: 表示是否加密或者使用了压缩算法 */ rt_uint8_t fm_time[6]; /* 原始 bin 文件的时间戳, 6 位时间戳, 使用了 4 字节, 包含年月日信息 */ char app_part_name[16]; /* app 执行分区名 */ char download_version[24]; /* 固件代码版本号 */ char current_version[24]; /* 这个域在 rbl 文件生成时都是一样的,我用于表示 app 分区当前运行固件的版本号,判断是否固件需要升级 */ rt_uint32_t code_crc; /* 代码的 CRC32 校验值, 它是的打包后的校验值, 即 rbl 文件 96 字节后的数据 */ rt_uint32_t hash_val; /* 估计这个域是指的原始代码本身的校验值,但不知道算法,无法确认,故在程序中未使用 */ rt_uint32_t raw_size; /* 原始代码的大小 */ rt_uint32_t com_size; /* 打包代码的大小 */ rt_uint32_t head_crc; /* rbl 文件头的 CRC32 校验值,即 rbl 文件的前 96 字节 */ } rt_fota_part_head, *rt_fota_part_head_t;
RT-FOTA 开机界面如下图:
可以看出使用了 RTT 的 SFUD 和 FAL 组件,同时列出了分区变信息。
RT-FOTA 源码公开,你想怎么改就怎么改, 不在受限制:)
最后一行是表示在 5 秒钟内,按下 Enter 键,即 0x0d,就可以进入命令行模式:
由于 FINSH 具备 authencation 功能,可以设置 shell 密码。具体详见 RTT 相关文档。
RT-FOTA 的命令行模式使用的 RTT 的 FINSH 组件, 除了 RTT 系统自带命令外,还增加 fota 和 ymdown 命令:
**fota 命令 **
键入 fota 命令后回车即可看到帮助命令:
rt-fota />fota Usage: fota probe - probe RBL file of partiton fota show partition addr size - show 'size' bytes starting at 'addr' fota clone des_part src_part - clone src partition to des partiton fota exec - execute application program
probe 参数可以打印出当分区的 RBL 信息:
rt-fota />fota probe [I/fota] ===== RBL of fm_area partition ===== [I/fota] | App partition name | app | [I/fota] | Algorithm mode | AES && QLZ | [I/fota] | Firmware version | 1.0.3 | [I/fota] | Code raw size | 48004 | [I/fota] | Code package size | 33824 | [I/fota] | Build Timestamp | 1571072350 | [I/fota] ===== RBL of df_area partition ===== [I/fota] | App partition name | app | [I/fota] | Algorithm mode | AES && QLZ | [I/fota] | Firmware version | 1.0.3 | [I/fota] | Code raw size | 48004 | [I/fota] | Code package size | 33824 | [I/fota] | Build Timestamp | 1571072350 |
这里列出了 fm_area 和 df_area 分区中 RBL 文件的主要信息项, 便于开发者查询:
App partition name: 指的是 RTT 打包文件时设置的分区名
Algorithm mode : 指的是 RTT 打包文件使用那些算法:AES256/Quicklz/Fastlz
Firmware version : 指的是 RTT 打包文件设置的固件版本号
Code raw size : 指的代码原始大小
Code package size : 指的代码打包后的大小
Build Timestamp : 指的代码生成的时间戳
show 参数可以显示分区的具体实际数据,方便调试与检查:
rt-fota />fota show app 0 96 00000000: C0 08 00 20 E5 57 02 08 5D 04 02 08 5F 04 02 08 00000010: 63 04 02 08 67 04 02 08 6B 04 02 08 00 00 00 00 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 6F 04 02 08 00000030: 71 04 02 08 00 00 00 00 73 04 02 08 75 04 02 08 00000040: FF 57 02 08 FF 57 02 08 FF 57 02 08 49 55 02 08 00000050: FF 57 02 08 FF 57 02 08 FF 57 02 08 FF 57 02 08
这里列出了 app 分区 0 到 96 字节的数据
**clone 参数是实现分区数据克隆 **
rt-fota />fota clone fm_area df_area Clone df_area partition to fm_area partition: ######################################################### ######################################################### ######################################################### ######################################################### ############################ Clone partition success, total 1048576 bytes!
这里是将 df _ area 分区数据完整的克隆岛 fm _ area 中。
**exec 参数是用于执行 app 分区的应用代码 **
rt-fota />fota exec [I/fota] Implement application now. LCD ID:5510
**ymdown 命令 **
ymdown 是基于 Ymodem 协议的下载命令,使用 RTT 的 ymodem 和 ymodem _ ota 组件实现,其中将 ymodem _ ota.c 中的 DEFAULT_DOWNLOAD_PART 设置为需要默认使用分区名,即在使用 ymdown 不带参数的情况下就下载到 DEFAULT_DOWNLOAD_PART 分区,也可加分区名作为参数指定下载位置。
rt-fota />ymdown Default save firmware on download partition. Warning: Ymodem has started! This operator will not recovery. Please select the ota firmware file and use Ymodem to send. CCCCCC Starting ymodem transfer. Press Ctrl+C to cancel. 100% 33 KB 6 KB/s 00:00:05 0 Errors Download firmware to flash success. Download firmware verify........[OK] Reset system and apply new firmware.
下载完成后,会自动复位重新启动,将新固件搬运到 app 分区中:
____ _____ _____ ___ _____ _ | _ \_ _| | ___/ _ \ _ _|/ \ | |_) || |_____ | |_ || || | | / _ \ | _ < | |_____ | _| ||_|| | |/ ___ \ |_| \_\|_| |_| \___/ |_/_/ \_\ 2016 - 2019 Copyright by Radiation @ warfalcon Version: 1.0.0 build Oct 18 2019 [SFUD] Find a Winbond flash chip. Size is 16777216 bytes. [SFUD] nor_flash0 flash device is initialize success. [I/FAL] ==================== FAL partition table ==================== [I/FAL] | name | flash_dev | offset | length | [I/FAL] ------------------------------------------------------------- [I/FAL] | app | onchip_flash | 0x00020000 | 0x000e0000 | [I/FAL] | fm_area | nor_flash0 | 0x00000000 | 0x00100000 | [I/FAL] | df_area | nor_flash0 | 0x00100000 | 0x00100000 | [I/FAL] ============================================================= [I/FAL] RT-Thread Flash Abstraction Layer (V0.4.0) initialize success. Please press [Enter] key into shell mode in 5 secs: [I/fota] Partition[app] erase start: [I/fota] Start to copy firmware from fm_area to app partition: ############ [I/fota] Upgrade success, total 48004 bytes. [I/fota] Copy firmware version Success! [I/fota] Implement application now. LCD ID:5510
恢复出厂固件的方式比较多,本人多年的工程实践经验,倾向于使用外部按键长按后进行出厂固件恢复。出厂固件存储在 df _ area 分区中(分区名在代码中任意设置),长按按键 10s 后 (长按时间在代码中任意设置),RT-FOTA 会自动解密解压 df _ area 分区代码,并搬运到 app 分区进行执行。
Default firmware key pressed: >>>>>>>>>> [I/fota] Partition[app] erase start: [I/fota] Start to copy firmware from df_area to app partition: ############ [I/fota] Upgrade success, total 48004 bytes. [I/fota] Implement application now. LCD ID:5510
RT-FOTA 移植很简单,只要 RT-Thread 源码包中有你的平台的 BSP 包即可:)
RT-FOTA 中使用的各种组件的修改也很简单,比如 FAL 和 SFUD 就可以参照 RTT 官方说明,SignalLED 参照源码包里的 README.md 即可。
RT-FOTA 可以直接使用在 RT-Thread 的完整版搭载,只需要将 * rt _ fota.c*、*rt _ fota.h * 和 * rt _ fota_crc.c * 放入工程中即可实现,然后用 env 配置相关组件即可。
双击 bootloader.uvprojx 文件,打开 MDK5 工程,编译并下载程序到开发板。
工程默认配置使用 JLINK 仿真器下载程序,点击下载按钮即可下载程序到开发板
下载程序成功之后,系统 RT-FOTA 会运行:
连接目标板的串口 1 到 PC , 在终端工具里打开相应的串口(115200-8-1-N),复位设备后,可以看到 RT-FOTA 的输出信息:
____ _____ _____ ___ _____ _ | _ \_ _| | ___/ _ \ _ _|/ \ | |_) || |_____ | |_ || || | | / _ \ | _ < | |_____ | _| ||_|| | |/ ___ \ |_| \_\|_| |_| \___/ |_/_/ \_\ 2016 - 2019 Copyright by Radiation @ warfalcon Version: 1.0.0 build Oct 18 2019 [SFUD] Find a Winbond flash chip. Size is 16777216 bytes. [SFUD] nor_flash0 flash device is initialize success. [I/FAL] ==================== FAL partition table ==================== [I/FAL] | name | flash_dev | offset | length | [I/FAL] ------------------------------------------------------------- [I/FAL] | app | onchip_flash | 0x00020000 | 0x000e0000 | [I/FAL] | fm_area | nor_flash0 | 0x00000000 | 0x00100000 | [I/FAL] | df_area | nor_flash0 | 0x00100000 | 0x00100000 | [I/FAL] ============================================================= [I/FAL] RT-Thread Flash Abstraction Layer (V0.4.0) initialize success.
RT-FOTA 使用正点原子的探索者开发板,如果要运行到其他目标板,可能需要修改相关设置;
代码中使用的硬件有 usart0、spi0、PE4(key0)、PF9(led0);
由于业余时间开发,文档逐步完善,但只要有一定编程基础的朋友,开代码注释即可知道如果进行相关修改;
目录 【STM32F429】移植TouchGFX到RT-Thread系统(1) 【STM32F429】使用TouchGFX的MVP架构来实现GUI和硬件的双向交互(2) 【STM32F429】RT-Thread移植touchgfx实现自动同步网络时间和天气预报(3) 【STM32F429】RT-Thread移植touchgfx使用sd卡升级固件和图片资源(4) 实验平台: 硬件: 野火挑战者STM
GD32 OTA/Bootloader驱动函数 驱动函数需要修改一个文件rt_fota.c,添加内部flash操作相关文件,删除外部flash操作相关文件,移植过程注意事项及其它外设移植细节参见 移植完整版RT-Thread到GD32F4XX(详细) 中关于bootloader及flash移植相关内容,移植完成后使用及验证方法同stm32 原开源项目位于https://gitee.com/spun
简介 为了能让开发者快速掌握 OTA 升级这把利器,RT-Thread 开发团队提供了通用的 Bootloader。开发者通过该 Bootloader 即可直接使用 RT-Thread OTA 功能,轻松实现对设备端固件的管理、升级与维护。 下图展示了 RT-Thread 通用 Bootloader 的软件框架: RT-Thread 通用 Bootloader 有如下特点: 以 bin 文件的形式
本文向大家介绍基于Debian的linux系统软件安装命令详解 (推荐),包括了基于Debian的linux系统软件安装命令详解 (推荐)的使用技巧和注意事项,需要的朋友参考一下 Debian简介 广义的Debian是指一个致力于创建自由操作系统的合作组织及其作品,由于Debian项目众多内核分支中以Linux宏内核为主,而且 Debian开发者 所创建的操作系统中绝大部分基础工具来自于GNU工
概述 本章节介绍如何从一个系统的数据库设计模型出发,一步步设计一个系统。 在软件项目(尤其是外包软件项目)中,通常有两种情况: 客户提供软件需求书; 客户提供原型设计; 对于以上两种情况的项目,在开发的流程上是有很大的差别的,最大的差别就在于页面交互上。 客户提供软件需求书:页面数量及形态不确定,带来的复杂性也不确定;(所以,为了固化需求,通常会跟客户做出原型或者UI进行需求确认,跟客户的合同也会
Polar M600 由 Wear OS by Google 提供支持。如果有新的 Wear OS by Google 系统更新版可用,您的 M600 将收到自动通知。当您的智能手表插入电源充电并通过蓝牙连接到您的手机,且您的手机有连接互联网时,更新版软件将下载到 M600。 您也可通过您的智能手表手动检查是否有 Wear OS by Google 软件更新版。 手动检查软件更新版 导航至 Set
1:联系用户兴趣和物品的方式 2:标签系统的典型代表 3:用户如何打标签 4:基于标签的推荐系统 5:算法的改进 6:标签推荐 一:联系用户兴趣和物品的方式 推荐系统的目的是联系用户的兴趣和物品,这种联系方式需要依赖不同的媒介。目前流行的推荐系统基本上是通过三种方式联系用户兴趣和物品。 1:利用用户喜欢过的物品,给用户推荐与他喜欢过的物品相似的物品,即基于item的系统过滤推荐算法 2:利用用户和
我的一个模块项目中有一个考勤系统,使用PHP和MySQL,MySQL表如下所示: 现在,时间表被用来存储一天中某一段的类时间表,以及分配给哪位老师。student_info表包含有关学生及其所属部分的一般信息。attendancetable用于记录缺勤人员,使用时间和学生id作为主键。 我可以得到一个学期有多少类被录取的统计如下: 然后计算一个学生参加的次数,也计算出勤率。 现在,我还想显示一种考