在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

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

3天內不再提示

求一種基于U盤拖拽更新固件的解決方案

痞子衡嵌入式 ? 來源:安德魯的設計筆記本 ? 2023-09-20 09:16 ? 次閱讀

引言

我們在向一些非專業開發者發放開發板時,有時對方沒有調試器,開發者就無法下載體驗在后續發布支持新功能的固件。并且,對于非專業開發者的用戶來說,僅僅是體驗新功能,而不介入開發工作,專門搭建一套開發環境,性價比實在不高。即使有調試器硬件,在不同操作系統平臺上,還需要安裝專門的工具軟件配合工作,才能實現下載固件的功能,操作比較繁瑣。為了簡化下載固件的操作,本例使用MM32F5270微控制器,基于芯片自帶的USB外設,實現了一個基于U盤拖拽更新固件的解決方案。我期望實現的結果是:

將開發板同PC連接后,PC將識別出一個U盤

可將開發板的固件(bin 格式)文件拖拽存放至該U盤中

復位開發板后,開發板能夠執行新的固件程序

相對于板載帶有U盤拖拽下載功能的daplink方案,本例節約了一個專門運行daplink程序的芯片,利用微控制器自帶的USB外設直接建立同PC的連接,更可有機會被實現成ROM,固化在芯片內部。

原理

MM32F5270片內集成了256KB Flash,但可通過QSPI接口外擴spiflash存儲設備,并可在外擴spiflash中執行程序(XIP)。本例實際將運行bootloader的片內Flash當做BOOT ROM,而將可執行程序的固件存放在對接的spiflash存儲介質中。當芯片上電后,通過一些外部控制手段(例如使用一個按鍵選擇啟動模式),先運行帶有USB功能的bootloader程序,由bootloader的程序將芯片模擬成U盤(U盤的物理存儲空間位于外擴spiflash的后半段)。PC可以看到模擬U盤中的現存文件,也可以向其中拖拽新文件。當拖拽新文件后,bootloader程序會繼續將新文件的程序內容復制到程序的執行區域,覆蓋掉之前的程序,然后再跳轉到程序的執行區域執行程序。

這里專門使用一塊物理存儲區域(spiflash存儲器的后半段)的原因是,USB協議棧模擬U盤時,對文件系統的管理操作全部交由PC完成,這就意味著,PC向模擬U盤發送包含文件內容的數據包時,不一定是按照物理上的先后順序發送的,微控制器端難以通過數據包本身解析出數據包的先后順序。但是,bootloader向程序執行區域復制可執行程序的內容必須是順序且連續的。PC在同U盤的通信過程中,數據包之間的內容可能不連續,但最終發送完成的文件內容一定是完整的。因此,這里使用使用了一個能包含整個固件文件大小的區域作為緩沖區,先緩沖下來整個完整的文件,然后再將完整的文件內容按順序復制到程序的可執行區域。

理想情況下,如果能用一塊RAM作為整個文件的緩沖區,通過U盤拖拽下載過程將會非常快。但本例中使用spiflash作為緩沖區,雖然擦除spiflash并向其寫入數據需要花費更多的時間,但能容納更大的程序文件。

如果芯片內部集成足夠大的片內Flash,也可以不依賴外擴spiflash,對內部的Flash做分區,分別作為bootloader、運行程序及文件緩存的存儲區。

實現

硬件相關

本例使用BIRD-F5270開發板,開發板基本情況如下:

晶振 12MHz

使用QSPI接口對接外擴spiflash存儲芯片FM25Q16(2MB Flash),引腳與MM32F5280片內合封所使用的引腳保持一致:

QSPI_NSS - PF6

QSPI_SCK - PG7

QSPI_D0 - PG6

QSPI_D1 - PF8

QSPI_D2 - PF10

QSPI_D3 - PG8

USB 引腳

USB_DP - PA12

USB_DM - PA11

按鍵引腳

SW1 - RESET

SW2 - BOOT0

SW3 - PA0

軟件相關

啟動到2nd bootloader

芯片上電復位后,默認是直接執行到用戶程序中,但也可以通過指定的手段改為執行bootloader,執行U盤程序。本例使用一個按鍵,綁定到一個指定的GPIO輸入(BOOT引腳),芯片在啟動過程中判定啟動模式:默認啟動到用戶程序,當按鍵按下時,啟動到帶有U盤程序的bootloader。

MM32F5芯片自帶的BOOT0引腳雖然在微控制器復位后可作為普通GPIO使用,但可能會將芯片引導到芯片內部已經固化到ROM中的bootloader程序中,因此不適合作為2nd bootloader的BOOT引腳。BIRD-F5270開發板上除RESET和BOOT0 之外,還有PA0引腳實現按鍵(SW3)功能,可作為2nd bootloader中的BOOT引腳。

當 SW3 被按下時,PA0 為低電平,可執行 U 盤任務,當 SW3 松開時,PA0 為高電平,可執行跳轉程序的任務,具體實現代碼如下:

/*readgpiopinlevel,selectbootmode.*/
if(GPIO_ReadInDataBit(BOARD_BTN_PORT,BOARD_BTN_PIN))
{
/*updateapp&run.*/
jump_to_app();
}
else
{
/*runusbmsctask.*/
msc_task();
}

/*cannotrunhere.*/
while(1)
{}

基于USB外設模擬U盤

MM32F5270微控制器集成了USB外設,配合TinyUSB協議棧,可模擬U盤(MSC設備)。

當運行模擬U盤的程序時,需要指定一塊存儲區域作為U盤的存儲空間,在本例中,將外擴的spiflash存儲區域一分為二,前半部分作為執行程序區域,存儲需要執行的應用程序,后半部分作為U盤的物理存儲空間,將用于緩存用戶通過拖拽方式下載的固件。

注意,spiflash作為U盤的存儲介質時需要解決一個問題,spiflash的最小擦除塊大小是4KB,而U盤設備對存儲介質的擦除塊大小是512B,擦除塊大小不匹配。該問題有兩種解法:

每次修改spiflash前,先將包含目標操作空間的4KB大小的數據塊讀取數據到RAM中緩存,修改指定位置的數據內容后,擦除spiflash中對應的整塊,再將修改后的數據塊寫入到spiflash中。

每次修改spiflash前,先將包含目標操作空間的4KB大小的數據塊讀取數據到RAM中緩存,修改指定位置的數據內容后,暫不寫回到spiflash中。如果接下來要寫入的數據仍在該塊中,則繼續寫入RAM緩存。只有當將要新寫入的數據不在緩存的數據塊中時,才寫回最近緩存的數據塊,并讀出新的數據塊到RAM緩存中。另外,每次在寫操作之后的讀操作,也都會重新清空RAM緩存中的數據。

第一種方法簡單易實現,但會頻繁擦寫spiflash,消耗存儲器件的壽命。第二種方法相當于實現了一個cache機制,操作行為較為復雜。當前暫時選擇第一種做法,先驗證原理,如果后續考慮將這個帶U盤功能的bootloader集成到芯片內部,到時也可以專門集成一塊以512B作為操作單元的dflash作為固件的緩存存儲設備。

運行TinyUSB協議棧的程序中,在執行MSC任務時,會執行對spiflash存儲設備進行讀寫操作的回調函數,如下:

從spiflash讀數據:

//CallbackinvokedwhenreceivedREAD10command.
//Copydisk'sdatatobuffer(uptobufsize)andreturnnumberofcopiedbytes.
int32_ttud_msc_read10_cb(uint8_tlun,uint32_tlba,uint32_toffset,void*buffer,uint32_tbufsize)
{
(void)lun;

uint8_t*addr=(uint8_t*)(BOARD_MEM_BASE+lba*512+offset);
memcpy(buffer,addr,bufsize);

returnbufsize;
}

向spiflash寫數據:

staticuint8_tflash_buf[4096];

//CallbackinvokedwhenreceivedWRITE10command.
//Processdatainbuffertodisk'sstorageandreturnnumberofwrittenbytes
int32_ttud_msc_write10_cb(uint8_tlun,uint32_tlba,uint32_toffset,uint8_t*buffer,uint32_tbufsize)
{
(void)lun;

/*readthe4Ksectorfromspiflashtolocalbuff.*/
uint8_t*flash_addr=(uint8_t*)((BOARD_MEM_BASE+lba*512)&0xFFFFF000);
memcpy(flash_buf,flash_addr,4096);
/*erasethesectorinspiflash.*/
BOARD_EraseSector4KB((uint32_t)flash_addr);
/*writethenewdataintolocalbuff.*/
uint8_t*block=flash_buf+((lba*512)&0xFFF)+offset;
memcpy(block,buffer,bufsize);
/*writethedatafromlocalbufftospiflash.*/
BOARD_WriteSector4KB((uint32_t)flash_addr,flash_buf);

returnbufsize;
}

另外,還有一種做法是不需要真實存在的物理存儲空間作為U盤的存儲介質,而是實時解算PC發過來的要存儲在Flash上的數據包,解析其中哪些數據是文件系統相關的信息,哪些數據是文件本身內容。此時,可丟棄文件系統相關的信息,而將文件本身內容按順序存放在spiflash的指定區域。該方法不需要將spiflash空間一分為二,可提高對spiflash的空間利用率,但該實現該方法需要十分熟悉FAT文件系統格式,且萬一電腦未按照指定的序列發數數據時,該方法無法正確解算出文件內容,造成更新固件失敗,因此,在本例中未實現該功能。

判斷是否存在新固件

前文中實現的U盤功能,將包括文件系統信息的新固件儲存在了spiflash的后半段空間中,bootloader程序要讀取新固件中的內容也需要能夠操作文件系統,本例中為bootloader程序性集成了嵌入式系統上常見的文件系統組件為 FatFs(http://elm-chan.org/fsw/ff/00index_e.html)

本項目中,僅需要 FatFs 實現文件的讀功能,不需要對文件進行寫操作,因此只需要在適配接口上實現讀操作即可, 配置文件ff_conf.h中配置宏選項 FF_FS_READONLY 的值為1。然后在diskio.c文件中適配文件系統對具體物理介質的讀操作函數disk_read()如下:

DRESULTdisk_read(
BYTEpdrv,/*Physicaldrivenmubertoidentifythedrive*/
BYTE*buff,/*Databuffertostorereaddata*/
LBA_tsector,/*StartsectorinLBA*/
UINTcount/*Numberofsectorstoread*/
)
{
(void)pdrv;

BYTE*flash_addr=(BYTE*)(BOARD_MEM_BASE+sector*FF_MAX_SS);
memcpy(buff,flash_addr,count*FF_MAX_SS);

return0;
}

如何在文件系統中的眾多文件中識別微控制器可執行程序的固件呢?本例采用通過文件名來確定是否為固件。

通過 FatFs 嘗試打開一個有宏BOARD_APP_NAME指定名稱的文件,若能成功打開該文件,則說明有可用的固件文件存在。

if(FR_OK==f_open(&file,"0:/"BOARD_APP_NAME,FA_READ))
{
...
}

為什么不能使用任意bin判斷文件作為固件呢?這里考慮到,當文件系統中有多個bin文件時,bootloader 沒有依據判斷哪一個固件為新固件(根據修改日期判斷是否可行,作為可移動存儲設備,會插在不同電腦上,如果不同電腦的時間不一致,則會出現判斷失誤的情況,因此不選擇使用修改日期作為新固件的判斷依據),指定固定文件名的方式判斷固件,最簡單有效,問題最少。

驗證固件的有效性

不少人都應該有這樣的經歷,在網上下載大文件如大型游戲時,往往下載頁面會提供一串 MD5 碼,這段 MD5 碼的作用是驗證下載的文件是否完整,當用戶在網上下載大文件完成后,可在 CMD 中使用 certutil -hashfile MD5 指令求出該文件的 MD5 碼,與下載頁面提供的 MD5 進行對比,判斷文件是否下載完整。

MicrosoftWindows[版本10.0.22621.1848]
(c) Microsoft Corporation。保留所有權利。

E:>certutil-hashfileproject.binMD5
MD5的project.bin哈希:
615ca0da12d496b7a8b1bd6c21876a97
CertUtil:-hashfile 命令成功完成。

E:>

嵌入式領域,Arm的MbedTLS加解密算法庫中提供了MD5的計算方法,因此可使用MbedTLS計算MD5,有程序如下:

/*calcmd5.*/
mbedtls_md5_contextmd5_ctx;

mbedtls_md5_init(&md5_ctx);
mbedtls_md5_starts(&md5_ctx);

while(1)
{
UINTbr=0;
f_read(&file,app_buf,sizeof(app_buf),&br);

mbedtls_md5_update(&md5_ctx,app_buf,br);

if(br

除了 MD5 以外,還可以使用如 SHA1,SHA2 或者 SM3 等更高安全等級的散列值算法作為新固件的判斷依據。

復制固件到執行區域

復制固件到執行區域的做法較為簡單,就是使用 f_read() 函數讀取數據,再寫入到spiflash的指定區域即可。

但除了復制固件文件內容本身,其文件的MD5值也要寫入到Flash中。應在寫新固件之前將之前的MD5值擦除,寫新固件完成之后,再將新MD5值寫入,如此一來,MD5除了作為檢查新固件的完整性的方法外,還可作為執行區域固件完整性檢查的重要依據。

本例中,將MD5值存放在片內flash的末尾。

檢查新固件和復制固件到執行區域的代碼如下:

/*checkmd5,themd5lengthis16byte.*/
if(memcmp((uint8_t*)BOARD_MD5_BASE,md5_val,sizeof(md5_val))!=0)
{
/*newfile,update.*/
BOARD_EraseSector4KB(BOARD_MD5_BASE);

uint32_thas_write=0;
while(1)
{
UINTbr=0;
memset(app_buf,0xff,sizeof(app_buf));
f_read(&file,app_buf,sizeof(app_buf),&br);

BOARD_EraseSector4KB(has_write);
BOARD_WriteSector4KB(has_write,app_buf);
has_write+=4096;

if(br

需要使用完整的一個塊存放MD5值,MD5必須保證單獨擦除,單獨寫入。除了MD5以外,該區域還可以可根據需要存放一些固件相關的信息,比如說修改時間,固件大小等信息,充分利用空間。

跳轉執行

跳轉程序需要做的事情包括:恢復系統時鐘,修改中斷向量表位置,復位棧指針,執行應用程序的復位程序等。具體操作如下:

voidjump_to_app(void)
{
...
/*jumptoapp.*/
CLOCK_ResetToDefault();

vtor=(uint32_t*)BOARD_APP_BASE;

__disable_irq();
SCB->VTOR=BOARD_APP_BASE;

__ISB();
__DSB();

__set_MSP(vtor[0]);
__set_PSP(vtor[0]);

__enable_irq();
((void(*)(void))vtor[1])();
}

用戶應用程序

為了配合bootloader正常工作,需要用戶在自己的應用程序需調整以下內容:

在Linker File中指定可執行程序在分塊后的存儲區

避免誤配置GPIO和QSPI導致BOOT按鍵或外擴spiflash失效

本例實現的bootloader,spiflash作為應用程序的執行區域,代碼段的起始位置位于spiflash的起始映射地址0x90000000,不是片內Flash的0x08000000,因此,需要調整Linker中對應的配置如下:

/*---------------------FlashConfiguration----------------------------------
;FlashConfiguration
;FlashBaseAddress<0x0-0xFFFFFFFF:8>
;FlashSize(inBytes)<0x0-0xFFFFFFFF:8>
;
*----------------------------------------------------------------------------*/
#define__ROM_BASE0x90000000
#define__ROM_SIZE0x00100000

若使用spiflash存儲應用程序,bootloader在執行應用程序前就應該將 QSPI 接口和 GPIO 引腳配置好。在用戶應用程序中,如果需要操作QSPI或者bootloader中使用的GPIO,要特別注意避開。

總結

通過USB接口將BIRD-F5270連接電腦,保持SW3按鍵按下時,再按下并松開RESET按鍵,稍后會在PC上看到一個大小約為1MB的U盤,將新編譯好的名為 “project.bin” 的固件文件拖拽存放至該U盤中,然后保持SW3按鍵松開的狀態下再次按下并松開RESET按鍵,稍后即可發現微控制器已經在執行新固件中的應用程序了。

作為下載新固件的 U 盤,還可以存放一些別的文件,供應用程序使用,例如一張圖片,一首音樂,或一段文字,但需要注意的是,應用程序對該文件系統只有讀操作的權限,不能進行寫操作(或者在bootloader中實現安全寫操作的接口,讓應用程序去調用相應的寫操作接口)

known issue

開發板通過 USB 連接電腦,保持 SW3 按鍵按下的狀態,多次快速按下復位鍵,可能會造成文件系統損壞,文件丟失,需重新格式化才能正常使用,其原因是兩次按下復位鍵中間,電腦正在修改 Flash 中的內容,但復位操作打斷了寫操作,造成文件系統損壞。因此需避免快速多次按下復位鍵的操作。這里可考慮使用一個可編程的指示燈,指示芯片內部程序的工作狀態:當拖拽固件文件到芯片時,指示燈快速閃爍;當復制新固件文件到程序運行區域時,指示燈保持常亮;當復制完畢后,指示燈熄滅。僅當指示燈熄滅后,方可重新復位芯片執行新程序。






審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 微控制器
    +關注

    關注

    48

    文章

    7553

    瀏覽量

    151426
  • ROM
    ROM
    +關注

    關注

    4

    文章

    572

    瀏覽量

    85773
  • 調試器
    +關注

    關注

    1

    文章

    305

    瀏覽量

    23741
  • SPI Flash
    +關注

    關注

    1

    文章

    13

    瀏覽量

    10363
  • QSPI接口
    +關注

    關注

    0

    文章

    14

    瀏覽量

    3355

原文標題:定制帶U盤功能的bootloader實現拖拽下載固件

文章出處:【微信號:pzh_mcu,微信公眾號:痞子衡嵌入式】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    一種PCIe接口的視頻采集解決方案

    一種PCIe接口的視頻采集解決方案
    發表于 04-30 06:29

    一種基于ZigBee的駕駛輔助系統解決方案

    一種基于ZigBee的駕駛輔助系統解決方案
    發表于 05-14 06:22

    一種單芯片低功耗藍牙BLE解決方案

    一種單芯片低功耗藍牙BLE解決方案
    發表于 05-21 07:01

    一種射頻開關的解決方案

    一種射頻開關的解決方案
    發表于 05-21 06:46

    一種NXP最新的NFC電子錢包解決方案

    NFC電子錢包總體結構是怎樣構成的?一種NXP最新的NFC電子錢包解決方案
    發表于 05-24 06:44

    一種可網絡化管理和配置機頂盒的網絡解決方案

    一種可網絡化管理和配置機頂盒的網絡解決方案
    發表于 05-25 07:10

    一種基于ARM Cortex-M處理器的音頻解決方案

    一種基于ARM Cortex-M處理器的音頻解決方案
    發表于 06-01 06:32

    一種應對壓電效應失效的電容器解決方案

    一種應對壓電效應失效的電容器解決方案
    發表于 06-08 06:39

    一種STM32仿真調試時復位后需要run多次的解決方案

    一種STM32仿真調試時復位后需要run多次的解決方案
    發表于 12-01 07:11

    一種MCU Specific Package單片機的具體解決方案

    一種MCU Specific Package單片機的具體解決方案
    發表于 12-10 07:46

    一種LCD和LED沖突的解決方案

    一種LCD和LED沖突的解決方案
    發表于 01-25 07:12

    一種用RK818實現電源管理的解決方案

    RK818是什么?一種用RK818實現電源管理的解決方案
    發表于 02-10 06:21

    一種基于RK3288的人臉識別測溫解決方案

    一種基于RK3288的人臉識別測溫解決方案
    發表于 03-03 12:21

    CH32X035實現U固件更新

    CH32X035的開發板上有個USB-A口, 實現U固件更新功能還是比較容易的,廠家有自己的U
    發表于 10-30 17:52

    通過U更新arm程序

    通過U更新arm程序
    發表于 03-21 15:24 ?14次下載
    主站蜘蛛池模板: 欧美成人高清性色生活| 免费高清在线爱做视频| 另类激情网| 天天射天天射天天干| 美女被猛男躁免费视频网站| 在线免费看片| 性欧美高清极品xx| 一区在线视频| 色播图片| 亚洲午夜久久久久国产| 免费看黄色片网站| 色站视频| 亚洲操操操| 亚洲专区一| 激情伦成人综合小说| 四虎官网| 午夜影院免费在线观看| 亚洲网站免费看| 欧美97色| brazzersvideosexhd欧美高清| h视频日本| 四虎影院欧美| 91色在线视频| 亚洲一区亚洲二区| 女人被男人免费播放网站| 久色国产| 亚洲swag精品自拍一区| hs网站在线观看| 一级毛片美国一级j毛片不卡| 欧美一卡二三卡四卡不卡| 女人被狂躁视频免费网站| 久久久香蕉视频| 亚洲wuma| 午夜精品久久久久久久99| 欧美呜巴又大粗又长| 精品国产三级a∨在线| 亚洲操综合| 欧美性爽xxxⅹbbbb| 加勒比精品久久一区二区三区| 五月激情片| 天天透天天射|