在應用編程(IAP)應該是MCU使用過程中常見的一種功能,MCU廠商為了加速用戶的產品開發,都會在其SDK中添加相關示例,而且也有不少用戶只需要簡單的集成,就完成了該功能并實現產品的量產。但你是否真的會在Flash上存數據?
首先我們需要從片內和片外存儲談起,MCU內部的非易失性存儲器絕大多數都是基于FLASH的(也有少部分是EEPROM的,比如NXP LPC80x系列),MCU外部的非易失性存儲器可以有FLASH,EEPROM,其中EEPROM比較常見的是I2C接口,FLASH有NAND, NOR, SPI NOR等等。
實際應該過程中,我們到底應該怎么選擇呢?需要存儲的數據量大小是首要問題,我們可以根據它來大致設定規則
![7b84d120-38aa-11ed-ba43-dac502259ad0.png](https://file1.elecfans.com//web2/M00/96/BB/wKgZomTnI1WAJMvDAAQ3mDRnfH8658.png)
-
當數據量大于128MB時,NAND FLASH或者SD(TF)卡是常見的選擇,但考慮到NAND FLASH會有壞塊的問題,編寫存儲軟件時需要考慮磨損均衡已經壞塊管理的問題,想要做的非常可靠并不容易。
-
當數據量小于128MB,大于2MB時,可以選擇NOR FLASH或EEPROM,EEPROM技術上的優勢是耐久性好,可以反復多次編程,最高可達100W次的擦寫循環,NOR FLASH相比EEPROM容量會更大,平均成本更好,但是壽命會少個0,最大只能到10W次的擦寫循環。
EEPROM(AT24C02)
FLASH(IS25WP032)
-
當數據量小于2MB時,就可以考慮將其放入MCU內部的FLASH中,一旦決定把數據放MCU內部FLASH時,就面臨兩個問題:
(1)MCU片內FLASH承諾的壽命更短,一般可能是1~5W次,好像也有幾百次的,鑒于大佬已經停線,這里就不點名了。關于這個參數切記要參考手冊,不同廠家的參數不一樣,同一廠家的不同系列也可能有差異
NXP Kinetis系列MCU
STM32 F103xx
(2) 擦寫過程可能需要關閉中斷,雖然這個不是必須的,但除非MCU的Datasheet明確有寫支持,絕大多數MCU都是有這方面的要求,并且IAP編程的函數需要運行于RAM或ROM中,因為擦寫過程中,如果MCU沒有特殊的設計(比如下圖NXP KinetisK64系列帶有雙Block flash是可以支持WWR),該過程是無法進行取指的,關中斷的目的是防止外部中斷觸發運行于FLASH上的ISR,如果用戶不希望關中斷,則必須要將可能發生中斷的函數Relocate到RAM中
//RAM中執行的編程函數 static status_t flash_command_sequence(flash_config_t *config) { uint8_t registerValue; __set_PRIMASK(1); #if FLASH_DRIVER_IS_FLASH_RESIDENT /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */ FTFx->FSTAT = FTFx_FSTAT_RDCOLERR_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_FPVIOL_MASK; status_t returnCode = flash_check_execute_in_ram_function_info(config); if (kStatus_FLASH_Success != returnCode) { __set_PRIMASK(0); return returnCode; } /* We pass the ftfx_fstat address as a parameter to flash_run_comamnd() instead of using * pre-processed MICRO sentences or operating global variable in flash_run_comamnd() * to make sure that flash_run_command() will be compiled into position-independent code (PIC). */ callFlashRunCommand((FTFx_REG8_ACCESS_TYPE)(&FTFx->FSTAT)); __set_PRIMASK(0); #else /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */ FTFx->FSTAT = FTFx_FSTAT_RDCOLERR_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_FPVIOL_MASK; /* clear CCIF bit */ FTFx->FSTAT = FTFx_FSTAT_CCIF_MASK; /* Check CCIF bit of the flash status register, wait till it is set. * IP team indicates that this loop will always complete. */ while (!(FTFx->FSTAT & FTFx_FSTAT_CCIF_MASK)) { } #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ /* Check error bits */ /* Get flash status register value */ registerValue = FTFx->FSTAT; /* checking access error */ if (registerValue & FTFx_FSTAT_ACCERR_MASK) { __set_PRIMASK(0); return kStatus_FLASH_AccessError; } /* checking protection error */ else if (registerValue & FTFx_FSTAT_FPVIOL_MASK) { __set_PRIMASK(0); return kStatus_FLASH_ProtectionViolation; } /* checking MGSTAT0 non-correctable error */ else if (registerValue & FTFx_FSTAT_MGSTAT0_MASK) { __set_PRIMASK(0); return kStatus_FLASH_CommandFailure; } else { __set_PRIMASK(0); return kStatus_FLASH_Success; } }
(3) 擦寫時間對系統的影響,之前講過擦寫過程是不能執行FLASH code的,所以勢必會讓系統pending住,而這個pending時間可以在Datasheet中尋找答案,一般擦除是按照sector/block大小來的,編程時按照word或者page大小來的,擦除時間一般更長,對系統影響更大。用戶需要考慮的是系統是否可以接受每個控制周期,等待1個擦除最小單位的編程時間,這是由于有可能需要編程的數據比較大,如果同一時間更新勢必會影響到控制周期,但如果把擦寫任務分配到每個控制周期,就可以將影響降低到最小,以NXPKinetis,擦除一個Sector典型值是14ms,每次寫入Longword(8字節)所需要的時間是65us,當需要升級的時候,在接收到升級命令的第一幀處理時,增加sector刪除命令,本次運算周期會增加14ms的pending時間,然后每周期編程8字節數據。如果系統需要將數據存在內部flash上,就必須接受某一個周期增加14ms的pending,隨著flash寫入次數的增多,14ms還會增大到114ms
在確定了上述問題之后就可以完成存儲設備的選型,但軟件處理還需要注意以下幾個要點,這些問題MCU廠家一般是不會提供解決方案的,需要用戶根據自己的需求來完成:
-
冗余備份:有些時候用戶需要更新正在使用的參數/固件,考慮到更新失敗的情況下,需要支持參數/固件版本回退,所以需要兩片備份區進行冗余備份。
-
Magic number or 校驗碼:Magic number一般就是在FLASH編程結束時候,寫一個位數較高的(64bit)值到固定地址,使用加載數據時,先判斷Magic number是否正確,以此判斷編程過程是否完整,切記Magic number要在編程時先擦后寫(第一個擦,最后一個寫),否則無法起到驗證效果。這種驗證方式比較初級,對于可靠性要求更高的場合,一般會使用校驗碼的方式(CRC或者MD5),特別是參數文件通過通信的方式傳輸到MCU中,雖然通信過程可能也有校驗(比如Modbus RTU的CRC),但是無法保證數據在RAM緩沖區不發生位翻轉的情況,大多數MCU都不支持ECC功能,在這種情況下是無法糾錯的,如果對端設備會將文件的校驗碼發過來進行校驗,就可以避免該問題的發生,雖然RAM出現位翻轉的概率非常低,但是如果發生位翻轉的參數是設備的保護點或者PWM死區值,一旦出現錯誤,就可能會發生設備故障或損毀,甚至出現安全事故。
-
編程過程掉電或復位:在編程的過程中出現掉電或者復位是經常出現的一種異常情況。比如震動導致電源接觸不良,或者系統異常導致看門狗無法喂狗都有可能出現,還有使用POE電源對端設備直接斷電都有可能造成這種異常。所有一定要考慮在這種情況下的異常處理,比如上電加載數據的時候,如果校驗失敗,可以使用一組安全數據或者更新前的數據。對于帶操作系統的應用,建議硬件添加系統掉電檢測電路,在檢測到掉電事件(如24V掉電)發生時,如果當前沒有寫入Flash,則lock住寫入進程,如果當前正在寫入Flash,則立即調用sync函數,盡快將數據從緩存寫入Flash(硬件上MCU VDD加個稍微大點的電容,多扛一段時間),不要等待系統后臺寫入。
-
二次編程:有些MCU內部的Flash是帶有校驗機制的,對于同一地址在擦除完成后,只能進行一次編程,如果進行二次編程寫入不同數值進去,可能會除非校驗失敗,導致該地址無法正常讀寫。
總結,這里列了一個表格,當需要IAP的時候,可以根據所選芯片的參數判斷是否滿足自身系統的需求(下表已經填入示例數據):
NVM | 擦除編程最小單元 | 擦除編程所用時間 | 擦除編程壽命 | 編程過程是否需要關中斷 | 編程數據的校驗 | 編程過程中掉電/復位 |
---|---|---|---|---|---|---|
EEPROM | 不需要擦,可以按字節或者Page寫入 | 寫周期5ms | 1000000 | 不需要 | 軟件添加 | 軟件添加 |
NOR FLASH | Sector = 4K, 最小寫入Page = 256B | Sector擦70ms,Page寫0.2ms | 100000 | 不需要 | 軟件添加 | 軟件添加 |
MCU FLASH | Sector = 2KB, 最小寫入8Byte | Sector擦14ms,寫65us | 50000 | 需要 | 軟件添加 | 軟件添加 |
-
mcu
+關注
關注
146文章
17343瀏覽量
352702 -
FlaSh
+關注
關注
10文章
1644瀏覽量
148706 -
數據
+關注
關注
8文章
7154瀏覽量
89615
原文標題:你真的會在Flash上存數據么
文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
FLASH數據丟失的解決方法
vca821按照數據手冊上仿真的AGCloop,請問頂部失真和直流偏置的原因是什么?
求助,如何清除provisioning的數據?
NAND Flash上的Vpp是什么?有何功能?
STM32C8T6的GPIO口和電源引腳短路是否能讀取FLASH數據?
知存科技助力AI應用落地:WTMDK2101-ZT1評估板實地評測與性能揭秘
存內計算芯片研究進展及應用
![<b class='flag-5'>存</b>內計算芯片研究進展及應用](https://file1.elecfans.com/web2/M00/E6/DF/wKgaomZFtOWAUuK5AA-8Vgn6BQ0843.png)
評論