RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

針對(duì)單片機(jī)開(kāi)發(fā)的輕量級(jí)OTA組件

strongerHuang ? 來(lái)源:Gitee ? 2022-12-26 09:36 ? 次閱讀

今天為大家分享一款開(kāi)源的,專(zhuān)為單片機(jī)開(kāi)發(fā)的輕量級(jí) OTA 組件:mOTA。

一、簡(jiǎn)介

本開(kāi)源工程是一款專(zhuān)為 32 位 MCU 開(kāi)發(fā)的 OTA 組件,組件包含了bootloader、固件打包器(Firmware_Packager)、固件發(fā)送器三部分,并提供了一個(gè)基于 STM32F103 和 YModem-1K 協(xié)議的案例,因此本案例的固件發(fā)送器名為YModem_Sender。

mOTA 中的 m 可意為 mini 、 micro 、 MCU ( Microcontroller Unit ),而 OTA ( Over-the-Air Technology ),即空中下載技術(shù),根據(jù)維基百科的定義, OTA 是一種為設(shè)備分發(fā)新軟件、配置,乃至更新加密密鑰(為例如移動(dòng)電話(huà)、數(shù)字視頻轉(zhuǎn)換盒或安全語(yǔ)音通信設(shè)備——加密的雙向無(wú)線(xiàn)電)的方法。OTA 的一項(xiàng)重要特征是,一個(gè)中心位置可以向所有用戶(hù)發(fā)送更新,其不能拒絕、破壞或改變?cè)摳?,并且該更新為立即?yīng)用到頻道上的每個(gè)人。用戶(hù)有可能“拒絕” OTA 更新,但頻道管理者也可以將其踢出頻道。由此可得出 OTA 技術(shù)幾個(gè)主要的特性:

一個(gè)中心可向多個(gè)設(shè)備分發(fā)更新資料(固件);

更新資料一旦發(fā)送便不可被更改;

設(shè)備可以拒絕更新;

中心可以排除指定的設(shè)備,使其不會(huì)接收到更新資料。

本工程僅實(shí)現(xiàn) OTA 更新資料的部分技術(shù),即上文列出的 OTA 技術(shù)幾個(gè)主要的特性,而不關(guān)心中心分發(fā)資料中間采用何種傳輸技術(shù)。(本工程的 example 使用 UART 作為 MCU 和外部的傳輸媒介)

二、實(shí)現(xiàn)的功能

MCU 設(shè)備上的 OTA 升級(jí)可理解為 IAP (In Application Programming) 技術(shù), MCU 通過(guò)外設(shè)接口(如 UART 、 IIC 、 SPI 、 CANUSB 等接口),連接具備聯(lián)網(wǎng)能力的模塊、器件、設(shè)備(以下統(tǒng)稱(chēng)上位機(jī))。上位機(jī)從服務(wù)器上拉取固件包,再將固件包以約定的通訊協(xié)議,經(jīng)由通訊接口發(fā)送至 MCU ,由 MCU 負(fù)責(zé)固件的解析、解密、存儲(chǔ)、更新等操作,以完成設(shè)備固件更新的功能。需要注意的是,example提供的示例不基于文件系統(tǒng),而是通過(guò)對(duì) Flash 劃分為不同的功能區(qū)域完成固件的更新。

本組件實(shí)現(xiàn)了以下功能:

固件包完整性檢查:自動(dòng)檢測(cè)固件 CRC 值,保證固件數(shù)據(jù)的可靠性。

固件加密:支持 AES256 加密算法,提高固件的安全性。

APP 完整性檢查:支持 APP 運(yùn)行前進(jìn)行完整性檢查,以確認(rèn)運(yùn)行的固件無(wú)數(shù)據(jù)缺陷。

斷電保護(hù):當(dāng)固件更新過(guò)程中(含下載、解密、更新等過(guò)程),任何一個(gè)環(huán)節(jié)斷電,設(shè)備再次上電時(shí),依然能確保有可用的固件。(需配置為至少雙分區(qū))

固件水印檢查:可檢測(cè)固件包是否攜帶了特殊的水印,確認(rèn)非第三方或非匹配的固件包。

固件自動(dòng)更新:當(dāng) download 或 factory 分區(qū)有可用的固件,且 APP 分區(qū)為空或 APP 分區(qū)不是最新版本的固件時(shí),可配置為自動(dòng)開(kāi)始更新。

恢復(fù)出廠設(shè)置:factory 分區(qū)存放穩(wěn)定版的固件,當(dāng)設(shè)備需要恢復(fù)出廠設(shè)置時(shí),該固件會(huì)被更新至 APP 分區(qū)。

無(wú)須 deinit :我們知道,固件更新完畢后從 bootloader 跳轉(zhuǎn)至 APP 前需要對(duì)所用的外設(shè)進(jìn)行 deinit ,恢復(fù)至上電時(shí)的初始狀態(tài)。本組件的 bootloader 包含了下載器的功能,當(dāng)使用復(fù)雜的外設(shè)收取固件包時(shí), deinit 也將變得復(fù)雜,甚至很難排除對(duì) APP 的影響。為此,本組件采用了再入 bootloader 的方式,給 APP 提供一個(gè)相當(dāng)于剛上電的外設(shè)環(huán)境,免去了 deinit 的代碼。

功能可裁剪:本組件通過(guò)功能裁剪可實(shí)現(xiàn)單分區(qū)、雙分區(qū)、三分區(qū)的方案切換、是否配置解密組件、是否自動(dòng)更新 APP 、是否檢查 APP 完整性、是否使用 SPI Flash (待實(shí)現(xiàn))。

固件存放至 SPI flash :本組件可通過(guò)user_config.h配置 download 分區(qū)和 factory 分區(qū)的所在位置為片內(nèi) flash 或 SPI flash ,使用了 SFUD (Serial Flash Universal Driver)作為 SPI flash 的底層驅(qū)動(dòng)庫(kù)。若使用的 SPI flash 支持 SFDP (Serial Flash Discovable Parameters),則可在不修改任何源代碼的情況下更換其它品牌型號(hào)的 SPI flash 。若不支持 SFDP ,SFUD 中已有對(duì)應(yīng) SPI flash 參數(shù)表的話(huà),也可做到在不修改任何源代碼的情況下更換其它品牌型號(hào)的 SPI flash 。

?三、 bootloader 架構(gòu)

(一)軟件架構(gòu)

c6714ed4-84b3-11ed-bfe3-dac502259ad0.png

硬件層描述的是運(yùn)算器件和邏輯器件,如CPU、ADC、TIMER、各類(lèi)IC等,是所有軟件組件的硬件基礎(chǔ),是軟件邏輯的最終底層實(shí)現(xiàn)。

硬件抽象層是位于驅(qū)動(dòng)與硬件電路之間的接口層,將硬件抽象化。它隱藏了特定平臺(tái)的硬件接口細(xì)節(jié),為驅(qū)動(dòng)層提供抽象化的硬件接口,使其具有硬件無(wú)關(guān)性。

驅(qū)動(dòng)層通過(guò)調(diào)用硬件抽象層的開(kāi)放接口,實(shí)現(xiàn)一定的邏輯功能后封裝,提供給上層軟件調(diào)用。

數(shù)據(jù)傳輸層負(fù)責(zé)收發(fā)數(shù)據(jù),對(duì)外開(kāi)放的是數(shù)據(jù)發(fā)送與接收相關(guān)的接口,屏蔽了通訊接口的邏輯代碼,使其易于修改為其他類(lèi)型的通訊接口。

協(xié)議析構(gòu)層將調(diào)用數(shù)據(jù)傳輸層的數(shù)據(jù)收發(fā)接口進(jìn)行封包發(fā)送與收包解析,通過(guò)實(shí)現(xiàn)用戶(hù)的自定義協(xié)議,完成對(duì)數(shù)據(jù)的構(gòu)造和解析。

應(yīng)用層負(fù)責(zé)業(yè)務(wù)邏輯代碼的實(shí)現(xiàn),通過(guò)調(diào)用其他層封裝的接口,完成頂層邏輯功能。

?

(二)文件架構(gòu)

文件 功能描述
main.c 由 STM32CubeMX 自動(dòng)生成,負(fù)責(zé)外設(shè)的初始化
user_config.h 用戶(hù)配置文件,用于裁剪 OTA 組件的功能
app_config.h 應(yīng)用配置文件,配置代碼工程的一些運(yùn)行選項(xiàng)
app.c 應(yīng)用層,負(fù)責(zé)業(yè)務(wù)邏輯代碼的實(shí)現(xiàn)
firmware_manage.c 固件的管理接口層,提供了固件的所有操作接口
protocol_parser.c 協(xié)議析構(gòu)層,實(shí)現(xiàn)協(xié)議的解包和封包
data_transfer.c 數(shù)據(jù)傳輸層,對(duì)外提供數(shù)據(jù)發(fā)送和接收的接口
data_transfer_port.c 數(shù)據(jù)傳輸層的移植位置,便于修改為其它通訊接口
utils.c 工具庫(kù),實(shí)現(xiàn)了一些需要全局調(diào)用的工具性質(zhì)函數(shù)
bsp_config.h BSP 層的配置文件
bsp_common.h BSP 層的公共頭文件
bsp_board.c 實(shí)現(xiàn)板卡的一些自定義的初始化代碼
bsp_uart.c 通用的 UART 驅(qū)動(dòng)庫(kù)
bsp_uart_port.c UART 的接口移植文件
bsp_uart_config.h UART 的配置文件
bsp_timer.c 通用的 timer 驅(qū)動(dòng)庫(kù)
bsp_flash.c flash 的分區(qū)操作抽象接口
fal_stm32f1_flash.c STM32F1 片內(nèi) flash 的寫(xiě)入、讀取和擦除的抽象接口

?

四、 bootloader 的設(shè)計(jì)思路

整個(gè) bootloader 設(shè)計(jì)思路的內(nèi)容較多,本設(shè)計(jì)思路也以 PDF 文檔的形式提供,詳見(jiàn)《bootloader程序設(shè)計(jì)思路》。c69660c0-84b3-11ed-bfe3-dac502259ad0.png

?

五、固件更新流程

根據(jù)配置的分區(qū)方案不同,固件的更新流程會(huì)有些不同,此處僅展示簡(jiǎn)要的更新流程,便于快速理解固件更新的流程,因此屏蔽了很多細(xì)節(jié),更詳細(xì)的內(nèi)容,請(qǐng)閱讀《bootloader程序設(shè)計(jì)思路》文檔和源代碼。

本組件的目的是最大程序的減少 APP 的改動(dòng)量以實(shí)現(xiàn) OTA 的功能,從下圖可知, bootloader 便完成了固件的下載、存放、校驗(yàn)、解密、更新等所有操作, APP 部分所需要做的有以下三件事。

根據(jù) bootloader 占用的大小和 flash 的最小擦除單位,重新設(shè)置 APP 的起始位置和中斷向量表。

增加觸發(fā)進(jìn)入 bootloader 以開(kāi)始固件更新的方式。(如:接收來(lái)自上位機(jī)的更新指令)

設(shè)置一個(gè)更新標(biāo)志位,且這個(gè)標(biāo)志位在 APP 軟復(fù)位進(jìn)入 bootloader 時(shí)仍能被讀取到。(當(dāng)固件更新的方式為上位機(jī)指令控制時(shí),可以不執(zhí)行此步驟)

一般來(lái)說(shuō),通知 bootloader 需要進(jìn)行固件更新的方式有以下兩種:

采用上位機(jī)指令控制的方式,優(yōu)點(diǎn)是 APP 無(wú)須設(shè)置更新標(biāo)志位,即便設(shè)備在收到更新指令后斷電,也可以照常更新。缺點(diǎn)是設(shè)備在上電后, bootloader 需要等待幾秒的時(shí)間(時(shí)間長(zhǎng)短由通訊協(xié)議和上位機(jī)決定),以確認(rèn)是否有來(lái)自上位機(jī)的更新指令,從而決定進(jìn)入固件更新模式亦或跳轉(zhuǎn)至 APP 。

APP 在軟復(fù)位進(jìn)入 bootloader 之前設(shè)置一個(gè)特殊的標(biāo)志位,可以放置在 RAM 、備份寄存器或者外部的非易失性存儲(chǔ)介質(zhì)中(如:EEPROM)。此方式的優(yōu)點(diǎn)是設(shè)備上電時(shí) bootloader 無(wú)須等待和驗(yàn)證是否有固件更新的指令,通過(guò)標(biāo)志位便可決定是否進(jìn)入固件更新模式亦或跳轉(zhuǎn)至 APP ,且利用再入 bootloader 的機(jī)制,可以給 APP 提供一個(gè)干凈的外設(shè)環(huán)境。缺點(diǎn)則是 APP 和 bootloader 都要記錄標(biāo)志位所在的地址空間,且該地址空間不能被挪作他用,不能被意外修改,更不能被編譯器初始化。相較于上個(gè)方案多了要專(zhuān)門(mén)指定該變量的地址并且不被初始化的步驟。若使用的是 RAM 作為記錄標(biāo)志位的介質(zhì),則還有斷電后更新標(biāo)志信息丟失的問(wèn)題。

綜上所述,沒(méi)有完美的方案。本組件支持上述方案二選一,根據(jù)實(shí)際需求進(jìn)行選擇和取舍即可。

由于案例采用了 YModem-1K 協(xié)議,而本組件開(kāi)始固件更新的方式是通過(guò)上位機(jī)發(fā)送指令開(kāi)始的,因此測(cè)試時(shí)若設(shè)備正在運(yùn)行 APP ,需要有個(gè)進(jìn)入 bootloader 的條件,為了便于展示,案例使用了板卡上的功能按鍵作為觸發(fā)條件,模擬上位機(jī)向設(shè)備發(fā)送了更新指令,詳見(jiàn)案例的使用說(shuō)明。

c6a8f88e-84b3-11ed-bfe3-dac502259ad0.png

?

六、固件檢測(cè)與處理機(jī)制

之所以單獨(dú)列出固件的檢測(cè)與處理機(jī)制,是為了方便理解代碼邏輯,此部分也以 PDF 文檔的形式提供,詳見(jiàn)《固件檢測(cè)與處理機(jī)制》。c6ba839c-84b3-11ed-bfe3-dac502259ad0.png

?

七、所需的工具

Firmware_Packager 此工具是必選項(xiàng),負(fù)責(zé)打包 bin 固件,并為 bin 固件添加一個(gè) 96 byte 的表頭,最終生成為 fpk(Firmware Package) 固件包。關(guān)于 96 byte 表頭的具體內(nèi)容,詳見(jiàn)《fpk固件包表頭信息》。由于 YModem-1K 協(xié)議的每包的數(shù)據(jù)大小是 1 Kbyte ,為了便于 bootloader 解包,本工具也將固件表頭擴(kuò)大至了 1 Kbyte ,若自定義的協(xié)議支持可變包長(zhǎng),可將表頭長(zhǎng)度恢復(fù)為 96 byte 。

需要注意的是,本案例選擇了 YModem-1K 協(xié)議,因此若直接采用或測(cè)試example目錄中的案例,固件打包器的表頭尺寸需要選擇 1024 byte 。

YModem_Sender 本工程的 example 采用廣泛使用且公開(kāi)的 YModem-1K 通訊協(xié)議,因此也提供了一個(gè)基于 YModem-1K 協(xié)議的發(fā)送器。由于固件發(fā)送器和通訊協(xié)議是綁定的,實(shí)際使用時(shí),不必綁定此工具,本工程僅為了方便測(cè)試而提供。

注:以上的工具是基于 Qt6 開(kāi)發(fā)的,YModem_Sender 依賴(lài) Qt 的 serial_port 庫(kù),需要自行添加。以上工具作為 OTA 組件的一部分,自然也是開(kāi)源的。運(yùn)行平臺(tái)是 windows ,目前僅在 win10 和 win11 上測(cè)試過(guò)。若需要修改和編譯工程,需要自行安裝 Qt ,請(qǐng)自行搜索安裝教程。

?

八、組件占用的空間

本組件的案例是基于 YModem-1K 協(xié)議及 UART 作為 MCU 與外部的數(shù)據(jù)傳輸媒介,因此不是僅計(jì)算核心代碼部分的占用空間情況,而是整個(gè)可用工程。此數(shù)據(jù)才更有參考意義。以下是幾種方案配置占用的 flash 和 RAM 的大小。

最小占用(單分區(qū) )
Program Size: Code=7796 RO-data=464 RW-data=116 ZI-data=9316
flash: 8376 byte (8.18 kB)
ram: 9432 byte (9.21 kB)

一般占用(單分區(qū) + 解密組件)
Program Size: Code=8574 RO-data=1010 RW-data=116 ZI-data=9572
flash: 9700 byte (9.47 kB)
ram: 9688 byte (9.46 kB)

一般占用(三分區(qū) )
Program Size: Code=8846 RO-data=614 RW-data=116 ZI-data=9348
flash: 9576 byte (9.35 kB)
ram: 9464 byte (9.24 kB)

最大占用(三分區(qū) + 解密組件)
Program Size: Code=9706 RO-data=1158 RW-data=116 ZI-data=9604
flash: 10980 byte (10.72 kB)
ram: 9720 byte (9.49 kB)

因雙分區(qū)和三分區(qū)的占用尺寸相差較小,因此不單獨(dú)列出雙分區(qū)的占用情況。本組件已盡量壓縮尺寸,但由于固件數(shù)據(jù)的處理需要一定的 RAM 開(kāi)銷(xiāo),此部分除非修改每個(gè)分包的最小處理單位(目前是 4096 byte ),否則已經(jīng)很難進(jìn)一步壓縮,請(qǐng)按實(shí)際需求選擇。

?

九、移植說(shuō)明

由于寫(xiě)教程工作量較大,本開(kāi)源工程暫不提供詳細(xì)的移植說(shuō)明文檔。代碼已分層設(shè)計(jì),具備一定的移植性,有經(jīng)驗(yàn)的工程師看example中的示例代碼和本說(shuō)明基本都能自行移植到別的芯片平臺(tái)。這里僅做幾點(diǎn)說(shuō)明。

挖個(gè)坑,后續(xù)有時(shí)間再錄個(gè)移植視頻。

bootloader 部分的核心代碼都在source目錄下,是移植的必需文件。

source/Component和source/BSP目錄下的組件庫(kù)非移植的必選項(xiàng),根據(jù)功能需要進(jìn)行裁剪。

因固件包含表頭,固件寫(xiě)入的 flash 分區(qū)的方式與通訊協(xié)議是強(qiáng)相關(guān)的。若自定義的協(xié)議支持可變長(zhǎng)度,那么建議傳輸?shù)谝粋€(gè)分包時(shí)就是固件表頭的大?。?biāo)準(zhǔn)表頭大小是 96 byte ,本工程因采用 YModem-1K 協(xié)議,固件打包器將表頭擴(kuò)大到了 1 Kbyte,自行修改即可),從而方便 bootloader 解包。

除開(kāi)表頭部分,固件的每個(gè)切包不能超過(guò) 4096 byte ,且 4096 除以每個(gè)切包大小后必須是整數(shù)(如常見(jiàn)的128、256、512、1024、2048等),否則就得修改源碼。

單分區(qū)方案雖然節(jié)省了 flash 空間,但本組件的很多功能和安全特性都無(wú)法使用,除非 flash 實(shí)在受限,否則建議至少使用雙分區(qū)的方案。

??以下是移植的基本步驟

(一)bootloader 部分

建議參考example中的案例進(jìn)行移植。

創(chuàng)建一個(gè)代碼工程,并確保這個(gè)工程可以正常運(yùn)行。(如:控制一個(gè) LED 閃爍)

將source目錄下的文件放到工程目錄下,可隨意放置和命名。

將source目錄下的文件按需添加進(jìn)代碼工程中(source/Component目錄下的組件庫(kù)非移植的必選項(xiàng)),并包含對(duì)應(yīng)的頭文件目錄。

實(shí)現(xiàn)data_transfer_port.c和fal_stm32f1_flash.c內(nèi)的函數(shù),若與案例一致,則無(wú)需修改。

若使用了自定義的通訊協(xié)議,則修改protocol_parser.c和protocol_parser.h,若與案例一致,則無(wú)需修改。

將app.c文件內(nèi)的函數(shù)移植進(jìn)你的應(yīng)用代碼,記得包含app.h,必要時(shí)可修改。

嘗試編譯并解決編譯器報(bào)錯(cuò)的問(wèn)題。(若提示缺失部分文件,可在example目錄中尋找并添加進(jìn)工程,后續(xù)再行修改也是可以的 )

按需求設(shè)置好user_config.h文件,請(qǐng)仔細(xì)閱讀說(shuō)明。

查看app_config.h是否有需要修改的配置項(xiàng)。

若選擇了“使用標(biāo)志位作為固件更新的依據(jù)USING_APP_SET_FLAG_UPDATE”(否則忽略此步驟),且標(biāo)志位放置在 RAM ,則需要配置標(biāo)志位update_flag所在的 RAM 地址,并且配置 IDE 或分散加載文件不對(duì)其進(jìn)行初始化。IDE 配置的方式參考如下圖所示。( 需包含common.h) 其中,宏FIRMWARE_UPDATE_VAR_ADDR在user_config.h中配置,本案例是0x20000000。注意,提供給update_flag的 RAM 區(qū)域一定要勾選NoInit。

/* 固件更新的標(biāo)志位,該標(biāo)志位不能被清零 */
#if (USING_IS_NEED_UPDATE_PROJECT == USING_APP_SET_FLAG_UPDATE)
    #if defined(__IS_COMPILER_ARM_COMPILER_5__)
    volatile uint64_t update_flag __attribute__((at(FIRMWARE_UPDATE_VAR_ADDR), zero_init));

    #elif defined(__IS_COMPILER_ARM_COMPILER_6__)
        #define __INT_TO_STR(x)     #x
        #define INT_TO_STR(x)       __INT_TO_STR(x)
        volatile uint64_t update_flag __attribute__((section(".bss.ARM.__at_" INT_TO_STR(FIRMWARE_UPDATE_VAR_ADDR))));

    #else
        #error "variable placement not supported for this compiler."
    #endif
#endif

c6d3a7b4-84b3-11ed-bfe3-dac502259ad0.png?c6e35cd6-84b3-11ed-bfe3-dac502259ad0.png

工程配置建議選擇 AC6 (雖然本組件也支持 AC5 ,除非不得已,否則建議使用 AC6),選擇C99(如果使用了perf_counter,則需要選擇gnu99) ,優(yōu)化根據(jù)需要選擇即可,建議按下圖所示配置。c6f42ade-84b3-11ed-bfe3-dac502259ad0.png

嘗試再次編譯并解決編譯器提示的問(wèn)題。

若選擇了“使用標(biāo)志位作為固件更新的依據(jù)USING_APP_SET_FLAG_UPDATE”(否則忽略此步驟),編譯通過(guò)后,查看 map 文件是否新增了一個(gè) Region ,并且地址正確,Type為Zero,該區(qū)域?yàn)閁NINIT,若全部符合,則移植成功。c7158616-84b3-11ed-bfe3-dac502259ad0.png

(二)APP 部分

APP 部分的移植相對(duì)簡(jiǎn)單,可直接參考example中的案例。

創(chuàng)建一個(gè)代碼工程,并確保這個(gè)工程可以正常運(yùn)行。(如:控制一個(gè) LED 閃爍)

確定 APP 在 flash 中的地址,需考慮 bootloader 的大小(不能和 bootloader 有沖突),中斷向量表對(duì)地址的要求(如必須是 0x200 的整數(shù)倍), flash 的擦除粒度(因 flash 擦除時(shí)是以扇區(qū)為單位的)。需要注意的是, APP 的地址一定要和 bootloader 的user_config.h中配置的一致,否則無(wú)法運(yùn)行。

在外設(shè)初始化前修改中斷向量表, keil 可采用下圖的方式修改,一勞永逸。

/* 設(shè)置中斷向量表后,開(kāi)啟總中斷 */
extern int Image$$ER_IROM1$$Base;
BSP_INT_DIS();
SCB->VTOR = (uint32_t)&Image$$ER_IROM1$$Base;
BSP_INT_EN();

c7245218-84b3-11ed-bfe3-dac502259ad0.png?
c72d6df8-84b3-11ed-bfe3-dac502259ad0.png

同 bootloader 部分的步驟 10 一致。

增加固件更新時(shí)進(jìn)入 bootloader 的代碼,如上位機(jī)發(fā)送固件更新的指令。(測(cè)試時(shí)可通過(guò)按鍵模擬上位機(jī)發(fā)送固件更新)

在執(zhí)行固件更新的指令的代碼處,添加設(shè)置update_flag標(biāo)志位的值和系統(tǒng)復(fù)位的代碼,如下圖所示。其中,F(xiàn)IRMWARE_UPDATE_MAGIC_WORD的值是0xA5A5A5A5,注意此值要和 bootloader 保持一致 。
若需要通過(guò)標(biāo)志位使用“恢復(fù)出廠固件”的功能,也是同理,對(duì)應(yīng)的宏則是FIRMWARE_RECOVERY_MAGIC_WORD,值為0x5A5A5A5A。

update_flag = FIRMWARE_UPDATE_MAGIC_WORD;
HAL_NVIC_SystemReset();

嘗試再次編譯并解決編譯器提示的問(wèn)題。

同 bootloader 部分的步驟 13 一致。

?

十、一些問(wèn)題的解答

為什么不使用 RTOS ?

為了最大程度的減少 bootloader 占用的 flash 空間,體積越小,組件的適用范圍就越廣。當(dāng)然,本組件是開(kāi)源的,想在 bootloader 里增加 RTOS 或者其它代碼也是可以的。

?

為什么要將 bootloader 設(shè)計(jì)在 flash 的首地址?

我們知道, bootloader 的運(yùn)行環(huán)境最理想的情況是未經(jīng)使用任何外設(shè)的。有些設(shè)計(jì)會(huì)將 APP 放置在 flash 首地址, bootloader 放置在其它地址,優(yōu)點(diǎn)是 APP 無(wú)須設(shè)置 APP 的起始位置和中斷向量表,改動(dòng)量最少,缺點(diǎn)是這種方式很難做到通用,需要在 bootloader 或 APP 中 deinit 所使用的外設(shè),否則固件更新時(shí)可能會(huì)出現(xiàn)各式各樣的異常。實(shí)際上,每個(gè)設(shè)備每個(gè)產(chǎn)品所使用的外設(shè)都是不確定的,為了做到通用,本組件選擇了 bootloader 設(shè)計(jì)在 flash 的首地址的方案。

?

為什么要設(shè)計(jì)成單分區(qū)、雙分區(qū)和三分區(qū)?

現(xiàn)實(shí)情況是,并非所有設(shè)備的 flash 空間都有比較大的富余。有些設(shè)備,無(wú)法使用多個(gè)分區(qū), bootloader + APP 分區(qū)已經(jīng)是極限。而 bootloader 分區(qū)方案不同時(shí),其占用的 flash 大小也不同,為了盡可能的減小 bootloader 的體積,而將分區(qū)設(shè)計(jì)成可配置的方式。

?

什么是 fpk ?

fpk 是 mOTA 組件的固件打包器生成的一種文件,基于 bin 文件,在其頭部增加了一個(gè) 96 byte 表頭后合成的一個(gè)新文件,后綴是.fpk。fpk 取自英文詞語(yǔ) Firmware Package 的縮寫(xiě),意為固件程序包,本組件統(tǒng)稱(chēng)為固件包,而提及固件時(shí),一般指的是 bin 文件。

?

我可以不用固件打包器(Firmware_Packager),直接用 bin 文件進(jìn)行更新嗎?

目前是不能的。本組件提供的功能和安全特性是基于 fpk 表頭和多分區(qū)的方式實(shí)現(xiàn)的,因此需要固件打包器打包固件,生成 fpk 固件包。為了最大程度的使用這些功能和安全特性, bootloader 的更新流程是基于含有表頭的固件包開(kāi)發(fā)的,暫時(shí)不考慮增加不含表頭的更新流程。當(dāng)然,不排除因?yàn)橐蟮娜硕嗔?,我就開(kāi)搞了。

?

十一、引用的第三方庫(kù)

本開(kāi)源工程使用了或?qū)⑹褂靡韵碌牡谌綆?kù),感謝以下優(yōu)秀的代碼庫(kù)(排名不分先后)。

fal(Flash Abstraction Layer) ,RT-Thread 團(tuán)隊(duì)的開(kāi)發(fā)的庫(kù),是對(duì) Flash 及基于 Flash 的分區(qū)進(jìn)行管理、操作的抽象庫(kù)。

SFUD(Serial Flash Universal Driver) 一款使用 JEDEC SFDP 標(biāo)準(zhǔn)的串行 (SPI) Flash 通用驅(qū)動(dòng)庫(kù)。

crc-lib-c為本工程的 CRC32 驗(yàn)算提供了基礎(chǔ)。

tinyAES這是一個(gè)用 C 編寫(xiě)的 AES 、 ECB 、 CTR 和 CBC 加密算法的小型可移植的庫(kù)。

SEGGER RTTSEGGER's Real Time Transfer (RTT) is the proven technology for system monitoring and interactive user I/O in embedded applications. It combines the advantages of SWO and semihosting at very high performance.

perf_counter該庫(kù)利用 SysTick 實(shí)現(xiàn)了代碼的運(yùn)行時(shí)間測(cè)量和通用的 ms 及 us 的延時(shí)函數(shù),且不影響原有的 SysTick 功能和邏輯,若使用的是 AC5 或 AC6 ,可以做到無(wú)感使用,即只需將 perf_counter 庫(kù)添加進(jìn)代碼工程后即可直接使用,無(wú)需調(diào)用 init 之類(lèi)的任何函數(shù)。

開(kāi)源地址: https://gitee.com/DinoHaw/mOTA

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 單片機(jī)
    +關(guān)注

    關(guān)注

    6035

    文章

    44554

    瀏覽量

    634591
  • mcu
    mcu
    +關(guān)注

    關(guān)注

    146

    文章

    17123

    瀏覽量

    350973
  • OTA
    OTA
    +關(guān)注

    關(guān)注

    7

    文章

    578

    瀏覽量

    35193
  • 組件
    +關(guān)注

    關(guān)注

    1

    文章

    512

    瀏覽量

    17813

原文標(biāo)題:針對(duì)單片機(jī)開(kāi)發(fā)的輕量級(jí)OTA組件

文章出處:【微信號(hào):strongerHuang,微信公眾號(hào):strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    國(guó)產(chǎn)芯上運(yùn)行TinyMaxi輕量級(jí)的神經(jīng)網(wǎng)絡(luò)推理庫(kù)-米爾基于芯馳D9國(guó)產(chǎn)商顯板

    TinyMaix是面向單片機(jī)的超輕量級(jí)的神經(jīng)網(wǎng)絡(luò)推理庫(kù),即TinyML推理庫(kù),可以讓你在任意單片機(jī)上運(yùn)行輕量級(jí)深度學(xué)習(xí)模型~開(kāi)源地址:https://github.com/s
    的頭像 發(fā)表于 07-05 08:02 ?1865次閱讀
    國(guó)產(chǎn)芯上運(yùn)行TinyMaxi<b class='flag-5'>輕量級(jí)</b>的神經(jīng)網(wǎng)絡(luò)推理庫(kù)-米爾基于芯馳D9國(guó)產(chǎn)商顯板

    10個(gè)輕量級(jí)框架

    這些輕量級(jí)框架使用HTML5和CSS3標(biāo)準(zhǔn)來(lái)幫助您快速開(kāi)發(fā)跨平臺(tái)的Web移動(dòng)應(yīng)用和網(wǎng)站。
    發(fā)表于 07-17 08:25

    輕量級(jí)深度學(xué)習(xí)網(wǎng)絡(luò)是什么

    輕量級(jí)深度學(xué)習(xí)網(wǎng)絡(luò)概覽
    發(fā)表于 04-23 14:53

    輕量級(jí)的ui框架如何去制作

    原創(chuàng)分享:自制輕量級(jí)單片機(jī)UI框架框架元素用戶(hù)接口代碼開(kāi)源平時(shí)常看csdn,但是從來(lái)沒(méi)有自己寫(xiě)過(guò)。正好這幾天需要用單片機(jī)做一個(gè)簡(jiǎn)易的ui界面,于是自己寫(xiě)了一個(gè)輕量級(jí)的ui框架。發(fā)個(gè)cs
    發(fā)表于 07-14 07:39

    如何自制輕量級(jí)單片機(jī)UI框架?

    如何自制輕量級(jí)單片機(jī)UI框架?
    發(fā)表于 10-14 06:13

    輕量級(jí)工作流引擎架構(gòu)設(shè)計(jì)

    為了克服傳統(tǒng)工作流管理系統(tǒng)的不足,設(shè)計(jì)了工作流管理型系統(tǒng)的原型體系結(jié)構(gòu),搭建了輕量級(jí)工作流引擎的核心架構(gòu),詳細(xì)地介紹了輕量級(jí)工作流引擎各個(gè)組件及功能,該架構(gòu)能根據(jù)
    發(fā)表于 04-12 16:15 ?0次下載
    <b class='flag-5'>輕量級(jí)</b>工作流引擎架構(gòu)設(shè)計(jì)

    Protothreads極輕量級(jí)系統(tǒng)的詳細(xì)資料簡(jiǎn)介

    Protothreads極輕量級(jí)系統(tǒng)用于資源緊張的單片機(jī)。 作者描述Protothreads的特性是:1 沒(méi)有專(zhuān)用的機(jī)器代碼,純C實(shí)現(xiàn);2 不使用容易犯錯(cuò)的跳轉(zhuǎn)指令;3 極小的內(nèi)存占用;4 當(dāng)不當(dāng)做操作系統(tǒng)來(lái)用都行;5 所提供的阻斷等待不需要堆?;蛘遞ull multi-
    發(fā)表于 07-29 17:36 ?6次下載
    Protothreads極<b class='flag-5'>輕量級(jí)</b>系統(tǒng)的詳細(xì)資料簡(jiǎn)介

    原創(chuàng)分享:自制輕量級(jí)單片機(jī)UI框架

    原創(chuàng)分享:自制輕量級(jí)單片機(jī)UI框架框架元素用戶(hù)接口代碼開(kāi)源平時(shí)??碿sdn,但是從來(lái)沒(méi)有自己寫(xiě)過(guò)。正好這幾天需要用單片機(jī)做一個(gè)簡(jiǎn)易的ui界面,于是自己寫(xiě)了一個(gè)輕量級(jí)的ui框架。發(fā)個(gè)cs
    發(fā)表于 11-05 15:20 ?29次下載
    原創(chuàng)分享:自制<b class='flag-5'>輕量級(jí)</b><b class='flag-5'>單片機(jī)</b>UI框架

    STC單片機(jī)在線(xiàn)ISP IAP OTA

    STC單片機(jī)在線(xiàn)ISP IAP OTA
    發(fā)表于 12-03 18:21 ?25次下載
    STC<b class='flag-5'>單片機(jī)</b>在線(xiàn)ISP IAP <b class='flag-5'>OTA</b>

    輕量級(jí)的媒體框架引擎組件HiStreamer

    簡(jiǎn)介 HiStreamer是一個(gè)輕量級(jí)的媒體引擎組件,提供播放、錄制等場(chǎng)景的媒體數(shù)據(jù)流水線(xiàn)處理。 播放場(chǎng)景分為如下幾個(gè)節(jié)點(diǎn):數(shù)據(jù)源讀取、解封裝、解碼、輸出; 錄制場(chǎng)景分為如下幾個(gè)節(jié)點(diǎn):數(shù)據(jù)源讀取
    發(fā)表于 04-06 10:05 ?1次下載

    開(kāi)源嵌入式輕量級(jí)OTA升級(jí)組件-mOTA

    mOTA 中的 m 可意為 mini 、 micro 、 MCU ( Microcontroller Unit ),而 OTA ( Over-the-Air Technology ),即空中下載技術(shù)
    的頭像 發(fā)表于 01-08 10:34 ?2062次閱讀

    分享一個(gè)開(kāi)源輕量級(jí)單片機(jī)命令行交互組件

    在進(jìn)行調(diào)試和維護(hù)時(shí),常常需要與單片機(jī)進(jìn)行交互,獲取、設(shè)置某些參數(shù)或執(zhí)行某些操作,nr_micro_shell正是為滿(mǎn)足這一需求,針對(duì)資源較少的MCU編寫(xiě)的基本命令行工具。
    的頭像 發(fā)表于 01-29 10:43 ?1232次閱讀

    一款專(zhuān)為32位MCU開(kāi)發(fā)OTA組件-mOTA

    今天為大家分享一款開(kāi)源的,專(zhuān)為單片機(jī)開(kāi)發(fā)輕量級(jí) OTA 組件,挺有參考和學(xué)習(xí)意義的。
    的頭像 發(fā)表于 04-04 09:18 ?1018次閱讀

    測(cè)評(píng)分享 | 如何在先楫HPM6750上運(yùn)行輕量級(jí)AI推理框架TinyMaix

    推理框架,官方介紹如下:TinyMaix是面向單片機(jī)的超輕量級(jí)的神經(jīng)網(wǎng)絡(luò)推理庫(kù),即TinyML推理庫(kù),可以讓你在任意單片機(jī)上運(yùn)行輕量級(jí)深度學(xué)習(xí)模型。甚至在Ardui
    的頭像 發(fā)表于 12-12 17:57 ?1567次閱讀
    測(cè)評(píng)分享 | 如何在先楫HPM6750上運(yùn)行<b class='flag-5'>輕量級(jí)</b>AI推理框架TinyMaix

    分享一個(gè)適合單片機(jī)輕量級(jí)日志庫(kù)

    單片機(jī)項(xiàng)目在很多時(shí)候都需要調(diào)試,通過(guò)日志診斷bug是常見(jiàn)的一種調(diào)試方法。
    的頭像 發(fā)表于 09-06 09:23 ?1480次閱讀
    分享一個(gè)適合<b class='flag-5'>單片機(jī)</b>的<b class='flag-5'>輕量級(jí)</b>日志庫(kù)
    RM新时代网站-首页