本應(yīng)用筆記介紹如何使用內(nèi)置實(shí)用程序ROM擦除/寫入MAXQ7665微控制器(μC)中的程序和數(shù)據(jù)閃存。此信息僅適用于帶扇形可擦除(SE)閃存的基于MAXQ7665閃存的微控制器(μC)。
介紹
本應(yīng)用筆記介紹如何管理帶有扇形可擦除(SE)閃存的MAXQ7665閃存微控制器(μC)中的內(nèi)部數(shù)據(jù)和程序閃存。此討論包括有關(guān)執(zhí)行程序閃存的應(yīng)用程序內(nèi)編程 (IAP) 的一般信息。
內(nèi)存映射
本節(jié)詳細(xì)介紹MAXQ7665器件各種存儲(chǔ)器大小的一般閃存信息和存儲(chǔ)器組織。MAX7665器件提供兩種類型的閃存。本文檔僅介紹帶SE閃存的MAXQ7665器件,不適用于尋頁(yè)(PE)器件。有關(guān)MAXQ7665 PE器件的信息,請(qǐng)參考應(yīng)用筆記“MAXQ7665頁(yè)面可擦除(PE)程序和數(shù)據(jù)閃存的應(yīng)用內(nèi)編程(IAP)”。
表 1 顯示了 128KB、64KB、48KB 和 32KB 設(shè)備的閃存映射??赡艽嬖谄渌W存選項(xiàng),因此請(qǐng)參考MAXQ7665數(shù)據(jù)資料以獲取完整列表。
表 1.閃存映射
使用閃存存儲(chǔ)數(shù)據(jù)
閃存可用于可靠地存儲(chǔ)系統(tǒng)數(shù)據(jù),這些數(shù)據(jù)需要在系統(tǒng)運(yùn)行期間進(jìn)行一次或定期編程。雖然閃存的任何扇區(qū)都可用于存儲(chǔ)數(shù)據(jù),但兩個(gè)4K x 16扇區(qū)通常提供最佳選擇。與EEPROM不同,MAXQ7665上的閃存不能被文字擦除。必須一次擦除完整的扇區(qū)。擦除扇區(qū)通常需要 0.7 秒,但在最壞的情況下可能需要長(zhǎng)達(dá) 15 秒的時(shí)間。在此期間,用戶代碼將停止,因此不會(huì)發(fā)生其他處理。在選擇適合系統(tǒng)要求的軟件技術(shù)時(shí),必須仔細(xì)考慮這些限制。對(duì)于大多數(shù)周期性數(shù)據(jù)存儲(chǔ)需求,有界隊(duì)列和/或銀行交換技術(shù)將滿足系統(tǒng)的可靠性要求和需求。下面是這兩種技術(shù)的簡(jiǎn)單示例。
有界隊(duì)列
有界隊(duì)列是受固定數(shù)量的項(xiàng)目限制的隊(duì)列。每當(dāng)處理定期數(shù)據(jù)時(shí),通常使用此技術(shù)。例如,4K x 16閃存扇區(qū)可以分為64個(gè)64字條目,這將導(dǎo)致表2中128kB部分的內(nèi)存映射。
初始化后,啟動(dòng)例程可以掃描隊(duì)列條目以確定隊(duì)列中的下一個(gè)可用條目。隊(duì)列已滿后,必須先擦除該隊(duì)列,然后才能寫入另一個(gè)條目。(注意:如果需要所有條目,則還必須使用庫(kù)切換來維護(hù)所有數(shù)據(jù)。擦除閃存后,可以寫入新條目。這種方法的缺點(diǎn)是,如果在擦除過程中功率下降,則所有數(shù)據(jù)都可能丟失。如果有界隊(duì)列技術(shù)不符合系統(tǒng)的要求,則還需要進(jìn)行銀行切換。
圖 1 說明了進(jìn)入有界隊(duì)列的條目流。
有關(guān)簡(jiǎn)單的 C 源代碼示例,請(qǐng)參閱附錄 A。
表 2.有界隊(duì)列內(nèi)存映射示例
FLASHQueue[ ] | |
Queue Index | Data Flash Address |
63 | 0xFFC0-0xFFFF |
62 | 0xFF80-0xFFBF |
61 | 0xFF40-0xFF7F |
. . . . | . . . . |
2 | 0xF080-0xF0BF |
1 | 0xF040-0xF07F |
0 | 0xF000-0xF03F |
圖1.有界隊(duì)列流。
銀行切換
組交換是在長(zhǎng)扇區(qū)擦除周期中防止數(shù)據(jù)丟失或損壞的有效方法。當(dāng)扇區(qū)大小僅略大于總數(shù)據(jù)大小時(shí),此方法非常有效。組切換的缺點(diǎn)是它至少需要兩個(gè)閃存扇區(qū)。當(dāng)要寫入的總數(shù)據(jù)大小遠(yuǎn)小于扇區(qū)大小時(shí),最佳方法將庫(kù)交換和有界隊(duì)列技術(shù)結(jié)合起來。如果應(yīng)用需要組切換,MAXQ4的兩個(gè)16K x 7665閃存扇區(qū)可以用作數(shù)據(jù)存儲(chǔ)。
表3是使用兩個(gè)4K x 16閃存扇區(qū)時(shí)的內(nèi)存映射示例。圖 2 顯示了組交換寫入/擦除流程。
有關(guān)簡(jiǎn)單的 C 源代碼示例,請(qǐng)參閱附錄 A。
表 3.組切換存儲(chǔ)器映射示例
閃存扇區(qū) | |
扇區(qū)編號(hào) | 數(shù)據(jù)閃存地址 |
0 | 0xF000-0xFFFF |
1 | 0xE000-0xEFFF |
圖2.銀行切換流程。
有界隊(duì)列和銀行交換
同時(shí)使用有界隊(duì)列和銀行交換技術(shù)是最可靠和靈活的方法。當(dāng)需要存儲(chǔ)少量數(shù)據(jù)以定期刷新時(shí),以及必須保持?jǐn)?shù)據(jù)完整性時(shí),這種組合方法非常有效。表 4 顯示了使用劃分為 4 個(gè)相等條目的兩個(gè) 16K x 64 扇區(qū)的內(nèi)存映射示例。圖 3 說明了兩個(gè)扇區(qū)之間有界隊(duì)列中的數(shù)據(jù)流。
這種組合技術(shù)的編碼僅比單獨(dú)的有界隊(duì)列稍微復(fù)雜一些。有關(guān)簡(jiǎn)單的 C 源代碼示例,請(qǐng)參閱附錄 A。
表 4.有界隊(duì)列內(nèi)存映射示例
FQueueBank0[ ] | |
Queue Index | Data Flash Address |
63 | 0xFFC0-0xFFFF |
62 | 0xFF80-0xFFBF |
61 | 0xFF40-0xFF7F |
. . . . | . . . . |
2 | 0xF080-0xF0BF |
1 | 0xF040-0xF07F |
0 | 0xF000-0xF03F |
FQueueBank1[ ] | |
Queue Index | Data Flash Address |
63 | 0xEFC0-0xEFFF |
62 | 0xEF80-0xEFBF |
61 | 0xEF40-0xEF7F |
. . . . | . . . . |
2 | 0xE080-0xE0BF |
1 | 0xE040-0xE07F |
0 | 0xE000-0xE03F |
圖3.有界隊(duì)列和銀行切換的流程圖。
實(shí)用程序 ROM 閃存例程
為了編程、擦除和驗(yàn)證閃存,MAXQ7665微控制器在ROM (只讀存儲(chǔ)器)中提供了片內(nèi)閃存支持例程。有兩種方法可以訪問這些例程。第一種也是最快的方法是直接訪問,即直接調(diào)用例程。為此,請(qǐng)?zhí)峁┌韵滦械念^文件:
u16 flashEraseSector(void *); u16 flashEraseAll(void); u16 flashWrite(void *pAddress, u16 iData);
接下來,添加鏈接器定義以為每個(gè)例程分配適當(dāng)?shù)牡刂贰?duì)于 IAR 鏈接器文件,添加的行如下所示:
-DflashEraseSector=0x8XXX -DflashEraseAll=0x8XXX -DflashWrite=0x8XXX
將 0x8XXX 替換為每個(gè)例程的相應(yīng)內(nèi)存地址。其他編譯器可能會(huì)使用不同的方法來添加這些引用。
注意:直接訪問方法不提供與未來 ROM 版本的向前兼容性。
間接尋址的第二種方法使用表查找。雖然此方法提供了與未來ROM版本更好的兼容性,但它消耗了更多的執(zhí)行時(shí)間。在下面描述的每個(gè)例程之后,程序集例程使用表查找方法來獲取 ROM 實(shí)用程序例程的地址。表 5 顯示了實(shí)用程序 ROM 提供的閃存例程。有關(guān)ROM實(shí)用程序的完整列表,請(qǐng)參考MAXQ7665用戶指南,該指南可在Maxim網(wǎng)站上找到。
表 5.閃存實(shí)用程序 ROM 例程
例程編號(hào) | 例程名稱 | 入口點(diǎn)可 ROMTable = ROM[800Dh] | 入口點(diǎn)物理地址 |
2 | 閃存擦除扇區(qū) | 羅姆[可浪漫 + 1] | 0x8XXX |
3 | 閃光擦除全部 | 羅姆[可浪漫 + 2] | 0x8XXX |
15 | 閃寫 | 羅姆[可浪漫 + 14] | 0x8XXX |
閃寫
常規(guī): | u16 flashWrite(void *pAddress, u16 iData) |
總結(jié): | 對(duì)單個(gè)字的閃存進(jìn)行編程。 |
輸入: |
A[0] - 閃存中要寫入的字地址。 A[1] - 要寫入閃存的字值。 |
輸出: |
攜帶:錯(cuò)誤時(shí)設(shè)置,成功時(shí)清除。如果設(shè)置,則 A[0] 包含以下錯(cuò)誤代碼之一: 1:由于軟件超時(shí)而導(dǎo)致的故障 2:硬件 (DQ5/FERR) 報(bào)告故障 4: 不支持 命令 SW_FERR - 出錯(cuò)時(shí)設(shè)置,成功時(shí)清除。 |
筆記: | 監(jiān)視器不得處于活動(dòng)狀態(tài),或者監(jiān)視器超時(shí)必須設(shè)置足夠長(zhǎng)的時(shí)間才能在不觸發(fā)重置的情況下完成此例程。 |
下面的匯編代碼示例使用間接尋址方法(查找表)調(diào)用 flashWrite() 實(shí)用例程。此例程可由 C 代碼調(diào)用。
; This routine is callable by C code using the following prototype ; u16 flashWrite(void *pAddress, u16 iData); ; flashWrite: move APC, #0 ; No auto inc/dec of accumulator. move DP[0], #0800Dh ; This is where the address of the table is ; stored. move ACC, @DP[0] ; Get the location of the routine table. add #14 ; Add the index to the flashWrite routine. move DP[0], ACC move ACC, @DP[0] ; Retrieve the address of the routine. call ACC ; Execute the routine. ret ; Status returned in A[0].
常規(guī): | u16 閃存擦除扇區(qū)(無效 *pAddress) |
總結(jié): | 擦除閃存的單個(gè)扇區(qū)。 |
輸入: | A[0] - 位于要擦除的扇區(qū)中的地址。 |
輸出: |
攜帶:錯(cuò)誤時(shí)設(shè)置,成功時(shí)清除。如果設(shè)置,則 A[0] 包含以下錯(cuò)誤代碼之一: 1:由于軟件超時(shí)而導(dǎo)致的故障 2:硬件 (DQ5/FERR) 報(bào)告故障 4: 不支持 命令 SW_FERR - 出錯(cuò)時(shí)設(shè)置,成功時(shí)清除。 |
筆記: | |
監(jiān)視器不得處于活動(dòng)狀態(tài),或者監(jiān)視器超時(shí)必須設(shè)置足夠長(zhǎng)的時(shí)間才能在不觸發(fā)重置的情況下完成此例程。 |
; This routine is callable by C code using the following prototype ; u16 flashEraseSector(void *pAddress); ; flashEraseSector: move APC, #0 ; No auto inc/dec of accumulator. move DP[0], #0800Dh ; This is where the address of the table is ; stored. move ACC, @DP[0] ; Get the location of the routine table. add #1 ; Add the index to the flashEraseSector routine. move DP[0], ACC move ACC, @DP[0] ; Retrieve the address of the routine. call ACC ; Execute the routine. ret ; Status returned in A[0]
常規(guī): | 虛空閃光擦除全部(虛空) |
總結(jié): | 擦除整個(gè)程序和數(shù)據(jù)閃存,包括引導(dǎo)加載程序扇區(qū)。此例程通常不用于 IAP,因?yàn)楸仨毞浅P⌒囊源_保擦除/編程序列不會(huì)中斷。 |
輸入: | 沒有 |
輸出: |
攜帶:錯(cuò)誤時(shí)設(shè)置,成功時(shí)清除。 SW_FERR - 出錯(cuò)時(shí)設(shè)置,成功時(shí)清除。 |
筆記: | 監(jiān)視器不得處于活動(dòng)狀態(tài),或者監(jiān)視器超時(shí)必須設(shè)置足夠長(zhǎng)的時(shí)間才能在不觸發(fā)重置的情況下完成此例程。 |
; This routine is callable by C code using the following prototype ; void flashEraseAll(void); ; flashEraseAll: move APC, #0 ; No auto inc/dec of accumulator. move DP[0], #0800Dh ; This is where the address of the table is ; stored. move ACC, @DP[0] ; Get the location of the routine table. add #2 ; Add the index to the flashEraseAll routine. move DP[0], ACC move ACC, @DP[0] ; Retrieve the address of the routine. call ACC ; Execute the routine. ret
應(yīng)用程序內(nèi)編程 (IAP)
大多數(shù)基于閃存的系統(tǒng)必須能夠在系統(tǒng)安裝在最終產(chǎn)品中時(shí)更新固件。此過程稱為應(yīng)用程序內(nèi)編程 (IAP)。以下討論概述了創(chuàng)建 IAP 應(yīng)用程序的一般準(zhǔn)則。
上一節(jié)中概述的實(shí)用程序 ROM 閃存例程執(zhí)行擦除和寫入閃存 ROM 所需的所有操作。因此,最終用戶應(yīng)用程序可以在閃存上執(zhí)行操作。與任何其他子例程調(diào)用一樣,控件將在例程完成后返回到最終用戶的代碼。
在MAXQ7665的僅扇區(qū)擦除版本上執(zhí)行IAP序列時(shí)必須小心,因?yàn)椴淮嬖趯S玫囊龑?dǎo)加載程序閃存扇區(qū)。要設(shè)計(jì)完全容錯(cuò)的 IAP,引導(dǎo)加載程序應(yīng)用程序必須與主應(yīng)用程序分開。這確保了即使在發(fā)生不完整的重編程序列后,也可以重試重編程過程。如果IAP必須容忍重編程過程中的斷電等故障,則選擇具有頁(yè)面擦除功能的MAXQ7665版本。這將允許引導(dǎo)加載程序應(yīng)用程序從0x0000(重置入口點(diǎn))啟動(dòng),并與主應(yīng)用程序代碼完全分開。對(duì)于不需要完全容錯(cuò) IAP 的應(yīng)用程序,可以使用基于 RAM 的重新刷新例程來完成 IAP。
使用基于 RAM 的閃存例程的 IAP
當(dāng)不需要故障恢復(fù)時(shí),可以使用基于RAM的閃存例程重新刷新MAXQ7665。此方法要求主應(yīng)用程序?qū)⒁粋€(gè)小的可重定位閃存編程例程復(fù)制到 RAM 中,然后跳轉(zhuǎn)到該例程。從 RAM 執(zhí)行代碼時(shí),必須考慮幾個(gè)限制。
通常,閃存例程將通過UART或CAN接口進(jìn)行通信。通常最好接收小數(shù)據(jù)包并發(fā)送確認(rèn),以允許更強(qiáng)大的錯(cuò)誤恢復(fù)機(jī)制。圖 4 是一個(gè)流程圖,顯示了重新刷新例程的工作原理。如果在斷電前未成功完成重新編程,請(qǐng)記住,微控制器需要通過JTAG端口重新編程。
圖4.簡(jiǎn)化的 RAM 重新刷新例程的流程圖。
審核編輯:郭婷
-
微控制器
+關(guān)注
關(guān)注
48文章
7552瀏覽量
151426 -
存儲(chǔ)器
+關(guān)注
關(guān)注
38文章
7492瀏覽量
163842 -
應(yīng)用程序
+關(guān)注
關(guān)注
37文章
3268瀏覽量
57710
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論