當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 嵌入式云IOT技術(shù)圈
[導(dǎo)讀]? 本文是博主在學(xué)習(xí)OTA時(shí),up主阿正推薦學(xué)習(xí)的文章,原作者leafguo,寫的非常簡(jiǎn)潔明了,在獲得授權(quán)后整理發(fā)布,可以在文末點(diǎn)擊閱讀原文跳轉(zhuǎn)到原文章。 ? 簡(jiǎn)介 本文主要講解在線升級(jí)(OTA)的基礎(chǔ)知識(shí), 主要是針對(duì)IAP OTA從原理分析,?分區(qū)劃分, 到代碼編寫和實(shí)驗(yàn)

本文是博主在學(xué)習(xí)OTA時(shí),up主阿正推薦學(xué)習(xí)的文章,原作者leafguo,寫的非常簡(jiǎn)潔明了,在獲得授權(quán)后整理發(fā)布,可以在文末點(diǎn)擊閱讀原文跳轉(zhuǎn)到原文章。

簡(jiǎn)介

本文主要講解在線升級(jí)(OTA)的基礎(chǔ)知識(shí), 主要是針對(duì)IAP OTA原理分析分區(qū)劃分, 到代碼編寫實(shí)驗(yàn)驗(yàn)證等過(guò)程闡述這一過(guò)程. 幫助大家加深對(duì)OTA的認(rèn)識(shí).

1. OTA基礎(chǔ)知識(shí)

什么是BootLoader?

BootLoader可以理解成是引導(dǎo)程序, 它的作用是啟動(dòng)正式的App應(yīng)用程序. 換言之, BootLoader是一個(gè)程序, App也是一個(gè)程序,  BootLoader程序是用于啟動(dòng)App程序的.

STM32中的程序在哪兒?

正常情況下, 我們寫的程序都是放在STM32片內(nèi)Flash中(暫不考慮外擴(kuò)Flash). 我們寫的代碼最終會(huì)變成二進(jìn)制文件, 放進(jìn)Flash中 感興趣的話可以在Keil>>>Debug>>>Memory中查看, 右邊Memory窗口存儲(chǔ)的就是代碼

接下來(lái)就可以進(jìn)入正題了.

進(jìn)行分區(qū)

既然我們寫的程序都會(huì)變成二進(jìn)制文件存放到Flash中, 那么我們就可以進(jìn)一步對(duì)我們程序進(jìn)行分區(qū). 我使用的是F103RB-NUCLEO開(kāi)發(fā)板,他的Flash一共128頁(yè), 每頁(yè)1K.見(jiàn)下圖:

以它為例, 我將它分為三個(gè)區(qū).BootLoader區(qū)、 App1區(qū)、 App2區(qū)(備份區(qū))具體劃分如下圖:

  • BootLoader區(qū)存放啟動(dòng)代碼
  • App1區(qū)存放應(yīng)用代碼
  • App2區(qū)存放暫存的升級(jí)代碼

總體流程圖

  • 先執(zhí)行 BootLoader程序, 先去檢查 APP2區(qū)有沒(méi)有程序, 如果有就將App2區(qū)(備份區(qū))的程序拷貝到 App1區(qū), 然后再跳轉(zhuǎn)去執(zhí)行 App1的程序.
  • 然后執(zhí)行 App1程序, 因?yàn)? BootLoaderApp1這兩個(gè)程序的向量表不一樣, 所以跳轉(zhuǎn)到 App1之后第一步是先去更改程序的向量表. 然后再去執(zhí)行其他的應(yīng)用程序.
  • 在應(yīng)用程序里面會(huì)加入程序升級(jí)的部分, 這部分主要工作是拿到升級(jí)程序, 然后將他們放到 App2區(qū)(備份區(qū)), 以便下次啟動(dòng)的時(shí)候通過(guò) BootLoader更新 App1的程序. 流程圖如下圖所示:

2. BootLoader的編寫

本節(jié)主要講解在線升級(jí)(OTA)的BooLoader的編寫,我將以我例程的BootLoader為例, 講解BootLoader(文末會(huì)提供免費(fèi)的代碼下載鏈接),其他的大體上原理都差不多。

流程圖分析

以我例程的BootLoader為例:

我將App2區(qū)的最后一個(gè)字節(jié)(0x0801FFFC)用來(lái)表示App2區(qū)是否有升級(jí)程序, STM32在擦除之后Flash的數(shù)據(jù)存放的都是0xFFFFFFFF, 如果有, 我們將這個(gè)地址存放0xAAAAAAAA. 具體的流程圖見(jiàn)下圖所示

程序編寫和分析

所需STM32的資源有:

  • 發(fā)送USART數(shù)據(jù)和printf重定向
  • Flash的讀寫
  • 程序跳轉(zhuǎn)指令,可以參考如下代碼:
/* 采用匯編設(shè)置棧的值 */
__asm void MSR_MSP (uint32_t ulAddr)
{
MSR MSP, r0 //設(shè)置Main Stack的值
BX r14
}


/* 程序跳轉(zhuǎn)函數(shù) */
typedef void (*Jump_Fun)(void);
void IAP_ExecuteApp (uint32_t App_Addr)
{
Jump_Fun JumpToApp;

if ( ( ( * ( __IO uint32_t * ) App_Addr ) & 0x2FFE0000 ) == 0x20000000 ) //檢查棧頂?shù)刂肥欠窈戏?
{
JumpToApp = (Jump_Fun) * ( __IO uint32_t *)(App_Addr + 4); //用戶代碼區(qū)第二個(gè)字為程序開(kāi)始地址(復(fù)位地址)
MSR_MSP( * ( __IO uint32_t * ) App_Addr ); //初始化APP堆棧指針(用戶代碼區(qū)的第一個(gè)字用于存放棧頂?shù)刂?
JumpToApp(); //跳轉(zhuǎn)到APP.
}
}
  • 在需要跳轉(zhuǎn)的地方執(zhí)行這個(gè)函數(shù)就可以了 IAP_ExecuteApp(Application_1_Addr);
  • 其他的代碼請(qǐng)參考 BootLoader源代碼

3. APP的編寫

本節(jié)主要講解在線升級(jí)(OTA)的App1的編寫以及整個(gè)流程的說(shuō)明,我將以我例程的App為例, 采用Ymodem協(xié)議進(jìn)行串口傳輸,講解App的編寫(后面會(huì)提供免費(fèi)的代碼下載鏈接), 其他的協(xié)議原理大體上都差不多, 都是通過(guò)某種協(xié)議拿到升級(jí)的代碼。

流程圖分析

以我例程的App1為例:

  • 先修改向量表, 因?yàn)楸境绦蚴怯葿ootLoader跳轉(zhuǎn)過(guò)來(lái)的, 不修改向量表后面會(huì)出現(xiàn)問(wèn)題;
  • 打印版本信息, 方便查看不同的App版本;
  • 本例程的升級(jí)程序采用串口的Ymoderm協(xié)議進(jìn)行傳輸bin文件. 具體的流程圖見(jiàn)下圖所示:

程序編寫和分析

所需STM32的資源有:

  • 發(fā)送USART數(shù)據(jù)和printf重定向
  • Flash的讀寫
  • 串口的DMA收發(fā)
  • YModem協(xié)議相關(guān)

Ymodem協(xié)議

  • 百度百科[Ymodem協(xié)議]
  • 具體流程可自行查找相關(guān)文檔, 這兒提供一個(gè)我找到的 XYmodem.pdf(文末和源碼一起提供).
  • Ymodem協(xié)議相關(guān)介紹可參考我的這篇教程 YModem介紹

(https://blog.csdn.net/weixin_41294615/article/details/104652105).

代碼分析

  • 代碼大多數(shù)都是通過(guò)串口實(shí)現(xiàn)Ymodem協(xié)議的接收, 這兒就不詳細(xì)說(shuō)明

  • 后面放了我的源代碼, 詳情請(qǐng)參考我的源代碼.

  • 主函數(shù)添加修改向量表的指令

  • 打印版本信息以及跳轉(zhuǎn)指令

  • YModem相關(guān)的文件接收部分

/**
* @bieaf YModem升級(jí)
*
* @param none
* @return none
*/
void ymodem_fun(void)
{
int i;
if(Get_state()==TO_START)
{
send_command(CCC);
HAL_Delay(1000);
}
if(Rx_Flag) // Receive flag
{
Rx_Flag=0; // clean flag

/* 拷貝 */
temp_len = Rx_Len;
for(i = 0; i < temp_len; i++)
{
temp_buf[i] = Rx_Buf[i];
}

switch(temp_buf[0])
{
case SOH:///<數(shù)據(jù)包開(kāi)始
{
static unsigned char data_state = 0;
static unsigned int app2_size = 0;
if(Check_CRC(temp_buf, temp_len)==1)///< 通過(guò)CRC16校驗(yàn)
{
if((Get_state()==TO_START)&&(temp_buf[1] == 0x00)&&(temp_buf[2] == (unsigned char)(~temp_buf[1])))///< 開(kāi)始
{
printf("> Receive start...\r\n");

Set_state(TO_RECEIVE_DATA);
data_state = 0x01;
send_command(ACK);
send_command(CCC);

/* 擦除App2 */
Erase_page(Application_2_Addr, 40);
}
else if((Get_state()==TO_RECEIVE_END)&&(temp_buf[1] == 0x00)&&(temp_buf[2] == (unsigned char)(~temp_buf[1])))///< 結(jié)束
{
printf("> Receive end...\r\n");

Set_Update_Down();
Set_state(TO_START);
send_command(ACK);
HAL_NVIC_SystemReset();
}
else if((Get_state()==TO_RECEIVE_DATA)&&(temp_buf[1] == data_state)&&(temp_buf[2] == (unsigned char)(~temp_buf[1])))///< 接收數(shù)據(jù)
{
printf("> Receive data bag:%d byte\r\n",data_state * 128);

/* 燒錄程序 */
WriteFlash((Application_2_Addr + (data_state-1) * 128), (uint32_t *)(&temp_buf[3]), 32);
data_state++;

send_command(ACK);
}
}
else
{
printf("> Notpass crc\r\n");
}

}break;
case EOT://數(shù)據(jù)包開(kāi)始
{
if(Get_state()==TO_RECEIVE_DATA)
{
printf("> Receive EOT1...\r\n");

Set_state(TO_RECEIVE_EOT2);
send_command(NACK);
}
else if(Get_state()==TO_RECEIVE_EOT2)
{
printf("> Receive EOT2...\r\n");

Set_state(TO_RECEIVE_END);
send_command(ACK);
send_command(CCC);
}
else
{
printf("> Receive EOT, But error...\r\n");
}
}break;
}
}
}
  • 其中部分函數(shù)未在以上代碼中展現(xiàn), 詳情請(qǐng)參看文末給出的源碼鏈接.

4. 整體測(cè)試

本節(jié)主要對(duì)前三節(jié)的教程做測(cè)試驗(yàn)證 BootLoader + App的升級(jí)功能。

源代碼

BootLoader源代碼和App1源代碼可以在原作者的gitee獲?。?/p>

https://gitee.com/leafguo/leaf_notes/STM32CubeMX/STM32CubeMx_OTA

代碼的下載

  • 由下圖可知兩份代碼的下載區(qū)域是不一樣的,所以他們 「下載的區(qū)域也不一樣」

BootLoader的下載

  • BootLoader的代碼默認(rèn)是最開(kāi)始的所以不需要特別設(shè)置代碼的下載位置
  • 按照下圖, 修改擦除方式為 Erase Sectors, 大小限制在 0X5000(20K)

  • 燒錄代碼
  • 運(yùn)行, 通過(guò)串口1打印輸出, 會(huì)看到以下打印消息
  • 說(shuō)明BootLoader已經(jīng)成功運(yùn)行

App1的下載

  • App1稍微復(fù)雜一點(diǎn), 需要將代碼的起始位置設(shè)置為 0x08005000
  • 同時(shí)也要修改擦除方式為 Erase Sectors, 見(jiàn)下圖

  • 燒錄代碼
  • 運(yùn)行, 通過(guò)串口1打印輸出, 會(huì)看到以下打印消息
  • 說(shuō)明 BootLoader已經(jīng)成功跳轉(zhuǎn)到版本號(hào)為0.0.1的 App1

生成App2的.bin文件

  • Keil如何生成.bin文件, 請(qǐng)參考這篇博文 Keil如何生成.bin文件

https://blog.csdn.net/weixin_41294615/article/details/104656577

  • 修改代碼, 把版本號(hào)改為0.0.2, 并且編譯并且生成.bin文件

  • 生成好之后你會(huì)得到一個(gè).bin結(jié)尾的文件, 這就是我們待會(huì)兒YModem要傳輸?shù)奈募?/p>

使用Xshell進(jìn)行文件傳輸

  • 打開(kāi)Xshell
  • 代碼中, 串口1進(jìn)行調(diào)試信息的打印, 串口2進(jìn)行YModem升級(jí)的
  • 所以使用Xshell打開(kāi)串口2進(jìn)行文件傳輸, 串口1則可以通過(guò)串口調(diào)試助手查看調(diào)試消息
  • 你會(huì)看到App的版本成功升級(jí)到0.0.2了.
  • 如果你到了這一步.
  • 那么恭喜你! 你已經(jīng)能夠使用在線升級(jí)了!

5. 總結(jié)

通過(guò)本幾節(jié)的教程, 想必你已經(jīng)會(huì)使用在線升級(jí)了, 只要原理知道了其他的問(wèn)題都可以迎刃而解了, 除了使用YModem協(xié)議傳輸.bin文件, 你還可以通過(guò)藍(lán)牙, WIFI,等其他協(xié)議傳輸, 只要能夠?qū)?bin文件傳輸過(guò)去, 那其他的部分原理都差不多.

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉