本文將根據ST官方Flashprogramming manual,檔案編號:PM0059,講解STM32F207內部Flash編程,
01、概述
這里的flash是指STM32F207內部集成的Flash
Flash存盤器有以下特點
- 最大1M位元組的能力
- 128位,也就是16位元組寬度的資料讀取
- 位元組,半字,字和雙字寫入
- 扇區擦除和批量擦除
存盤器的構成
主要存盤區塊包含4個16K位元組扇區,1個64K位元組扇區和7個128K位元組扇區,
系統存盤器是用于在系統boot模式啟動設備的,這一塊是預留給ST的,包括bootloader程式,boot程式用于通過以下介面對Flash進行編程,USART1、USART3、CAN2、USB OTG FS設備模式(DFU:設備韌體升級),boot程式由ST制造期間撰寫,用于保護防止錯誤寫入和擦除操作,
512OTP(一次性編程)位元組用于用戶資料,OTP區域包含16個附加的位元組,用于鎖定回應的OTP資料,
選項位元組,讀寫保護,BOR水平,軟體/硬體看門狗和復位當設定處于待機和停機狀態,
低功耗模式(參考參考手冊的PWR部分)
對比參考手冊的boot部分
當BOOT0為0是運行主存盤區
當BOOT0為1,BOOT1為0時運行系統存盤區
系統存盤區運行的是ST出廠的bootloader代碼,跳過過了用戶的代碼,如果在應用層代碼鎖定了JTAG管腳(將JTAG管腳用于普通GPIO),我們可以通過修改boot管腳狀態,進入系統存盤中,再進行debug,
02、Flash操作
2.1、讀取
內置的Flash是處于CortexM3的資料總線上的,所以可以在通用地址空間之間尋址,任何32位資料的讀操作都能訪問Flash上的資料,
data32 = *(__IO uint32_t*)Address;
將Address強制轉化為32位整型指標,然后取該指標所指向的地址的值,就得到了Address地址上的32位資料,
2.2、擦除
Flash 擦除操作可針對扇區或整個Flash(批量擦除)執行,執行批量擦除時,不會影響OTP扇區或配置扇區,
扇區擦除步驟
1、檢查FLASH_SR 暫存器中的BSY 位,以確認當前未執行任何Flash 操作
2、在FLASH_CR 暫存器中將SER 位置1 并選擇要擦除的扇區(SNB)(主存盤器塊中的12個扇區之一)
3、將FLASH_CR 暫存器中的STRT 位置1
4、等待BSY 位清零
批量擦除步驟
1、檢查FLASH_SR 暫存器中的BSY 位,以確認當前未執行任何Flash 操作
2、將FLASH_CR 暫存器中的MER 位置1
3、將FLASH_CR 暫存器中的STRT 位置1
4、等待BSY 位清零
ST提供相應的庫函式介面
FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_tVoltageRange)
FLASH_Status FLASH_EraseAllSectors(uint8_tVoltageRange)
??????注意到,有個特殊的引數VoltageRange,這是因為
這里就不再翻譯了,就是在不同電壓下資料訪問的位數不同,我們是3.3V,所以是32位資料,這也就是在讀資料是為什么要讀取32位的原因,
2.3、寫入
寫入之前必須擦除,這里和NorFlash操作是相同的
復位后,Flash控制器暫存器(FLASH_CR)不允許寫入的,去保護Flash閃存因為電氣原因出現的以外操作,以下是解鎖的步驟
1、在Flash 密鑰暫存器(FLASH_KEYR) 中寫入KEY1 = 0x45670123
2、在Flash 密鑰暫存器(FLASH_KEYR) 中寫入KEY2 = 0xCDEF89AB
將FLASH_CR 暫存器中的LOCK 位置為1 后,可通過軟體再次鎖定FLASH_CR 暫存器
ST提供了庫函式
FLASH_Unlock();//解鎖 FLASH_Lock();//重新上鎖
備注:
當FLASH_SR 暫存器中的BSY 位置為1 后,將不能在寫模式下訪問FLASH_CR 暫存器,BSY 位置為1 后,對該暫存器的任何寫操作嘗試都會導致AHB 總線阻塞,直到BSY位清零
這要求我們在寫入前必須判斷下FLASH_SR暫存器中的BSY位,
ST提供了對用的庫函式
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR| FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
寫入步驟
1、檢查FLASH_SR 中的BSY 位,以確認當前未執行任何主要Flash 操作
2、將FLASH_CR 暫存器中的PG 位置1,
3、通過不同的位寬對指定地址寫入
4、等待BSY 位清零
對于寫入介面,ST提供相應的庫函式,提供了8位,16位,32位的操作,因為我們是3.3V電壓,所以使用32位寫入介面
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)
2.4、中斷
如果對于寫入要求較高,可以使能中斷,對于寫入完成,寫入錯誤都會有回應的中斷回應,我也沒有詳細研究,參看Flash編程手冊的15.5章節
03、Flash保護
3.1概述
Flash具有讀寫保護機制,主要是用過選項地址實作的,還有一次性編程保護
這講述了選項位元組的構成
用戶修改選項位元組
To run any operation on this sector, the option lock bit (OPTLOCK) inthe Flash option control register (FLASH_OPTCR) must be cleared. Tobe allowed to clear this bit, you have to perform the followingsequence:
1. Write OPTKEY1 = 0x0819 2A3B in the Flash option key register(FLASH_OPTKEYR)
2. Write OPTKEY2 = 0x4C5D 6E7F in the Flash option key register(FLASH_OPTKEYR)
The user option bytes can be protected against unwanted erase/programoperations by setting the OPTLOCK bit by software.
這個上面講述的解鎖Flash相同,就是要寫入不能的數值
ST提供相應的庫函式
void FLASH_OB_Unlock(void) void FLASH_OB_Lock(void)
修改用戶位元組的步驟
1、檢查FLASH_SR 暫存器中的BSY 位,以確認當前未執行任何Flash 操作
2、在FLASH_OPTCR 暫存器中寫入所需的選項值
3、將FLASH_OPTCR 暫存器中的選項啟動位(OPTSTRT) 置1
4、等待BSY 位清零
3.2 讀保護
從上面概述中得知,Flash讀保護共分三個等級
等級0:沒有保護
將0xAA 寫入讀保護選項位元組(RDP) 時,讀保護級別即設為0,此時,在所有自舉配置(Flash用戶自舉、除錯或從RAM 自舉)中,均可執行與Flash 或備份SRAM 相關的所有讀/寫操作(如果未設定寫保護),
等級1:閃存讀保護
這是擦除選項位元組后的默認讀保護級別,將任意值(分別用于設定級別0 和級別2 的0xAA和0xCC 除外)寫入RDP 選項位元組時,即激活讀保護級別1,設定讀保護級別1 后:
-在連接除錯功能或從RAM 進行自舉時,將不執行任何Flash 訪問(讀取、擦除和編程),Flash 讀請求將導致總線錯誤,而在使用Flash 用戶自舉功能或在系統存盤器自舉模式下操作時,則可執行所有操作
-激活級別1 后,如果將保護選項位元組(RDP) 編程為級別0,則將對Flash 和備份SRAM執行批量擦除,因此,在取消讀保護之前,用戶代碼區域會清零,批量擦除操作僅擦除用戶代碼區域,包括寫保護在內的其它選項位元組將保持與批量擦除操作前相同,OTP 區域不受批量擦除操作的影響,同樣保持不變,
只有在已激活級別1 并請求級別0 時,才會執行批量擦除,當提高保護級別(0->1,1->2, 0->2) 時,不會執行批量擦除,
等級2:禁止除錯/芯片讀保護
注意:
在注意中寫道,如果使能了等級2的讀保護,永久禁止JTAG埠(相當于JTAG熔絲)ST也無法進行分析,說白了就是沒辦法再debug了,目前我沒有使用到這個水平的讀保護
讀保護庫函式
void FLASH_OB_RDPConfig(uint8_t OB_RDP)
查詢讀保護狀態庫函式
FlagStatus FLASH_OB_GetRDP(void)
3.3 寫保護
Flash 中的用戶扇區(0到11)具備寫保護功能,可防止因程式計數器(PC) 跑飛而發生意外的寫操作,當扇區i 中的非寫保護位(nWRPi, 0 ≤ i ≤ 11) 為低電平時,無法對扇區i 執行擦除或編程操作,因此,如果某個扇區處于寫保護狀態,則無法執行批量擦除,
如果嘗試對Flash 中處于寫保護狀態的區域執行擦除/編程操作(由寫保護位保護的扇區、鎖定的OTP 區域或永遠不能執行寫操作的Flash 區域,例如ICP),則FLASH_SR 暫存器中的寫保護錯誤標志位(WRPERR) 將置1,
寫保護庫函式
void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState)
查詢寫保護狀態庫函式
uint16_t FLASH_OB_GetWRP(void)
04、一次性可編程位元組
沒有使用過,使用了芯片就廢了吧,沒有做過這個等級等保護,可以參看Flash編程手冊的2.7章節
05、代碼
關于讀寫保護代碼如何呼叫的問題,在stm32f2xx_flash.c檔案中有呼叫說明.?????,
/** @defgroup FLASH_Group3 Option Bytes Programming functions * @brief Option Bytes Programming functions * @verbatim =============================================================================== Option Bytes Programming functions =============================================================================== This group includes the following functions: - void FLASH_OB_Unlock(void) - void FLASH_OB_Lock(void) - void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState) - void FLASH_OB_RDPConfig(uint8_t OB_RDP) - void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY) - void FLASH_OB_BORConfig(uint8_t OB_BOR) - FLASH_Status FLASH_ProgramOTP(uint32_t Address, uint32_t Data) - FLASH_Status FLASH_OB_Launch(void) - uint32_t FLASH_OB_GetUser(void) - uint8_t FLASH_OB_GetWRP(void) - uint8_t FLASH_OB_GetRDP(void) - uint8_t FLASH_OB_GetBOR(void) Any operation of erase or program should follow these steps: 1. Call the FLASH_OB_Unlock() function to enable the FLASH option control register access 2. Call one or several functions to program the desired Option Bytes: - void FLASH_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState) => to Enable/Disable the desired sector write protection - void FLASH_OB_RDPConfig(uint8_t OB_RDP) => to set the desired read Protection Level - void FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY) => to configure the user Option Bytes. - void FLASH_OB_BORConfig(uint8_t OB_BOR) => to set the BOR Level 3. Once all needed Option Bytes to be programmed are correctly written, call the FLASH_OB_Launch() function to launch the Option Bytes programming process. @note When changing the IWDG mode from HW to SW or from SW to HW, a system reset is needed to make the change effective. 4. Call the FLASH_OB_Lock() function to disable the FLASH option control register access (recommended to protect the Option Bytes against possible unwanted operations) @endverbatim * @{ */
編程Flash,寫保護,讀保護代碼開源
開源地址:
https://github.com/strongercjd/STM32F207VCT6
點擊查看本文所在的專輯,STM32F207教程
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/255435.html
標籤:嵌入式
