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

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

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

分享一種適用于嵌入式單片機的差分升級通用庫

電子工程師筆記 ? 來源:CSDN-風(fēng)吹花中花吹風(fēng) ? 2023-09-15 09:46 ? 次閱讀

1. 什么是差分/增量升級?

借用網(wǎng)上的介紹:適合嵌入式的差分升級又叫增量升級,顧名思義就是通過差分算法將源版本與目標(biāo)版本之間差異的部分提取出來制作成差分包,然后在設(shè)備通過還原算法將差異部分在源版本上進行還原從而升級成目標(biāo)版本的過程。

差分升級方案不僅可以節(jié)省MCU內(nèi)部的資源空間、還可以節(jié)省下載流程及下載和升級過程中的功耗。

也就是說,差分升級是拿以前舊設(shè)備內(nèi)的bin,和當(dāng)前新版本的bin用某種算法算出他們的差異部分,然后在借助壓縮算法,生產(chǎn)一個極其小的差分包,然后將這個差分包下載到設(shè)備中,設(shè)備在根據(jù)解壓算法、差分還原算法,生產(chǎn)一個完整的新版本bin,然后將這個新版本bin刷到執(zhí)行區(qū)執(zhí)行代碼。

差分升級一般來說,可以極大的減少下載量,特別是對于嵌入式STM32單片機來說,可以極大的減少維護成本,因為嵌入式設(shè)備的升級維護一般都是空中ota升級,比如藍牙紅外等,下載速度受到波特率、包長等限制,更新固件包非常的慢,而差分升級可以讓下載的過程極大的縮小。

正常的維護版本,即使改的再多,生成的差分包bin理論上在原bin的5%左右,比如一個300k的bin,改的很多的情況下差分包也不過15k左右,而我實際測試,版本維護平均都在5~10k左右。

2. 差分升級實現(xiàn)原理

差分升級過程:

1、使用舊版本bin文件和新版本bin文件制作差分包

2、將差分包下載到設(shè)備內(nèi)

3、設(shè)備使用差分算法還原出新版本bin

4、設(shè)備將新版本bin進行crc驗證后刷到代碼執(zhí)行區(qū)

5、設(shè)備重啟并以新版本運行

在過程中有2個關(guān)鍵點:

第一:如何使用舊版本bin文件和新版本bin文件制作差分包?

該過程我們使用穩(wěn)定的開源差分算法bsdiff+lzma生成差分包,該算法被大量使用,穩(wěn)定安全,并且我們已在項目中批量使用,經(jīng)過長時間的驗證無任何問題。一般來說,該過程都是使用上位機來完成,嵌入式設(shè)備無需關(guān)心,我們已經(jīng)做好了上位機軟件,可以供大家隨意使用,稍后會進行介紹。

第二:設(shè)備收到差分包后如何還原出新版本的bin文件?

該過程就是我們要講解的重點過程,相對應(yīng)的,嵌入式設(shè)備中,我們依然使用開源差分算法bsdiff+lzma來還原新版本文件,代碼全開源,并且我已做成了庫、抽象出了極簡的接口,移植起來費不了多少功夫。

基本是市場上所有的單片機如stm32、瑞薩、華大、復(fù)旦微等都可以使用,但是有內(nèi)存限制,要求ram至少要10k以上,然后是該庫本身的消耗大概是5k的rom。

3. 關(guān)鍵點一:差分包制作過程

對于差分包的制作,我已經(jīng)開發(fā)好了上位機軟件,界面如下圖所示:

fe15f436-52f6-11ee-a25d-92fbcf53809c.png

上位機這邊主要實現(xiàn)使用開源算法bsdiff制作舊版本bin和新版本bin的差分包,然后在使用lzma壓縮算法來壓縮差分包,最終生成一個差分bin,使用方法上位機界面提示的很清楚,最終效果如下圖所示:

fe65ae18-52f6-11ee-a25d-92fbcf53809c.png

4. 關(guān)鍵點二:嵌入式設(shè)備中差分算法庫的移植(還原差分包)

4.1. 移植開關(guān)算法庫代碼

代碼已開源,地址:

https://gitee.com/qq791314247/mcu_bsdiff_upgrade

整體代碼如下圖所示:

feb4e30c-52f6-11ee-a25d-92fbcf53809c.png

如上圖所示,99%的代碼用戶都不用去關(guān)心,用戶只需要提供一個flash寫入接口即可,也就是該庫給定用戶flash地址、數(shù)據(jù)內(nèi)容指針、數(shù)據(jù)內(nèi)容長度,用戶將該段數(shù)據(jù)寫入到flash即可,移植起來特別簡單,花不了幾分鐘的功夫,這也是我花大力氣抽象接口的原因。

4.2. 使用該庫的流程

4.2.1. 使用庫的接口

對于整個庫的代碼,我們只需要關(guān)心一個接口iap_patch,iap_patch在文件”user_interface.h”中。

ff01d32e-52f6-11ee-a25d-92fbcf53809c.png

該接口介紹也比較清晰,差分包的還原,只需要調(diào)用這一個接口即可。

/**
*@brief用戶使用差分升級時唯一需要關(guān)心的接口
*
*@paramold設(shè)備中執(zhí)行區(qū)代碼所在的地址,用戶可指定flash執(zhí)行區(qū)的地址,方便算法讀出來當(dāng)前
*運行中的代碼
*@paramoldsize設(shè)備中執(zhí)行區(qū)代碼的長度,用戶可在差分包bin頭獲取
*@parampatch設(shè)備中已經(jīng)下載的差分包所在的flash地址,或者ram地址,只要能讓算法讀出來即可
*注意,下載的差分包自帶image_header_t格式的文件頭,真正的差分包需要偏
*移sizeof(image_header_t)的長度
*@parampatchsize設(shè)備中已經(jīng)下載的差分包的長度,用戶可在差分包bin頭獲取
*@paramnewfile新文件的大小,用戶需填入新版本bin的長度,用戶亦可以差分包bin頭獲取
*@returnint然后錯誤碼,0成功,1失敗
*/
externintiap_patch(constuint8_t*old,uint32_toldsize,constuint8_t*patch,
uint32_tpatchsize,uint32_tnewfile);

另外,使用該接口還原時所需要的一些信息可以在差分包文件頭中獲取,上位機在制作差分包時,會自動在差分包的bin頭加上64字節(jié)的文件頭,以便于告訴嵌入式設(shè)備舊/新版本bin文件的CRC校驗、長度等信息。所以用戶在收到差分包頭時,偏移掉這64個字節(jié)的文件頭的地址才是需要給到iap_patch接口的真正的bin文件。

文件頭格式如下代碼,用戶只需要關(guān)心中文注釋的部分,其余的都是預(yù)留的信息。

/*差分包制作時自帶的文件頭信息,用戶只需要關(guān)心中文注釋的部分*/
typedefstructimage_header
{
uint32_tih_magic;/*ImageHeaderMagicNumber*/
uint32_tih_hcrc;/*ImageHeaderCRCChecksum差分包包頭校驗*/
uint32_tih_time;/*ImageCreationTimestamp*/
uint32_tih_size;/*ImageDataSize差分包的大小*/
uint32_tih_load;/*DataLoadAddress上一版本舊文件的大小*/
uint32_tih_ep;/*EntryPointAddress要升級的新文件的大小*/
uint32_tih_dcrc;/*ImageDataCRCChecksum新文件的CRC*/
uint8_tih_os;/*OperatingSystem*/
uint8_tih_arch;/*CPUarchitecture*/
uint8_tih_type;/*ImageType*/
uint8_tih_comp;/*CompressionType*/
uint8_tih_name[IH_NMLEN];/*ImageName*/
uint32_tih_ocrc;/*OldImageDataCRCChecksum上一版本舊文件的CRC*/
}image_header_t;
/*差分包制作時自帶的文件頭信息,用戶只需要關(guān)心中文注釋的部分*/

4.2.2. 接口使用例子

我截取一段我工程中的代碼來講解如何使用該接口還原出新版本bin文件:

#ifdefBSDIFF_UPGRADE
image_header_trecv_head;
uint32_trecv_hcrc;/*接收到的文件頭CRC*/
uint32_tcalculation_crc;/*計算出來的文件頭CRC*/
uint32_tspi_flash_addr=UPGRADE_PROGRAM_ADDR;

memcpy(&recv_head,(uint8_t*)APPLICATION_A,sizeof(image_header_t));
recv_hcrc=BigtoLittle32(recv_head.ih_hcrc);
recv_head.ih_hcrc=0;
calculation_crc=crc32((uint8_t*)&recv_head,sizeof(image_header_t));

if(recv_hcrc==calculation_crc)
{
recv_head.ih_hcrc=recv_hcrc;
recv_head.ih_time=BigtoLittle32(recv_head.ih_time);
recv_head.ih_size=BigtoLittle32(recv_head.ih_size);
recv_head.ih_dcrc=BigtoLittle32(recv_head.ih_dcrc);
recv_head.ih_ocrc=BigtoLittle32(recv_head.ih_ocrc);
/*差分升級包*/
recv_head.ih_hcrc=calculation_crc;
if(crc32((uint8_t*)APPLICATION_RUN,recv_head.ih_load)!=recv_head.ih_ocrc)
{
APP_ERR_PRINT("fileoldcrcerr,calcrc:0X%08X,ih_oldbin_crc:0X%08X,",
crc32((uint8_t*)APPLICATION_RUN,
recv_head.ih_load),recv_head.ih_ocrc);
gotobsdiff_out;
}
RTOS_LOCK();
disable_task_monitoring(ALL_TASK_RUNFLAG_BIT,true);
//flash_erase_sector(UPGRADE_PROGRAM_ADDR,UPGRADE_PROGRAM_PAGE);
recv_hcrc=iap_patch((uint8_t*)APPLICATION_RUN,recv_head.ih_load,
(uint8_t*)(APPLICATION_A+sizeof(image_header_t)),
recv_head.ih_size,UPGRADE_PROGRAM_ADDR);
if(recv_hcrc!=recv_head.ih_ep)
{
APP_ERR_PRINT("iap_patchlenerr.");
APP_ERR_PRINT("iap_patchlen:%lu,new_len:%lu",recv_hcrc,recv_head.ih_ep);
gotobsdiff_out;
}
if(erase_program(APPLICATION_A))
{
APP_ERR_PRINT("Ieraseprogramfailed.");
gotobsdiff_out;
}

current_flash_write_addr=APPLICATION_A;
for(uint32_ti=0;i
審核編輯:湯梓紅                                        
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 單片機
    +關(guān)注

    關(guān)注

    6030

    文章

    44491

    瀏覽量

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

    關(guān)注

    146

    文章

    16900

    瀏覽量

    349950
  • 嵌入式
    +關(guān)注

    關(guān)注

    5060

    文章

    18975

    瀏覽量

    302094
  • STM32
    +關(guān)注

    關(guān)注

    2264

    文章

    10854

    瀏覽量

    354319

原文標(biāo)題:適用于嵌入式的差分升級通用庫!

文章出處:【微信號:電子工程師筆記,微信公眾號:電子工程師筆記】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    一種基于單片機的搶占實時嵌入式操作系統(tǒng)設(shè)計

    一種基于單片機的搶占實時嵌入式操作系統(tǒng)設(shè)計
    發(fā)表于 04-22 12:59

    單片機嵌入式系統(tǒng)的區(qū)別 單片機嵌入式linux區(qū)別

    `在如今高速發(fā)展的社會下,電子信息技術(shù)的更新迭代相當(dāng)迅速,想要不被社會淘汰,就要不斷更新自己的技術(shù)水平。本文簡單分析了單片機嵌入式系統(tǒng)的聯(lián)系、組成結(jié)構(gòu)對比等基礎(chǔ)知識,并列舉了幾種適用于PIC18F
    發(fā)表于 03-16 16:22

    到底什么是嵌入式?什么是單片機?

    系統(tǒng)、定時器/計數(shù)器等功能,塞進塊硅片上,變成個超小型的計算機。這么說來,單片機不就是嵌入式系統(tǒng)?別急,我們往下看。“
    發(fā)表于 05-08 10:35

    什么是嵌入式?什么是單片機

    、定時器/計數(shù)器等功能,塞進塊硅片上,變成個超小型的計算機。這么說來,單片機不就是嵌入式系統(tǒng)?別急,我們往下看。“
    發(fā)表于 05-19 14:25

    如何去實現(xiàn)基于單片機分升級

    分算法有開源的bsdiff,壓縮算法也有開源的單片機就能用的,把這兩個結(jié)合起來放單片機里就可以實現(xiàn)分升級。由于上位
    發(fā)表于 11-19 06:14

    一種適用于嵌入式系統(tǒng)的模塊動態(tài)加載技術(shù)

    嵌入式系統(tǒng)中的模塊動態(tài)加載技術(shù)摘要提出一種適用于嵌入式系統(tǒng)的模塊動態(tài)加載技術(shù),設(shè)計實現(xiàn)簡單,占用資源少,開銷小,并且成功運用于DeltaOS
    發(fā)表于 12-20 06:32

    一種適用于嵌入式數(shù)據(jù)的新索引機制

    由于嵌入式系統(tǒng)具有內(nèi)存資源極為有限和處理器速度不高等特點,因此適用于嵌入式數(shù)據(jù)的索引機制應(yīng)在盡量減少內(nèi)存占用量的基礎(chǔ)上進步提高數(shù)據(jù)操作的
    發(fā)表于 12-22 10:57 ?23次下載

    單片機嵌入式鍵盤接口技術(shù)

    本文介紹一種超小尺寸、防水措施良好的單片機嵌入式鍵盤,作為PC/104CPU模塊專用輸入設(shè)備。其工作原理不僅適用于鍵盤輸入系統(tǒng),同時也適用于
    發(fā)表于 03-25 11:22 ?16次下載

    什么是嵌入式單片機?嵌入式單片機詳情匯總

    嵌入式單片機,即嵌入式微控制器,指以微控制器為核心控制單元的嵌入到對象體系中的專用計算機系統(tǒng),是應(yīng)用十分廣泛的一種
    發(fā)表于 11-13 09:39 ?6044次閱讀

    嵌入式單片機的關(guān)系

    單片機是眾多嵌入式處理器的一種,目前通用的理解是,嵌入式主要是指ARM\DSP等處理器.而嵌入式
    發(fā)表于 10-06 09:59 ?6153次閱讀

    基于單片機分升級

    分算法有開源的bsdiff,壓縮算法也有開源的單片機就能用的,把這兩個結(jié)合起來放單片機里就可以實現(xiàn)分升級。由于上位
    發(fā)表于 11-12 21:06 ?11次下載
    基于<b class='flag-5'>單片機</b>的<b class='flag-5'>差</b><b class='flag-5'>分升級</b>

    單片機嵌入式的區(qū)別

    ,價格低,應(yīng)用領(lǐng)域大多為小家電,終端設(shè)備。 嵌入式片上資源豐富,價格高,應(yīng)用領(lǐng)域廣泛,基本可以適用于任何領(lǐng)域。開發(fā)模式 單片機般都是裸機開發(fā),程序規(guī)模較小,只有在比較高端的芯
    發(fā)表于 11-15 12:36 ?15次下載
    <b class='flag-5'>單片機</b>和<b class='flag-5'>嵌入式</b>的區(qū)別

    自編適用于嵌入式單片機Json封包與解析的程序

    @[TOC]**自編適用于嵌入式單片機Json封包與解析的程序**說明:由于網(wǎng)上提供的標(biāo)準(zhǔn)JSON,對向單片機這類的小設(shè)備占用資源過多,很
    發(fā)表于 12-05 16:51 ?17次下載
    自編<b class='flag-5'>適用于</b><b class='flag-5'>嵌入式</b><b class='flag-5'>單片機</b>Json封包與解析的程序

    "單片機分升級算法(STM32,M0,M3,M4等芯片都適用)"

    "單片機分升級算法(STM32,M0,M3,M4等芯片都適用)"
    發(fā)表于 12-07 14:06 ?24次下載
    "<b class='flag-5'>單片機</b><b class='flag-5'>差</b><b class='flag-5'>分升級</b>算法(STM32,M0,M3,M4等芯片都<b class='flag-5'>適用</b>)"

    基于STM32單片機分升級(增量升級)算法

    DiffIAP應(yīng)用背景隨著目前物聯(lián)網(wǎng),車聯(lián)網(wǎng),智能設(shè)備的增多,需要遠程升級設(shè)備程序的場景增多,以往的IAP升級和OTA升級都是整包升級,bin文件過大導(dǎo)致
    發(fā)表于 12-09 15:51 ?19次下載
    基于STM32<b class='flag-5'>單片機</b>的<b class='flag-5'>差</b><b class='flag-5'>分升級</b>(增量<b class='flag-5'>升級</b>)算法