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





