STM32單片機實現固件線上升級(IAP)

来源:https://www.cnblogs.com/JXL-Blogs/archive/2023/08/15/17632507.html
-Advertisement-
Play Games

## 固件升級方案綜述 單片機的固件升級方式有很多種, 1、ICP:In Circuit Programing,簡單說就是在單片機開發時使用燒錄器升級程式,比如使用J-Link燒錄單片機程式。 2、ISP:In System Programing,在單片機內部實現了基於通信介面(如串口、I2C、SP ...


固件升級方案綜述

單片機的固件升級方式有很多種,
1、ICP:In Circuit Programing,簡單說就是在單片機開發時使用燒錄器升級程式,比如使用J-Link燒錄單片機程式。
2、ISP:In System Programing,在單片機內部實現了基於通信介面(如串口、I2C、SPI等等)的FLASH引導程式,配合廠家提供的燒錄軟體工具或自行開發的軟體實現程式燒錄。
3、IAP:In applicating Programing,是指單片機程式開發好之後在運行過程中由外部用戶發起的線上升級,這種升級方式一般由用戶自行設計升級方案,方案靈活性和自由度較高,在智能家居、汽車電子、物聯網設備中常用的OTA(Over The Air)即空中下載技術原理也與之類似。
本文以STM32單片機為例介紹了IAP的設計原理。

劃分FALSH存儲區域

在STM32系列單片機中,程式存儲在內部FLASH中,按照不同的單片機型號FLASH大小有所不同,有64KB、128KB、512KB等等。以STM32F407VET6系列單片機為例,內置FLASH大小為512KB,存儲地址為0x08000000-0x0807FFFF。單片機每次程式複位時從0x08000000的位置開始執行主程式,如果不做IAP則這512KB空間都可以用來存儲用戶編寫的APP程式。
若要實現IAP功能則必須將FLASH空間劃分為幾個部分,每部分都存儲一個可以獨立運行的程式文件(可以理解為幾個獨立的單片機工程):
1、引導程式,每次複位時程式預設執行此程式,在接下來的執行過程中可以跳轉到用戶編寫的程式,因此這部分程式是固化在以0x08000000為起始的區域中。在引導程式中可以對電路系統作出一些自檢和初始化檢查的工作,因此該程式又稱為bootloader或boot程式,需要註意的是在設計bootloader時要提前規定好程式空間的大小,比如規定程式存儲區域為0x08000000-0x8007FFF,則bootlader程式存儲空間為32KB,編寫boot程式時要註意這一點
2、用戶需要升級的新程式,這部分包含了用戶的業務代碼,複雜的運算邏輯和演算法實現均在這一部分完成,稱為APP程式,該部分程式一般存儲在bootloader區域之後的FLASH中。用一個不是特別恰當的例子類比bootloader和APP:bootloader相當於電腦組裝時的BIOS,APP則相當於操作系統,電腦開機時首先運行BIOS,完成後跳轉運行到操作系統。
3、升級之前的老版APP備份。這部分相當於電腦系統更新前對老系統的備份,一旦在升級過程中發生錯誤需要還原到備份系統,防止系統升級失敗成磚。同樣的APP與APP備份將剩餘的FLASH平分,以上述booloader為例,APP程式及其備份所占區域為:(512-32)/2=240KB,因此編寫的APP程式編譯後的占用的FLASH空間不得超過240KB,這一點可以通過查驗.map文件確認,對於不同FLASH大小的晶元可以類比以上計算方法確認自己的程式大小上限(在此插入一句,改變編譯器的優化等級可以改變最後的程式大小,但是高的優化等級對程式編寫規範要求更高,因此優化等級應該在一開始設計APP之前就確定好,中途變更會帶來不可預測的問題)。
以STM32F407VET6單片機為例劃分後的FALSH存儲框圖如下所示:

bootlader設計

根據上面的描述,bootloader主要有完成以下功能:
1、系統自檢
2、實現APP程式跳轉
3、升級過程中接收APP文件並存儲到對應的FLASH區域
功能1、3對於不同的系統要求不同,自檢的內容以及實現文件傳輸的物理層介面和鏈路協議不同,不在此過多描述。下麵主要給出APP跳轉的部分代碼:

#define  APP_ADDR     0x08008000    //應用程式起始地址 
typedef  void (*pFunction)(void);   //重定義pFunction為void(*)(void)函數指針類型
void jump(void)
{
	uint32_t      APP_ADDR_Buff=0;   //緩存APP地址數值
	uint32_t      APP_ADDR_Value=0;  //APP地址的內容
	uint32_t     Jump_ADDR;        //跳轉的目標地址
	pFunction    Jump_APP;        //跳轉的目標函數指針
	APP_ADDR_Buff = APPLICATION_ADDRESS; //用戶程式的首地址
	APP_ADDR_Value = (*(volatile uint32_t*)APP_ADDR_Buff);//取出首地址裡面的值
	if (( APP_ADDR_Value & 0x2FFE0000 ) == 0x20000000) //判斷APP首地址裡面存的棧頂地址值是否合法
	{
			DISABLE_INTERRUPTS(); //關總中斷,使用不同的庫寫法不同,不可直接複製
			RCC_DeInit();//將外設RCC寄存器重設為預設值,使用不同的庫寫法不同,不可直接複製
			Jump_ADDR = *(volatile uint32_t*)(APP_ADDR_Buff + 4);//APP起始地址第二個字為程式開始地址(新程式複位地址)
		    //指針函數指向用戶程式地址,也就是PC指針goto到用戶程式起始地址
			Jump_APP = (pFunction)Jump_ADDR; //取出程式地址給指針函數
			__set_MSP(*(volatile uint32_t*)APP_ADDR_Buff);    //初始化APP的堆棧指針 
			Jump_APP();     //執行指針函數,實現程式跳轉
	}
    else
    {
        ErrorHandle();  //拋出異常
    }
}
int main(void)
{

	SystemInit();//系統時鐘初始化
	SYSInit();  //系統初始化
	delay_ms(200);	
    if(ReadProgramAPPFlag())  //如果需要更新APP
    {
        APP_FlashWrite(); //接收APP文件數據,並將APP程式存儲到指定位置
        if(APP_Check())   //APP文件校驗通過,將新的APP程式更新到備份區域
            APP_Backup(); 
        else			 //否則恢復備份區
            APP_Restore();
        ResetProgramAPPFlag();  //對完成升級的標誌複位
    }
    jump();    //正常情況下運行到這一步時APP區域已經正確寫入程式文件
	while(1);	  
}

其中ReadProgramDoneFlag()是判斷程式應該是先接收升級文件再跳轉還是直接跳轉的標誌,在APP中如果有升級需求則對這個標誌置位,在bootloader中完成文件接收之後對標誌複位,需要註意的時這個標誌位不是全局變數也不是局部變數,要保證程式跳轉,初始化堆棧之後這個標誌的值不受影響,因此該標誌變數最佳選擇是寫在外部EEPROM或內置FLASH中,讀寫標誌的操作其實是對EEPROM或FLASH的讀寫。

編寫APP程式

APP程式中實現了用戶的業務代碼,和由APP跳轉回bootloader的邏輯,實際的操作還是對上文中程式存儲Flag的讀寫,這部分邏輯實現的流程圖如下圖所示:

由於APP程式對應的是另外一個工程文件,因此在工程設置中要將FLASH的偏移地址向下移動,空出bootlader的區域,比如上文中bootloader區域是0x08000000-0x08008000,因此APP工程的FLASH起始地址是0x8008000,偏移量是0x8000,這一點非常重要。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • # 數據安全之資料庫欄位加解密檢索和前端返回脫敏?看看我這個最強解決方案 ## 前言 數據安全一直是我們老生常談的話題了,隨著國產化的日漸推進和數字化信息改革,數據安全越來越被人們所重視。資料庫作為存儲、管理和檢索數據的核心基礎設施,其中可能包含著大量的敏感信息,如個人手機號、身份證號碼、銀行賬戶、 ...
  • TPTABP採用ABP6.0微服務架構。TPTABP擁有更強大的許可權系統,許可權可控制到按鈕、api級別。ABP本身使用多租戶、模塊化、領域驅動設計、微服務等架構設計, 支持多個ORM切換,支持後臺任務(HangFire,Quartz)集成、 事件匯流排、AutoMapper、審計日誌、數據過濾等基礎設 ...
  • 在項目中有的時候可能會用的畫虛線或者設置線的流動效果,這個時候可能會使用到線控制項。 屬性 說明 描述 X1 起始x軸坐標 X1="10" Y1 起始Y軸坐標 Y1="10" X2 結束X軸坐標 X2="100" Y2 結束Y軸坐標 Y2="100" Stroke 線條顏色 Stroke="Red" ...
  • 開源的git管理工具確實非常方便,相信很多小伙伴工作了一些年都會有自己的代碼庫,有的時候做一個新的項目了,需要使用到以前用過的技術,這個時候在去翻找以前的項目,可能就找不到了,但是吧代碼庫都整理到git上就方便多了,而且有什麼新的代碼或者優化等等都可以在任何地方修改和同步,想想還是很厲害的。 下載安 ...
  • 作為.NET開發者,介面是C#必須掌握的知識點,介面是C#中實現多態和組件間互操作性的關鍵機制之一。 介面是一種抽象的類型,它定義了一組成員(方法、屬性、事件等)的規範,但沒有實現代碼。類可以實現一個或多個介面,以表明它們提供了特定的功能。 以下是每個.NET開發者應該掌握的C#介面知識點: **1 ...
  • ## 前言: 在當今信息化社會,網路數據分析越來越受到重視。而作為開發人員,掌握一門能夠抓取網頁內容的語言顯得尤為重要。在此篇文章中,將分享如何使用 .NET構建網路抓取工具。詳細瞭解如何執行 HTTP 請求來下載要抓取的網頁,然後從其 DOM 樹中選擇 HTML 元素,進行匹配需要的欄位信息,從中 ...
  • ## 引言 深拷貝是指創建一個新對象,該對象的值與原始對象完全相同,但在記憶體中具有不同的地址。這意味著如果您對原始對象進行更改,則不會影響到複製的對象 常見的C#常見的深拷貝方式有以下4類: 1. 各種形式的序列化及反序列化。 2. 通過反射機制獲取該對象的所有欄位和屬性信息。遍歷所有欄位和屬性,遞 ...
  • 本文介紹如何使用Centos伺服器部署Docker和Docker Compose. ### 背景信息 本文中的命令使用的是**root用戶**登錄執行, 若不是root用戶要註意許可權問題. 筆者這裡使用的是阿裡雲伺服器, Linux版本為Centos 7.9, 使用SSH遠程連接到伺服器. ### ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...