本文根據AUTOSAR4.4(Classic Platform)(https://www.autosar.org/standards/classic-platform/classic-platform-440/)標準中的 :
AUTOSAR_EXP_NVDataHandling.pdf
文章整理。僅爲個人理解,不當之處,還請指正,感謝!
目錄
3 支持的同步機制(Synchronization Mechanism)
4.4.1 During startup phase (NvM_ReadAll)
4.4.2 During shutdown phase (NvM_WriteAll)
4.5 Resistant to changed software
1 Acronyms and abbreviations
Abbreviation / Acronym: |
Description: |
NvM | NVRAM Manager |
NV | Non-volatile |
NVRAM | Non-volatile Random Access Memory |
NVRAM Block | The NVRAM Block is the entire structure, which is needed to administrate and to store a block of NV data. |
NV Block | The NV Block is a Basic Storage Object. It represents the part of a “NVRAM Block” which resides in the NV memory |
RAM Block | The RAM Block is a Basic Storage Object. It represents the part of a “NVRAM Block” which resides in the RAM. |
RAM Mirror | RAM mirrors are NvM internal buffer used for operations that read and write the RAM block of NVRAM blocks with NvMBlockUseSyncMechanism set TRUE. |
ROM Block | The ROM Block is a Basic Storage Object. It represents the part of a “NVRAM Block” which resides in the ROM. |
ROM | Read-Only Memory |
RTE | Runtime Environment |
SW-C | Software Component |
App | Application |
RTE | Run Time Environment |
2 NvM Stack Overview
![]()
上圖同時展示了整個 NvM Stack 的構成。
如上圖所示,AUTOSAR規定,App只能通過NvM(NVRAM Manager)來訪問NV Memory(比如FLASH)。
3 支持的同步機制(Synchronization Mechanism)
根據App對NvM Block‘’s RAM的訪問方式,數據同步機制可以分爲兩種:
- 隱式同步(Implicit synchronization)
- 顯示同步(Explicit synchronization)
3.1 Implicit synchronization
AUTOSAR規範:在隱式同步機制下,一個NvM Block的 RAM 被映射到一個固定的 SWC,不建議共享RAM。 每當SW-C使用RAM block(temporary/permanent)訪問NVRAM時,都必須確保RAM塊的數據一致性,直到NvM完成正在進行的操作爲止。
說人話:
在隱式同步機制下,RAM block 和 SWC 之間是一一對應的關係,其他SWC不能訪問該RAM。SWC要保持數據的一致性是說,從SWC調用NvM接口到NvM內部操作完成前,SWC不能再改變該RAM中的值。但是該RAM可以被read。
補充(個人理解):
temporary RAM:一般指局部變量;
permanent RAM:一般指全局變量。
使用隱式同步機制時分參考步驟:
3.2 Explicit synchronization
AUTOSAR 規範:在顯式同步中,NvM會定義一個RAM mirror,用於與App的RAM block交換數據。 App將數據寫入RAM block,然後調用NvM Write API(NvM_WriteBlock / NvM_WritePRAMBlock)。 NvM 調用API(NvMWriteRamBlockToNvM)將數據從 RAM Block 拷貝到RAM Mirror,進而寫入 NV Block。
顯示同步的優點:
- App可以更好地管理自己的RAM block。在App調用NvM_WriteBlock / NvM_WritePRAMBlock 到NvM 調用NvMWriteRamBlockToNvM()這段期間,App仍然可以修改RAM block中的數據。
- 幾個SWC可以共享一個NvM Block;
顯示同步的缺點:
- 浪費內存:除了RAM block,又多了一個RAM Mirror(additional RAM),且RMA Mirror需要和使用顯示同步機制的最大的NvM Block 具有相同的大小;
- 多了一步RAM間的拷貝操作:即多了RAM block 和 RAM mirror之間的拷貝操作;
4. 其他機制
4.1 CRC 機制
NvM模塊內部使用CRC生成例程(8/16/32bit)來對 NvM Block 進行相關的檢查。當然是否使用CRC是可以配置的。NvM模塊內的配置選項爲 NvMBlockUseCRCCompMechanism,啓用後,如果將要寫入的數據(即RAM中的數據)沒有改變,則NvM寫入請求會被跳過。 基於此,使用CRC的風險在於:如果RAM中的數據內容改變了,但是改變前後計算得出的CRC一致,就會導致數據無法正常寫入。因此,此選項應僅用於可以容忍此風險的 NvM Block 。
4.2 錯誤恢復
4.2.1 對於 Read 操作的錯誤恢復機制
1. 隱式錯誤恢復:
NvM 模塊對於 Native 和 Redundant 類型的NvM Block 的 Read 操作提供隱式的錯誤恢復機制,即如果配置了 NvMRomBlockDataAddress 或者NvMInitBlockCallback,則加載對應的默認數據。
2. 顯示錯誤恢復:
對於任何管理類型(NATIVE,Redundant,dataset)的NvM Block,如果其配置了ROM數據,都可以使用顯示數據恢復機制來恢復數據,方法是調用 NvM_RestoreBlockDefaults()這個API。當然,對於 Dataset類型的NvM block,在調用API之前必須設置相應的Index(指向ROM Block)。
3. 其他
NvM 模塊對於Redundant 類型的NvM Block 的 Read 操作還提供一種錯誤恢復機制,即將默認數據加載到RAM中。
4.2.2 對於 Write 操作的錯誤恢復機制
即重新重寫寫操作,不區分NvM Block的管理類型。
4.3 寫驗證
寫驗證即爲,將RAM block中的數據寫入NV block後,立刻將其回讀並與RAM Block的原數據內容做比較,如果比較結果不一致:則再次執行寫操作,如果啓用DET,則同時迴向DEM模塊報告錯誤 NVM_E_VERIFY_FAILED;
如果回讀比較失敗,則不會再次執行讀操作。
4.4 NvMSetRamBlockStatusApi
4.4.1 During startup phase (NvM_ReadAll)
對於某些NVRAM塊,可能需要保留相應RAM塊的數據內容,以免其在NvM_ReadAll() 期間被覆蓋,尤其是在NV塊中的數據早於RAM塊中的數據的場景下(例如當RAM中的數據尚未寫入NV block時發生了熱復位)。 在這種情況下,必須將RAM block分配在復位安全(non-initialized)的RAM區域中,並且必須將配置參數CalcRamBlockCrc==TRUE 和 NvMSetRamBlockStatusApi==TRUE。(·CalcRamBlockCrc==TRUE,意味着相應的NV塊也具有/具有 CRC配置)
每當RAM中的數據發生變化時都需要調用NvM_SetRamBlockStatus(blockID,TRUE),NvM 模塊會重新計算RAM中的CRC並將其存儲在一個內部變量(該變量存儲在 reset-fase 區域)。當然前提 NVRAM Block 配置了PIM或啓用顯示同步機制。
在ReadAll()期間,會重新計算RAM的CRC,如果計算得出的CRC和之前存儲的CRC一致,則RAM block的內容不會改變。如果不一致,則會將NV Block中的值讀到RAM中(即RAM會重寫),如果讀失敗,則會將使用默認數據恢復RAM(即將ROM中的值讀到RAM中或者調用InitBlock )
4.4.2 During shutdown phase (NvM_WriteAll)
如果 NvMSetRamBlockStatusApi == FALSE,則 NvM_WriteAll() 會將所有 NVRAM Block 的RAM的內容拷貝到 NV Block中。當然前提是的這些 NVRAM Block 的要求配置: NvMSelectBlockForWriteAll ==TRUE 並且 配置了NvMRamBlockDataAddress 或者使用顯示同步機制。
當然,爲了提高 NvM_WriteAll() 的速度,我們可以將那些只有 RAM Block的內容發生變化的 NVRAM Block寫到 NV Memory中,這就需要配置 NvMSetRamBlockStatusApi==TRUE。這種場景下,每當 RAM中的內容發生變化時,用戶就需要調用 NvM_SetRamBlockStatus(BlockID, TRUE),從而告訴 NvM 模塊在 NvM_WriteAll()時要處理該 NVRAM Block。
4.5 Resistant to changed software
NvM 模塊的 start-up(即NvM_ReadAll() 的處理過程)行爲受2個配置參數 NvMDynamicConfiguration 和 NvMResistantToChang 的影響。
在ECU項目中,如果如何處理NVRAM block的配置變更並不重要,則必須配置參數 NvMDynamicConfiguration==FALSE。對於每個NVRAM Block 的配置參數NvMCalcRamBlockCrc:
- NvMCalcRamBlockCrc == FALSE,直接檢查NV block 的有效性(validty)。 如果檢測結果爲:
- NV Block有效,則將NV block中的數據加載到 其對應的RAM Block。
- NV Block無效,則將默認數據加載到RAM中(默認數據通過參數NvMRomBlockDataAddress或參數NvMInitBlockCallback進行配置)。
- NvMCalcRamBlockCrc == TRUE ,NvM首先檢查其 RAM block 的有效性(validty)。 如果檢測結果爲:
- RAM block內容有效,不再檢查NV block 的有效性,也不再從NV Block加載數據。
- RAM block內容無效,則繼續檢查NV block 的有效性。 如果:
- NV Block無效,則將默認數據加載到RAM中(默認數據通過參數NvMRomBlockDataAddress或參數NvMInitBlockCallback進行配置)。
- NV Block有效,則將NV block中的數據加載到 其對應的RAM Block。
如果更改了NVRAM block 的配置,而已經存儲在NV memory(比如FLASH)中的 NV block 仍與舊配置相對應,則在NvM_ReadAll()過程中可能會出現嚴重問題。 例如,當添加新的NVRAM塊時,許多其他塊的標識符可能會隱式更改,這可能導致從NV存儲器讀取錯誤的數據。
在這種情況下,可以配置NvM模塊,使其不使用NV memory 中的數據初始化RAM block。即配置參數 NvMDynamicConfiguration == TRUE。 這時候集成商要修改配置參數NvmCompiledConfigID 從而告訴 NvM模塊 NVRAM配置已經更改。 NvM模塊使用單獨的NVRAM block 將 NvmCompiledConfigID 的值存儲在NV memory中。 每次執行啓動過程(NvM_ReadAll)時,NvM模塊都會將存儲在NV memory中的值與配置參數NvmCompiledConfigID的值進行比較。 如果兩個值不相同,則NV memory 中的值將在下一個shutdown過程(NvM_WriteAll)中被新的配置值所覆蓋。
在這種情況下,NvM 在 NvM_ReadAll()過程中會根據配置參數 NvMResistantToChangedSw 來決定如何初始化 NVRAM Blocks:
- NvMResistantToChangedSw == FALSE:不管 RAM Block是否有效,都將忽略NV Block中的值,使用默認數據(ROM或InitBlockCallback)加載RAM Block,則必須配置 ;
- NvMResistantToChangedSw == TRUE:必須將 NV Block中的數據加載到RAM中,即便是在配置變更的情況下。如此,NvM模塊會像沒有發生配置變更一樣處理 NvM_ReadAll()。
因此,一旦將某個 NVRAM Block 配置爲 NvMResistantToChangedSw == TRUE,則集成商必須確保在ECU的整個生命週期內不得更改以下配置參數,否則可能將無法成功地從NV memory 中恢復數據:
- NvMResistantToChangedSw (must not be changed from TRUE to FALSE)
- ShortName
- NvMBlockUseCrc
- NvmBlockCrcType (if NvMBlockUseCrc is set to TRUE)
- NvMStaticBlockIDCheck
- NvmNvramDeviceId
- NvmBlockManagementType
- NvmNvBlockLength
- NvmNvBlockBaseNumber
注意:根據所使用的NvM,Fee和Ea模塊的具體實現,可能會施加其他約束。 請參考相應的用戶手冊。
總結一下:
NvMNvM_ReadAll()的過程如下:
- 首先檢查NvmCompiledConfigID,看從NV Block中讀出的ID和現在配置的ID(RAM中)是否一致:
- 一致,認爲沒有發生配置變更,正常加載所有NVRAM Block。
- 不一致,認爲發生了配置變更,首先檢查配置參數 NvMDynamicConfiguration:
- NvMDynamicConfiguration == FALSE,配置已變更,不會讀取NV Block中的值到RAM,使用默認數據(ROM或InitBlockCallback)加載RAM Block(具體過程待定,要結合NvM模塊的具體實現);
- NvMDynamicConfiguration==TRUE,對於每一個 NVRAM Block,查看參數 NvMResistantToChangedSw:
- NvMResistantToChangedSw == FALSE,不管 RAM Block是否有效,都將忽略NV Block中的值,使用默認數據(ROM或InitBlockCallback)加載RAM Block;
- NvMResistantToChangedSw == TRUE,將 NV Block中的數據加載到RAM中,NvM模塊會像沒有發生配置變更一樣處理 NvM_ReadAll()。