STM32的Flash操做

說到STM32FLSAH,咱們的第一反應是用來裝程序的,實際上,STM32的片內FLASH不只用來裝程序,還用來裝芯片配置、芯片ID、自舉程序等等。固然, FLASH還能夠用來裝數據。 編程

 

FLASH分類 安全

根據用途,STM32片內的FLASH分紅兩部分:主存儲塊、信息塊。 ui

主存儲塊用於存儲程序,咱們寫的程序通常存儲在這裏。 spa

信息塊又分紅兩部分:系統存儲器、選項字節。 指針

系統存儲器存儲用於存放在系統存儲器自舉模式下的啓動程序(BootLoader),當使用ISP方式加載程序時,就是由這個程序執行。這個區域由芯片廠寫入BootLoader,而後鎖死,用戶是沒法改變這個區域的。 調試

選項字節存儲芯片的配置信息及對主存儲塊的保護信息。 接口

 

FLASH的頁面 開發

STM32FLASH主存儲塊按頁組織,有的產品每頁1KB,有的產品每頁2KB。頁面典型的用途就是用於按頁擦除FLASH。從這點來看,頁面有點像通用FLASH的扇區。 產品

 

STM32產品的分類 it

STM32根據FLASH主存儲塊容量、頁面的不一樣,系統存儲器的不一樣,分爲小容量、中容量、大容量、互聯型,共四類產品。

小容量產品主存儲塊1-32KB,每頁1KB。系統存儲器2KB

中容量產品主存儲塊64-128KB,每頁1KB。系統存儲器2KB

大容量產品主存儲塊256KB以上,每頁2KB。系統存儲器2KB

互聯型產品主存儲塊256KB以上,每頁2KB。系統存儲器18KB

對於具體一個產品屬於哪類,能夠查數據手冊,或根據如下簡單的規則進行區分:

STM32F101xxSTM32F102xx STM32F103xx產品,根據其主存儲塊容量,必定是小容量、中容量、大容量產品中的一種,STM32F105xxSTM32F107xx是互聯型產品。

互聯型產品與其它三類的不一樣之處就是BootLoader的不一樣,小中大容量產品的BootLoader只有2KB,只能經過USART1進行ISP,而互聯型產品的BootLoader18KB,能經過USAT14CAN等多種方式進行ISP。小空量產品、中容量產品的BootLoader與大容量產品相同

 

關於ISPIAP

ISPIn System Programming)在系統編程,是指直接在目標電路板上對芯片進行編程,通常須要一個自舉程序(BootLoader)來執行。ISP也有叫ICPIn Circuit Programming)、在電路編程、在線編程。

IAPIn Application Programming)在應用中編程,是指最終產品出廠後,由最終用戶在使用中對用戶程序部分進行編程,實如今線升級。IAP要求將程序分紅兩部分:引導程序、用戶程序。引導程序老是不變的。IAP也有叫在程序中編程。

ISPIAP的區別在於,ISP通常是對芯片整片從新編程,用的是芯片廠的自舉程序。而IAP只是更新程序的一部分,用的是電器廠開發的IAP引導程序。綜合來看,ISP受到的限制更多,而IAP因爲是本身開發的程序,更換程序的時候更容易操做。

 

FPEC

FPEC(FLASH Program/Erase controller 閃存編程/擦除控制器)STM32經過FPEC來擦除和編程FLASHFPEC使用7個寄存器來操做閃存:

FPEC鍵寄存器(FLASH_KEYR)                                   寫入鍵值解鎖。

選項字節鍵寄存器(FLASH_OPTKEYR)               寫入鍵值解鎖選項字節操做。

閃存控制寄存器(FLASH_CR)                                選擇並啓動閃存操做。

閃存狀態寄存器(FLASH_SR)                                查詢閃存操做狀態。

閃存地址寄存器(FLASH_AR)                                存儲閃存操做地址。

選項字節寄存器(FLASH_OBR)                             選項字節中主要數據的映象。

寫保護寄存器(FLASH_WRPR)                              選項字節中寫保護字節的映象。

 

鍵值

爲了加強安全性,進行某項操做時,需要向某個位置寫入特定的數值,來驗證是否爲安全的操做,這些數值稱爲鍵值。STM32FLASH共有三個鍵值:

RDPRT   = 0x000000A5         用於解除讀保護

KEY1          = 0x45670123          用於解除閃存鎖

KEY2          = 0xCDEF89AB             用於解除閃存鎖

 

閃存鎖

FLASH_CR中,有一個LOCK位,該位爲1時,不能寫FLASH_CR寄存器,從而也就不能擦除和編程FLASH,這稱爲閃存鎖。

LOCK位爲1時,閃存鎖有效,只有向FLASH_KEYR依次寫入KEY1KEY2後,LOCK位纔會被硬件清零,從而解除閃存鎖。當LOCK位爲1時,對FLASH_KEYR的任何錯誤寫操做(第一次不是KEY1,或第二次不是KEY2),都將會致使閃存鎖的完全鎖死,一旦閃存鎖完全鎖死,在下一次復位前,都沒法解鎖,只有復位後,閃存鎖才恢復爲通常鎖住狀態。

復位後,LOCK位默認爲1,閃存鎖有效,此時,能夠進行解鎖。解鎖後,可進行FLASH的擦除編程工做。任什麼時候候,均可以經過對LOCK位置1來軟件加鎖,軟件加鎖與復位加鎖是同樣的,均可以解鎖。

 

主存儲塊的擦除

主存儲塊能夠按頁擦除,也能夠整片擦除。

頁擦除

主存儲塊的任何一頁均可以經過FPEC的頁擦除功能擦除。

建議使用如下步驟進行頁擦除:

1.檢查FLASH_SR寄存器的BSY位。以確認沒有其餘正在進行的閃存操做。必須等待BSY位爲0,才能繼續操做。

              2.設置FLASH_CR寄存器的PER位爲1。選擇頁擦除操做。

3.設置FLASH_AR寄存器爲要擦除頁所在地址,選擇要擦除的頁。FLASH_AR的值在哪一頁範圍內,就表示要擦除哪一頁。

4.設置FLASH_CR寄存器的STRT位爲1,啓動擦除操做。

5.等待FLASH_SR寄存器的BSY位變爲0,表示操做完成。

6.查詢FLASH_SR寄存器的EOP位,EOP1時,表示操做成功。

              7.讀出被擦除的頁並作驗證。擦完後全部數據位都爲1

 

整片擦除

整片擦除功能擦除整個主存儲塊,信息塊不受此操做影響。

建議使用如下步驟進行整片擦除:

       1.檢查FLASH_SR寄存器的BSY位,以確認沒有其餘正在進行的閃存操做。

              2.設置FLASH_CR寄存器的MER位爲1。選擇整片擦除操做。

              3.設置FLASH_CR寄存器的STRT位爲1。啓動整片擦除操做。

              4.等待FLASH_SR寄存器的BSY位變爲0,表示操做完成。

              5.查詢FLASH_SR寄存器的EOP位,EOP1時,表示操做成功。

              6.讀出全部頁並作驗證。擦完後全部數據位都爲1

 

主存儲塊的編程

對主存儲塊編程每次能夠寫入16位。當FLASH_CR寄存器的PG位爲1時,在一個閃存地址寫入一個半字(16位)將啓動一次編程;寫入任何非半字的數據,FPEC都會產生總線錯誤。在編程過程當中(BSY位爲1),任何讀寫閃存的操做都會使CPU暫停,直到這次閃存編程結束。

建議使用以下步驟對主存儲塊進行編:

       1.檢查FLASH_SR寄存器的BSY位,以確認沒有其餘正在進行的編程操做。

       2.設置FLASH_CR寄存器的PG位爲1。選擇編程操做。

       3.在指定的地址寫入要編程的半字。直接用指針寫。

       4.等待FLASH_SR寄存器的BSY位變爲0,表示操做完成。

       5.查詢FLASH_SR寄存器的EOP位,EOP1時,表示操做成功。

6.讀出寫入的地址並驗證數據。

 

關於主存儲塊擦除編程操做的一些疑問

1. 爲何每次都要檢查BSY位是否爲0

由於BSY位爲1時,不能對任何FPEC寄存器執行寫操做,因此必需要等BSY位爲0時,才能執行閃存操做。

2. 若是沒有擦除就進行編程,會出現什麼結果?

STM32在執行編程操做前,會先檢查要編程的地址是否被擦除,若是沒有,則不進行編程,並置FLASH_SR寄存器的PGERR位爲1。惟一例外的是,當要編程的數據爲0X0000時,即便未擦除,也會進行編程,由於0X0000即便擦除也能夠正確編程。

3. 爲何操做後要讀出數據並驗證?

STM32在某些特殊狀況下(例如FPEC被鎖住),可能根本就沒有執行所要的操做,僅經過寄存器沒法判斷操做是否成功。因此,保險起見,操做後都要讀出全部數據檢查。

4. 等待BSY位爲1的時間以多少爲合適?

請參考STM32固件庫中的數據。

5. FLASH編程手冊上說進行閃存操做(擦除或編程)時,必須打開內部的RC振盪器(HSI),是否是必定要用HIS進行閃存的擦除及編程操做?

對於這點,個人理解是,進行閃存操做時,必需要保證HIS沒有被關閉,可是操做時的系統仍然能夠是HSE時鐘。STM32復位後,HIS默認是開的,只要你不爲了低功耗去主動關閉它,則用什麼時鐘均可以進行閃存操做的。我所編的程序也驗證了這一點。

 

選項字節

選項字節用於存儲芯片使用者對芯片的配置信息。

目前,全部的STM32101xxSTM32102xxSTM32103xxSTM32105xxSTM32107xx產品,選項字節都是16字節。可是這16字節,每兩個字節組成一個正反對,即,字節1是字節0的反碼,字節3是字節2的反碼,...,字節15是字節14的反碼,因此,芯片使用者只要設置8個字節就好了,另外8個字節系統自動填充爲反碼。所以,有時候,也說STM32的選項字節是8個字節,可是佔了16字節的空間。

選項字節的8字節正碼概述以下:

RDP                    字節0。讀保護字節,存儲對主存儲塊的讀保護設置。

USER           字節2。用戶字節,配置看門狗、停機、待機。

Data0           字節4。數據字節0,由芯片使用者自由使用。

Data1           字節6。數據字節1,由芯片使用者自由使用。

WRP0          字節8。寫保護字節0,存儲對主存儲塊的寫保護設置。

WRP1          字節10。寫保護字節1,存儲對主存儲塊的寫保護設置。

WRP2          字節12。寫保護字節2,存儲對主存儲塊的寫保護設置。

WRP3          字節14。寫保護字節3,存儲對主存儲塊的寫保護設置。3

 

選項字節寫使能

FLASH­_CR中,有一個OPTWRE位,該位爲0時,不容許進行選項字節操做(擦除、編程)。這稱爲選項字節寫使能。只有該位爲1時,才能進行選項字節操做。

該位不能軟件置1,但能夠軟件清零。只有向FLASH_OPTKEYR依次寫入KEY1KEY2後,硬件會自動對該位置1,此時,才容許選項字節操做。這稱爲解鎖(打開)選項字節寫使能。

該位爲1後,能夠由軟件清零,關閉寫使能。

復位後,該位爲0。錯誤操做不會永遠關閉寫使能,只要寫入正確的鍵序列,則又能夠打開寫使能。寫使能已打開時,再次打開,不會出錯,而且依然是打開的。

很顯然,進行選項字節操做前,先要解開閃存鎖,而後打開選項字節寫使能,以後,才能進行選項字節操做。

 

選項字節擦除

建議使用以下步驟對選項字節進行擦除:

       1.檢查FLASH_SR寄存器的BSY位,以確認沒有其餘正在進行的閃存操做。

       2.解鎖FLASH_CR寄存器的OPTWRE位。即,打開寫使能。

       3.設置FLASH_CR寄存器的OPTER位爲1。選擇選項字節擦除操做。

       4.設置FLASH_CR寄存器的STRT位爲1

       5.等待FLASH_SR寄存器的BSY位變爲0,表示操做完成。

       6.查詢FLASH_SR寄存器的EOP位,EOP1時,表示操做成功。

7.讀出選項字節並驗證數據。

因爲選項字節只有16字節,所以,擦除時是整個選項字節都被擦除了。

 

選項字節編程

建議使用以下步驟對選項字節進行編程:

       1.檢查FLASH_SR寄存器的BSY位,以確認沒有其餘正在進行的編程操做。

       2.解鎖FLASH_CR寄存器的OPTWRE位。即,打開寫使能。

       3.設置FLASH_CR寄存器的OPTPG位爲1。選擇編程操做。

       4.寫入要編程的半字到指定的地址。啓動編程操做。

       5.等待FLASH_SR寄存器的BSY位變爲0,表示操做完成。

       6.查詢FLASH_SR寄存器的EOP位,EOP1時,表示操做成功。

7.讀出寫入的選項字節並驗證數據。

對選項字節編程時,FPEC使用半字中的低字節並自動地計算出高字節(高字節爲低字節的反碼),並開始編程操做,這將保證選項字節和它的反碼始終是正確的。

 

主存儲塊的保護

能夠對主存儲塊中的數據進行讀保護、寫保護。

讀保護用於保護數據不被非法讀出。防止程序泄密。

寫保護用於保護數據不被非法改寫,加強程序的健壯性。

讀保護

主存儲塊啓動讀保護後,簡單的說具備如下特性:

1.從主存儲塊啓動的程序,能夠對整個主存儲塊執行讀操做,不容許對主存儲塊的前4KB進行擦除編程操做,能夠對4KB以後的區域進行擦除編程操做。

2.從SRAM啓動的程序,不能對主存儲塊進行讀、頁擦除、編程操做,但能夠進行主存儲塊整片擦除操做。

       3.使用調試接口不能訪問主存儲塊。

這些特性足以阻止主存儲器數據的非法讀出,又能保證程序的正常運行。

只有當RDP選項字節的值爲RDPRT鍵值時,讀保護才被關閉,不然,讀保護就是啓動的。所以,擦除選項字節的操做,將啓動主存儲塊的讀保護。若是要關閉讀保護,必須將RDP選項字節編程爲RDPRT鍵值。而且,若是編程選項字節,使RDP由非鍵值變爲鍵值(即由保護變爲非保護)時,STM32將會先擦除整個主存儲塊,再編程RDP

芯片出廠時,RDP會事先寫入RDPRT鍵值,關閉寫保護功能。

 

寫保護

STM32主存儲塊能夠分域進行寫保護。

若是試圖對寫保護的域進行擦除或編程操做,在閃存狀態寄存器(FLASH_SR)中會返回一個寫保護錯誤標誌。

STM32主存儲塊每一個域4KBWRP0-WRP3選項字節中的每一位對應一個域,位爲0時,寫保護有效。對於超過128KB的產品,WRP315保護了域31及以後的全部域。

顯然,擦除選項字節將致使解除主存儲塊的寫保護。

 

選項字節與它的寄存器映象

咱們知道,FPEC有兩個寄存器存儲了選項字節的映象。那麼,選項字節本體(在FLASH中)與映象(在寄存器中)究竟有什麼區別呢?

選項字節的本體只是個FLASH,它的做用只是掉電存儲選項字節內容而以,真正起做用的是寄存器中的映象。即,一個配置是否有效,不是看本體,而是看映象。而映象是在復位後,用本體的值加載的,此後,除非復位,映象將再也不改變。因此,更改本體的數據後,不會當即生效,只有復位加載到映象中後,纔會生效。

有一點要注意的是,當更改本體的值,使主存儲塊讀保護變爲不保護時,會先擦除整片主存儲塊,而後再改變本體。這是惟一一個改變本體會引起的動做。但即便這樣,讀保護依然要等到復位後,加載到映象後,纔會解除。

 

 

關於FLASH編程手冊中文版的幾處錯誤(不必定是,可是與個人理解不符)

1.選項字節編程一節中:

FPEC解鎖後,必須分別寫入KEY1KEY2(2.3.1)FLASH_OPTKEYR寄存器,再設置FLASH_CR寄存器的OPTWRE位爲’1’,此時能夠對選項字節進行編程

實際上,對FLASH_OPTKEYR寫入KEY1KEY2後,OPTWRE位會被硬件置1,而不是用軟件寫1。這一點在後面的寄存器描述中也能夠獲得驗證。

2.對讀保護的描述中:

對讀保護的數值對沒法理解。正確的應該是,RDPRDPRT鍵值時,解除讀保護,爲其它值時,讀保護生效。

相關文章
相關標籤/搜索