程序執行時(shí)寫(xiě)閃存的應用實(shí)例
閃存(flash)是一種可在線(xiàn)進(jìn)行電擦寫(xiě),掉電后信息不丟失的存儲器。它具有低操作電壓、低功耗、大容量、擦寫(xiě)速度快等特點(diǎn)。在嵌入式系統中廣泛使用閃存來(lái)保存程序。在實(shí)際應用中為了節省整個(gè)嵌入式系統的成本和系統復雜程度,整個(gè)系統僅設計成具有一塊閃存,CPU執行的程序被保存在閃存中,設備產(chǎn)生的重要數據也保存在該閃存中,且這些數據必須在設備運行過(guò)程中及時(shí)進(jìn)行更新保存。因此要求系統在程序執行時(shí)必須完成向閃存中保存數據信息的功能,也就是CPU從閃存中取指執行程序時(shí),同時(shí)向閃存中寫(xiě)入數據。絕大多數閃存芯片是不支持同時(shí)對芯片進(jìn)行讀寫(xiě)操作的。本文通過(guò)一個(gè)完整的應用實(shí)例,詳細介紹了在應用程序執行過(guò)程中寫(xiě)SST32HF162的方法,并提供了相應的C語(yǔ)言源程序代碼,同時(shí)對C語(yǔ)言代碼的可行性進(jìn)行了詳細的分析。
SST32HF162存儲器特點(diǎn)
SST32HF162是來(lái)自SST公司的Combo存儲器,其結構為1M×16閃存+128K×16 SRAM。它的主要特點(diǎn)如下:2.7~3V單電源供電;讀寫(xiě)SRAM時(shí)可同時(shí)對閃存進(jìn)行讀寫(xiě)操作;支持JEDEC單電源閃存存儲器標準;向其命令寄存器寫(xiě)入相應的指令即可完成閃存的擦除、寫(xiě)操作;通過(guò)查詢(xún)特定的數據位可監控擦除或寫(xiě)操作是否完成??蓪θ我簧葏^、塊進(jìn)行讀、寫(xiě)或擦除操作,而不影響其它部分的數據;扇區大小為2K字;支持字節編程方式。
向閃存的特定寄存器連續寫(xiě)入3個(gè)特定的字節可開(kāi)始一個(gè)寫(xiě)循環(huán),而后寫(xiě)入地址以及相應的數據就可對閃存進(jìn)行編程操作。在寫(xiě)閃存期間僅有讀檢測位有效,其他命令都將被忽略。由于編程指令不能使閃存中的邏輯“0”改寫(xiě)為“1”,因此在編程閃存時(shí)必須先進(jìn)行擦除操作。閃存編程命令見(jiàn)表1。
|
表1:閃存編程命令表。
系統環(huán)境描述
本例采用的MCU采用ARM內核。ARM體系使用單一的平板地址空間,該地址空間的大小為232個(gè)8位字節。這些字節單元的地址是一個(gè)無(wú)符號的32位整數值,其取值范圍為0到232-1。ARM體系支持32位或16位的數據總線(xiàn),本文介紹的系統使用16位的數據總線(xiàn),因此ARM的地址空間可以看作是231個(gè)16位的半字單元。
源程序代碼要求系統環(huán)境中有SRAM,SRAM的大小至少能容納寫(xiě)一個(gè)字到閃存中的程序代碼。對于SRAM以及閃存的實(shí)際地址分配沒(méi)有特別要求。
寫(xiě)閃存過(guò)程
1.搬移閃存中的程序到SRAM中
系統中僅設計有一塊閃存,且同塊閃存在寫(xiě)入時(shí)讀出的數據無(wú)效,因此在閃存寫(xiě)入期間MCU不能再從閃存中取指執行程序。因在讀寫(xiě)SRAM時(shí)可以進(jìn)行閃存的寫(xiě)入操作,所以我們可以將寫(xiě)閃存時(shí)MCU將執行的代碼全部搬移到SRAM中,強制程序在SRAM中執行。通過(guò)執行SRAM中的程序完成對閃存的擦除以及寫(xiě)入的工作。
2.閃存寫(xiě)入以扇區為單位
在進(jìn)行閃存寫(xiě)入時(shí),首先必須進(jìn)行擦除,而后再編程閃存。閃存擦除時(shí)以扇區為單位,在本應用中每個(gè)扇區為2K字。當每次寫(xiě)入數據少于一個(gè)扇區的大小時(shí),原來(lái)保存在該扇區中的信息將被擦除。因此在進(jìn)行寫(xiě)閃存時(shí)必須先讀出原來(lái)在該區中保存的信息,而后與準備寫(xiě)入的信息共同組成一個(gè)扇區內容,再開(kāi)始寫(xiě)閃存的操作。
程序實(shí)現流程見(jiàn)圖1和圖2。
|
圖1:寫(xiě)閃存流程。
|
圖2:寫(xiě)扇區流程
源程序技術(shù)難點(diǎn)分析
以上兩個(gè)C語(yǔ)言函數在編譯完成后將作為程序代碼的一部分,它將和其他程序代碼一樣保存在閃存中。為此將產(chǎn)生的問(wèn)題1:WriteWord函數是怎樣被搬移到SRAM中的?問(wèn)題2:WriteWord函數代碼被搬移到SRAM中后因此時(shí)函數保存起始地址發(fā)生變更,函數還能正確運行嗎?
對于第一個(gè)問(wèn)題的解決,在程序中定義了proginram這個(gè)全局靜態(tài)數組,該數組在A(yíng)RM編譯器進(jìn)行編譯時(shí)將被標記為zidata段映象,這種映象將在程序運行時(shí)自動(dòng)在RAM空間分配相應的內存區域。因此當將WriteWord函數起始地址的信息保存到proginram數組中時(shí),就完成了代碼從閃存中搬移到SRAM中的操作。
對于問(wèn)題2,整個(gè)程序指令都是由順序指令以及分支指令組成的。順序指令指程序執行完當前指令后將執行緊接著(zhù)它的下一條指令。分支指令指程序執行完當前指令后將執行該指令之前或之后某個(gè)偏移處的指令。在程序執行時(shí),CPU將使用PC指針來(lái)標記當前運行的程序地址。
1.指令執行
對于順序指令,PC指針總是自動(dòng)完成指向下一條執行指令的增1操作,只要PC的首地址正確,程序將正確的執行直到代碼結束。
2.分支指令
對于分支指令,在程序執行過(guò)程中確定正確的目標跳轉地址將是程序能否正確運行的關(guān)鍵。在A(yíng)RM體系中,跳轉指令有:B/跳轉指令;BL/帶返回的跳轉指令;BLX/帶返回和狀態(tài)切換的跳轉指令;BX/帶狀態(tài)切換的跳轉指令?,F在以B(跳轉指令)為例進(jìn)行說(shuō)明跳轉指令的執行情況。
每條B指令由表2中的4字節內容組成,其中跳轉目標地址的計算方法是:將指令中的Signed_immed_24這24位帶符號數的補碼擴展為32位(擴展其符號位);將此32位數左移兩位;將得到的數加到PC寄存器中,得到跳轉的目標地址。因此有如下結論:跳轉指令的執行是以當前PC指針值為基準的,在閃存保存的程序僅保存了跳轉的偏移量。
WriteWord函數編譯后生成的偽指令如圖3中灰色字體。
|
圖3:WriteWord函數編譯
后生成的偽代碼。
從函數產(chǎn)生的偽代碼可以看出,對于WriteWord函數,在編譯后形成的指令由一些數據操作指令以及跳轉指令B組成,而對于數據操作指令都是順序執行的。而跳轉指令B的執行情況前面已經(jīng)進(jìn)行了相應的分析,因此函數WriteWord從閃存中移入SRAM中后依舊可以正確運行。
設計要點(diǎn)小結
1. 在應用程序中寫(xiě)閃存時(shí)必須先將相應的寫(xiě)程序搬移到SRAM中,通過(guò)執行SRAM中的程序完成寫(xiě)閃存功能。不能既執行閃存中的程序又寫(xiě)該片閃存。
2. 在寫(xiě)閃存時(shí)必須保證不破壞原來(lái)的數據,同時(shí)必須禁止系統的中斷以防止執行存儲在閃存中的中斷響應程序。
3. 因為程序是靜態(tài)編址的,即程序在編譯鏈接時(shí)就已經(jīng)確定了指令執行期間的跳轉目標地址,因此必須確定原存儲在閃存中的程序搬移到SRAM中后,該代碼段在新的起始地址是否能正確執行。
作者:肖德勇
產(chǎn)品開(kāi)發(fā)軟件經(jīng)理
聯(lián)系客服