GD32 flash FMC/bootloade操作
GD32的Flash的名字是FMC,BOOT的操作主要基於這些進行實現
.GD32有三種啓動模式,對應的存儲介質均是芯片內置的,他們是:1)用戶閃存=芯片內置的閃存2)SRAM =芯片內置的RAM區,就是內存啦0.3)系統存儲器=芯片內部一塊特定的區域,芯片出廠時在這個區域預置了一段引導程序,就是通常說的ISP程序。這個區域的內容在芯片出廠後沒有人能夠修改或擦除,即它是一個ROM區。 在每個GD32的芯片上都有兩個管腳BOOT1和BOOT0,兩個這管腳在芯片復位時的電平狀態決定了芯片復位後從哪個區域開始執行程序1)BOOT1 = X BOOT0 = 0從用戶閃存啓動,這是正常的工作模式。2)BOOT1 = 0 BOOT0 = 1從系統存儲器啓動,這種模式啓動的程序功能由廠家設置。3) BOOT1 = 1 BOOT0 = 1從內置SRAM啓動,這種模式可用於調試。 要注意的是,一般不使用內置SRAM啓動(BOOT1 = 1 BOOT0 = 1),因爲SRAM 電後數據就丟失。多數情況下SRAM只是在調試時使用,也可以做其他一些用途。如做故障的局部診斷,寫一段小程序加載到SRAM中診斷板上的其他電路,或用此方法讀寫板上的閃存EEPROM或等。還可以通過這種方法解除內部閃存的讀寫保護,當然解除讀寫保護的同時閃光的內容也被自動清除,以防止惡意的軟件拷貝。一般BOOT0和BOOT1跳線都跳到0(地) 在GD32的芯片函數庫gd32f1x0_fmc.c中,我們可以查找到這樣的函數:
/ **
* @brief編程BOOT1選項位。 * @參數OB_BOOT1:法定參數可以是以下值之一: * @arg OB_BOOT1_RESET * @arg OB_BOOT1_SET * @retval FMC狀態:FMC_READY,FMC_BSY,FMC_WRPERR,FMC_PGERR或FMC_TIMEOUT_ERR * / FMC_State FMC_OB_BOOTConfig (uint8_t OB_BOOT1){ FMC_State temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT); if(temp_state == FMC_READY) { / *設置OBPG位* / FMC-> CMR | = FMC_CMR_OBPG; OB-> USER = OB_BOOT1 | 0xEF; / *等待FMC就緒* / temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT); 如果(temp_state!= FMC_TIMEOUT_ERR)
{ / *復位OBPG位* / FMC-> CMR&= ~FMC_CMR_OBPG; } } / *返回FMC狀態* / return temp_state; } 由函數描述我們可以得到,該函數的作用是清空或者重置BOOT1位,他的參數是OB_BOOT1_RESET,OB_BOOT1_SET(在對應的頭文件中進行定義)/ ** @defgroup FMC_Option_Bytes_BOOT1 * @ { * / #define OB_BOOT1_RESET((uint8_t)0x00)/ *!<BOOT1 Reset * / #define OB_BOOT1_SET((uint8_t)0x10)/ *!<BOOT1 Set * / BOOT1和BOOT0的作用是決定程序以哪種方式進入,那麼從GD的startup_gd32f1x0.s中我們可以知道,在0x08000000開始啓動的重映射。這是什麼原因:原因是由於STM32設計的Flash起始地址是在0x0800 0000位置開始的。全部代碼都只能從這裏開始存儲。
理論上,CM3中規定上電後CPU是從0地址開始執行,但是這裏中斷向量表卻被燒寫在0x0800 0000地址裏,那啓動時不會中斷向量表了?既然CM3定下的規矩是從0地址啓動,SMT32當然不能破壞ARM定下的“規矩”,所以它做了一個啓動映射的過程,就是和芯片上總能見到的BOOT0和BOOT1有關了,當選擇從主閃存啓動模式後,芯片一上電,Flash的0x0800 0000地址被映射到0地址處,不影響CM3內核的讀取,所以這時的CM3既可以在0地址處訪問中斷向量表,也可以在0x0800 0000地址處理問中斷向量表,而代碼還是在0x0800 0000地址處存儲的。這就是最難理解的地方,其實,這是基本上所有的ARM芯片採用的啓動映射方法.ARM7,ARM9沒有內部Flash的通常都是這樣做的。
理解上述描述之後,我們來學習一下OTA固件升級原理:
OTA設計升級很重要的一個工作就是首先規劃好閃存區域的佈局,清晰地知道引導程序,應用程序以及下載的的的.bin文件在閃存中放置的位置
OTA固件升級其實就是IAP應用編程,要完成固件升級需要設計兩個程序,一個爲引導加載程序,另外一個爲應用程序。通常我們是在應用程序中建立套接字連接來發起HTTP請求去查詢服務器是否有新的固件並進行下載的,並且在片外的閃存中修改和存儲固件的參數信息,而引導程序的程序主要檢查固件的參數信息並且如果需要就負責將應用程序下載的固件從片外Flash搬運到片內Flash,然後跳到那裏運行1.Bootloader角色主要完成的: 1)讀取固件參數信息; 2)判斷是否需要更新,如果不需要直接跳到應用區域執行;
3)如果需要更新,則將固件搬到應用區域,並且更新固件參數信息(表示已將更新過該固件了),跳到求最後應用程序 角色主要完成的: 1)發送HTTP請求查詢服務器最新固件信息; 2)當前固件做對比,如果發送HTTP請求查詢服務器最新固件信息; 2)當前固件做對比,如果需要更新,就進行下載; 3)將下載的固件寫到規劃好的OTA固件存儲區; 4)更新固件參數回寫片外閃存,最後進行軟件復位; 這裏也相應地首先完成網絡上固件下載的完整性校驗,以確保在網絡下載下來的固件是完整的,然後在寫進OTA固件存儲區域的時候也需要再進行校驗計算,以在引導加載程序在搬運固件時校驗確保完整性。引導程序放置在片內閃存的0x08000000地址,大小爲64K,STM32上設備電後首先跳到裏執行;(主閃存存儲器被選爲啓動區域)2.應用放置在片內的Flash的0x08010000地址; 3.PARAMETER_1和PARAMETER_2(備份用)記錄固件參數信息的區域,它們放在片外的閃存; 4. OTA_TEMP區域爲OTA固件存儲區域,放置片外閃存,應用從網絡下載倉庫文件然後寫到該區域,而引導程序從這個區域搬運固件到應用區域。
從上面可以看出,不管是引導程序還是應用都需要做好片內閃存驅動和片外的閃存驅動來進行閃光操作。 內容參考:HTTPS://blog.csdn.net/yueqian_scut/article/details/ 52804009
.GD32有三種啓動模式,對應的存儲介質均是芯片內置的,他們是:1)用戶閃存=芯片內置的閃存2)SRAM =芯片內置的RAM區,就是內存啦0.3)系統存儲器=芯片內部一塊特定的區域,芯片出廠時在這個區域預置了一段引導程序,就是通常說的ISP程序。這個區域的內容在芯片出廠後沒有人能夠修改或擦除,即它是一個ROM區。 在每個GD32的芯片上都有兩個管腳BOOT1和BOOT0,兩個這管腳在芯片復位時的電平狀態決定了芯片復位後從哪個區域開始執行程序1)BOOT1 = X BOOT0 = 0從用戶閃存啓動,這是正常的工作模式。2)BOOT1 = 0 BOOT0 = 1從系統存儲器啓動,這種模式啓動的程序功能由廠家設置。3) BOOT1 = 1 BOOT0 = 1從內置SRAM啓動,這種模式可用於調試。 要注意的是,一般不使用內置SRAM啓動(BOOT1 = 1 BOOT0 = 1),因爲SRAM 電後數據就丟失。多數情況下SRAM只是在調試時使用,也可以做其他一些用途。如做故障的局部診斷,寫一段小程序加載到SRAM中診斷板上的其他電路,或用此方法讀寫板上的閃存EEPROM或等。還可以通過這種方法解除內部閃存的讀寫保護,當然解除讀寫保護的同時閃光的內容也被自動清除,以防止惡意的軟件拷貝。一般BOOT0和BOOT1跳線都跳到0(地) 在GD32的芯片函數庫gd32f1x0_fmc.c中,我們可以查找到這樣的函數:
/ **
* @brief編程BOOT1選項位。 * @參數OB_BOOT1:法定參數可以是以下值之一: * @arg OB_BOOT1_RESET * @arg OB_BOOT1_SET * @retval FMC狀態:FMC_READY,FMC_BSY,FMC_WRPERR,FMC_PGERR或FMC_TIMEOUT_ERR * / FMC_State FMC_OB_BOOTConfig (uint8_t OB_BOOT1){ FMC_State temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT); if(temp_state == FMC_READY) { / *設置OBPG位* / FMC-> CMR | = FMC_CMR_OBPG; OB-> USER = OB_BOOT1 | 0xEF; / *等待FMC就緒* / temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT); 如果(temp_state!= FMC_TIMEOUT_ERR)
{ / *復位OBPG位* / FMC-> CMR&= ~FMC_CMR_OBPG; } } / *返回FMC狀態* / return temp_state; } 由函數描述我們可以得到,該函數的作用是清空或者重置BOOT1位,他的參數是OB_BOOT1_RESET,OB_BOOT1_SET(在對應的頭文件中進行定義)/ ** @defgroup FMC_Option_Bytes_BOOT1 * @ { * / #define OB_BOOT1_RESET((uint8_t)0x00)/ *!<BOOT1 Reset * / #define OB_BOOT1_SET((uint8_t)0x10)/ *!<BOOT1 Set * / BOOT1和BOOT0的作用是決定程序以哪種方式進入,那麼從GD的startup_gd32f1x0.s中我們可以知道,在0x08000000開始啓動的重映射。這是什麼原因:原因是由於STM32設計的Flash起始地址是在0x0800 0000位置開始的。全部代碼都只能從這裏開始存儲。
理論上,CM3中規定上電後CPU是從0地址開始執行,但是這裏中斷向量表卻被燒寫在0x0800 0000地址裏,那啓動時不會中斷向量表了?既然CM3定下的規矩是從0地址啓動,SMT32當然不能破壞ARM定下的“規矩”,所以它做了一個啓動映射的過程,就是和芯片上總能見到的BOOT0和BOOT1有關了,當選擇從主閃存啓動模式後,芯片一上電,Flash的0x0800 0000地址被映射到0地址處,不影響CM3內核的讀取,所以這時的CM3既可以在0地址處訪問中斷向量表,也可以在0x0800 0000地址處理問中斷向量表,而代碼還是在0x0800 0000地址處存儲的。這就是最難理解的地方,其實,這是基本上所有的ARM芯片採用的啓動映射方法.ARM7,ARM9沒有內部Flash的通常都是這樣做的。
理解上述描述之後,我們來學習一下OTA固件升級原理:
OTA設計升級很重要的一個工作就是首先規劃好閃存區域的佈局,清晰地知道引導程序,應用程序以及下載的的的.bin文件在閃存中放置的位置
OTA固件升級其實就是IAP應用編程,要完成固件升級需要設計兩個程序,一個爲引導加載程序,另外一個爲應用程序。通常我們是在應用程序中建立套接字連接來發起HTTP請求去查詢服務器是否有新的固件並進行下載的,並且在片外的閃存中修改和存儲固件的參數信息,而引導程序的程序主要檢查固件的參數信息並且如果需要就負責將應用程序下載的固件從片外Flash搬運到片內Flash,然後跳到那裏運行1.Bootloader角色主要完成的: 1)讀取固件參數信息; 2)判斷是否需要更新,如果不需要直接跳到應用區域執行;
3)如果需要更新,則將固件搬到應用區域,並且更新固件參數信息(表示已將更新過該固件了),跳到求最後應用程序 角色主要完成的: 1)發送HTTP請求查詢服務器最新固件信息; 2)當前固件做對比,如果發送HTTP請求查詢服務器最新固件信息; 2)當前固件做對比,如果需要更新,就進行下載; 3)將下載的固件寫到規劃好的OTA固件存儲區; 4)更新固件參數回寫片外閃存,最後進行軟件復位; 這裏也相應地首先完成網絡上固件下載的完整性校驗,以確保在網絡下載下來的固件是完整的,然後在寫進OTA固件存儲區域的時候也需要再進行校驗計算,以在引導加載程序在搬運固件時校驗確保完整性。引導程序放置在片內閃存的0x08000000地址,大小爲64K,STM32上設備電後首先跳到裏執行;(主閃存存儲器被選爲啓動區域)2.應用放置在片內的Flash的0x08010000地址; 3.PARAMETER_1和PARAMETER_2(備份用)記錄固件參數信息的區域,它們放在片外的閃存; 4. OTA_TEMP區域爲OTA固件存儲區域,放置片外閃存,應用從網絡下載倉庫文件然後寫到該區域,而引導程序從這個區域搬運固件到應用區域。
從上面可以看出,不管是引導程序還是應用都需要做好片內閃存驅動和片外的閃存驅動來進行閃光操作。 內容參考:HTTPS://blog.csdn.net/yueqian_scut/article/details/ 52804009
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.