前言
存儲協議棧負責ECU中非易失性數據的存儲管理。存儲協議棧的分享包括NVM、MemI、Ea、Fea、Eep、Fls模塊的詳細介紹及代碼分析,具體的項目實戰請關注本號的后續文章,本篇為NVRAM Manager(NVM)模塊詳細介紹篇(二)。
?
?
正文
3.5 功能需求 Functional requirements
對于每個異步請求,在任務完成后通知調用者應該是一個可配置選項。
NvM模塊應提供一個回調接口。
?
提示:NvM模塊的環境只能通過NvM模塊訪問非易失性內存。不允許任何模塊(除了NvM模塊)直接訪問非易失性內存。
?
NvM模塊只提供了一種隱式的方式來訪問NVRAM和共享內存(RAM)中的塊。這意味著,NvM模塊將一個或多個塊從NVRAM復制到RAM,反之亦然。
?
應用程序直接訪問RAM數據,根據給定的限制(例如同步)。
?
NvM模塊將對所有異步的“單塊”讀/寫/控制請求進行排隊,如果具有特定ID的塊尚未排隊或正在進行(多任務限制)。
?
只要不發生隊列溢出,NvM模塊將接受多個異步的“單塊”請求。
?
優先級最高的請求將由NvM模塊從隊列中獲取,并以序列化的順序處理。
?
NvM模塊應該實現隱式機制來對保存在NV內存中的數據進行一致性/完整性檢查。
?
根據內存堆棧的實現,NvM模塊提供和/或調用的回調例程可能在中斷上下文中被調用。
?
提示:提供在中斷上下文中調用的例程的NvM模塊因此必須確保它們的運行時間相當短。
?
如果在配置時沒有默認的ROM數據可用,或者沒有NvMInitBlockCallback定義的回調,那么應用程序將負責提供默認的初始化數據。
?
在這種情況下,應用程序必須使用NvM_GetErrorStatus()來區分首次初始化和損壞的數據。
?
在處理NvM_ReadAll的過程中,NvM模塊應該能夠通過執行校驗和計算來檢測損壞的RAM數據。
?
在處理NvM_ReadAll的過程中,NvM模塊應該能夠通過測試管理塊內數據的有效性來檢測RAM中的無效數據。
?
在啟動階段和NvM_ReadAll的正常運行期間,如果NvM模塊在NV塊內檢測到不可恢復的錯誤,NvM模塊將復制默認數據(如果配置)到相應的RAM塊。
?
為了使用OS服務,NvM模塊只能使用BSW調度器,而不能直接使用OS對象和/或相關的OS服務。
?
3.6 NVM啟動 NVRAM manager startup
NvM_Init應該由ECU狀態管理器獨占調用。
?
由于ECU啟動時間的強約束,NvM_Init請求不能包含配置的NVRAM塊的初始化。
NvM_Init請求不負責觸發底層驅動和內存硬件抽象的初始化。這也應由EcuM處理。
內存數據塊的初始化應該由另一個請求完成,即NvM_ReadAll。
?
如果使用EcuM Fixed, NvM_ReadAll將由EcuM調用,如果使用EcuM Flex,則由集成代碼調用。
?
使用NvM模塊的軟件組件應負責檢查由于NvM模塊啟動而產生的全局錯誤/狀態信息。ECU狀態管理器應該通過使用NvM_GetErrorStatus(預留塊ID 0)或回調通知(可配置選項NvM_MultiBlockCallback)來輪詢啟動過程中產生的全局錯誤/狀態信息。如果使用輪詢,NVRAM啟動過程的結束將由全局錯誤/狀態NVM_REQ_OK或NVM_REQ_NOT_OK檢測(在啟動過程NVM_REQ_PENDING期間)。如果回調被選擇用于通知,如果指定的NVRAM塊已被處理,軟件組件將被自動通知。
?
注1:如果回調被配置為每個NVRAM塊在NvM_ReadAll內處理,它們可以被RTE在早期的時間點啟動,例如SW-Cs。
?
注2:為了確保DEM在早期完全運行,即它的NV數據被恢復到RAM中,與DEM相關的NVRAM塊應該配置為低ID,在NvM_ReadAll中首先處理。
?
NvM模塊不能以持久的方式自動存儲當前使用的Dataset索引。軟件組件應該檢查他們負責的所有塊的特定錯誤/狀態,使用帶有特定塊id的NvM_GetErrorStatus來確定對應RAM塊的有效性。
?
對于塊管理類型為“NVRAM數據集”的所有塊,軟件組件應負責通過NvM_SetDataIndex設置適當的索引位置。例如,當前索引位置可以被軟件組件存儲/維護在一個唯一的NVRAM塊中。為了獲得“數據集塊”的當前索引位置,軟件組件應該使用NvM_GetDataIndex API調用。
?
3.7 NVM關機 NVRAM manager shutdown
基本的關閉過程應該由請求NvM_WriteAll完成。
?
提示:NvM_WriteAll將被ECU狀態管理器調用
?
3.8 對NvM模塊的并行寫訪問 Parallel write access to the NvM module
NvM模塊應該通過一個使用排隊機制的異步接口來接收請求。NvM模塊將根據請求的優先級順序處理所有請求。
?
3.9 NVM一致性檢查 NVRAM block consistency check
NvM模塊應該提供隱式的技術來檢查NVRAM塊的數據一致性。
?
NVRAM塊的數據一致性檢查應通過CRC對其相應的NV塊進行重新計算來完成。
數據一致性檢查的隱式方式應由內部功能的可配置選項提供。隱式一致性檢查對每個NVRAM塊都是可配置的,依賴于可配置的參數NvMBlockUseCrc和NvMCalcRamBlockCrc。
?
當NVRAM塊的NvMWriteBlockOnce = TRUE時,應該啟用NVRAM塊校驗NvMBlockUseCrc。當NVRAM塊的NvMWriteBlockOnce = TRUE時,應該禁用NVRAM塊的NvMBlockWritePort,以便在CRC檢查失敗的情況下,用戶可以向NVRAM塊寫入數據。
?
根據可配置參數NvMBlockUseCrc和NvMCalcRamBlockCrc, NvM模塊將為使用的最大CRC分配內存。
?
提示:NvM用戶必須不知道關于CRC內存(例如大小,位置)的任何東西,為他們的數據在RAM塊。
?
3.10 錯誤恢復 Error Recovery
NvM模塊應該提供錯誤恢復的技術。錯誤恢復取決于NVRAM塊管理類型。
NvM模塊通過加載默認值,為每一種NVRAM塊管理類型提供讀取時的錯誤恢復。
?
NvM模塊將通過加載RAM塊的默認值,在讀取塊管理類型為 NVM_BLOCK_REDUNDANT的NVRAM塊時提供錯誤恢復。
?
無論NVRAM塊管理類型如何,NvM模塊都應該通過執行寫重試來提供寫時的錯誤恢復。
?
在RAM塊重新驗證失敗的情況下,NvM模塊應在啟動時為所有配置了RAM塊CRC的NVRAM塊提供讀取錯誤恢復。
?
3.11 用ROM數據恢復RAM塊
當NV塊出現不可恢復的數據不一致時,NvM模塊應提供隱式和顯式恢復技術,將ROM數據恢復到相應的RAM塊。
?
3.12 使用ROM默認數據隱式恢復RAM塊
在隱式恢復過程中,相應NV塊的數據內容保持不變。
?
在啟動(NvM_ReadAll的一部分)時不提供隱式恢復,當沒有配置ROM塊時(通過參數NvMRomBlockDataAddress或NvMInitBlockCallback),每個NVRAM塊都不提供NvM_ReadBlock或NvM_ReadPRAMBlock。
?
在以下情況下,在啟動(NvM_ReadAll的一部分)和NVRAM塊的NvM_ReadBlock或NvM_ReadPRAMBlock不會提供隱式恢復: (1)&&(2)
(1) 配置了ROM塊(通過參數nvromblockdataaddress或參數NvMInitBlockCallback)
(2) NvM模塊中的永久RAM塊或RAM鏡像的內容(在顯式同步的情況下)狀態是有效的,CRC(數據)是一致的。
?
在以下情況下,在啟動(NvM_ReadAll的一部分)和NVRAM塊的NvM_ReadBlock或NvM_ReadPRAMBlock不會提供隱式恢復: (1)&&(2)&&(3)
(1) 配置了ROM塊(通過參數nvromblockdataaddress或參數NvMInitBlockCallback)
(2) NvM模塊中的永久RAM塊或RAM鏡像的內容(在顯式同步的情況下)無效,CRC(數據)不一致。
(3) 從NV成功讀取嘗試。
?
在以下情況下,隱式恢復應該在啟動時(NvM_ReadAll的一部分)或者NVRAM塊的NvM_ReadBlock或NvM_ReadPRAMBlock時被提供:
(1)配置了ROM塊(通過參數nvromblockdataaddress或參數NvMInitBlockCallback)
(2)NvM模塊中的永久RAM塊狀態或RAM鏡像的內容(在顯式同步的情況下)是無效的,CRC(數據)不一致。
(3)從NV讀取失敗。
?
隱式恢復應該在NvM_ReadBlock()或NvM_ReadPRAMBlock()請求NVM_BLOCK_NATIVE和NVM_BLOCK_REDUNDANT類型的NVRAM塊時提供。
?
3.13 使用ROM默認數據顯式恢復RAM
對于使用ROM塊數據的顯式恢復,NvM模塊應該提供NvM_RestoreBlockDefaults和NvM_RestorePRAMBlockDefaults函數來將ROM數據恢復到相應的RAM塊。
?
NvM_RestoreBlockDefaults和NvM_RestorePRAMBlockDefaults函數不會修改對應NV塊的數據內容。
?
提示:應用程序每次需要將ROM數據恢復到相應的RAM塊時,使用NvM_RestoreBlockDefaults或NvM_RestorePRAMBlockDefaults函數。
?
3.14 檢測對NV塊的寫操作未完成
檢測NV塊的未完成寫操作不在NvM模塊的范圍之內。這是由內存硬件抽象處理和檢測的。NvM模塊期望從內存硬件抽象中獲取信息,如果引用的NV塊無效或不一致,并且在請求時無法讀取。
?
SW-Cs可能會使用NvM_InvalidateNvBlock來阻止底層傳遞舊數據。
?
3.15 終止單個塊請求
NvM模塊提供的所有異步請求(除了NvM_CancelWriteAll)都應該在相應的管理塊的指定的錯誤/狀態字段中指明結果。
?
可選配置參數NvMSingleBlockCallback在異步塊請求終止時通過回調來配置通知(NvM_CancelWriteAll除外)。
?
注意:在與應用SW-C通信時,NvMSingleBlockCallback需要映射到Rte_call_ _
?
3.16 終止一個多塊請求
NvM模塊應該使用一個單獨的變量來存儲異步多塊請求的結果(NvM_ReadAll, NvM_WriteAll包括NvM_CancelWriteAll, NvM_ValidateAll)。
?
函數NvM_GetErrorStatus將返回異步多塊請求(包括NvM_CancelWriteAll)的最新錯誤/狀態信息,并將保留的塊ID值設置為0。
?
多塊請求的結果只能代表一個常見的錯誤/狀態信息。
?
NvM模塊提供的多塊請求應在每個受影響的管理塊指定的錯誤/狀態字段中指明其詳細的錯誤/狀態信息。
?
可選配置參數NvMMultiBlockCallback在異步多塊請求終止時通過callback配置通知。
?
3.17 異步請求/作業處理的一般處理
每次在一個請求中處理CRC計算時,如果NVRAM塊的長度超過參數NvMCrcNumOfBytes.配置的字節數,NvM模塊就會分多次計算CRC。
?
對于CRC計算,NvM模塊應使用CRC模塊公布的初始值。
?
多個并發的單個塊請求應該是可排隊的。
?
NvM模塊將中斷異步請求/任務處理,優先處理具有即時優先級的任務(崩潰數據)。
?
如果在NvM模塊上調用異步函數導致作業隊列溢出,該函數將返回E_NOT_OK。
?
當一個請求成功進入隊列時,NvM模塊應該將對應NVRAM塊的請求結果設置為NVM_REQ_PENDING。
?
如果NvM模塊已經成功處理了一個任務,它將返回NVM_REQ_OK作為請求結果。
?
3.18 NVRAM塊寫保護
NvM模塊應該提供不同類型的寫保護,這些寫保護應該是可配置的。每一種寫保護都只與NVRAM塊的NV部分有關,即RAM塊數據可以修改,但不能寫入NV內存。
?
當“NvMWriteBlockOnce”為FALSE時,無論“ NvMBlockWriteProt”配置的值(True/ FALSE)是多少,使用“NvM_SetBlockProtection”功能都允許開啟/關閉寫保護。
?
當“NvMWriteBlockOnce”為TRUE時,無論“NvMBlockWriteProt”配置的值是(TRUE /False),使用NvM_SetBlockProtection功能都不允許開啟/關閉寫保護。
?
對于所有配置了NVRAM塊的NvMBlockWriteProt = TRUE, NvM模塊應該啟用默認寫保護。
?
NvM模塊的環境可以使用NvM_SetBlockProtection功能顯式地禁用寫保護。
?
對于配置了NvMWriteBlockOnce == TRUE的NVRAM塊,NvM模塊只能向相關的NV內存寫入一次,即在空白NV設備的情況下。
?
對于配置了NvMWriteBlockOnce == TRUE的NVRAM塊,NvM模塊不允許使用NvM_SetBlockProtection功能顯式地禁用寫保護。
?
對于配置了MVM_WRITE_BLOCK_ONCE (TRUE)的塊,NvM將拒絕第一個讀請求之前的任何寫/擦除/無效請求。
?
注意:如果重置,NvM管理塊中配置了NVM_WRITE_BLOCK_ONCE (TRUE)的塊的寫保護標志將被清除。為了重新激活該保護,必須在第一個寫/擦除/失效請求被處理之前讀取該塊,以便設置寫保護僅對有效且一致的塊有效。第一個讀請求可以作為單個塊請求完成,也可以作為NvM_ReadAll的一部分完成。
?
3.19 驗證和修改RAM塊數據
下圖描述了RAM塊的狀態轉換。
?
由于進入和保持一種狀態可以基于多種條件,而把它們都放在上面的圖中會讓人難以理解,所以在下面的小節中會提供更詳細的解釋。INVALID / CHANGED狀態沒有詳細說明,因為它永遠無法到達(如上圖所示)。
?
在初始化之后,RAM塊的狀態是INVALID/UNCHANGED,直到通過NvM_ReadAll更新它,這將導致轉換到VALID/UNCHANGED狀態。在這個狀態下,不允許WriteAll。如果調用了NvM_SetRamBlockStatus,這個狀態是左邊的。如果發生CRC錯誤,RAM塊再次改變到無效狀態,這可以通過隱式或顯式錯誤恢復機制離開。錯誤恢復后,塊的狀態是VALID/CHANGED,因為RAM的內容不同于NVRAM內容。
?
如果修改RAM塊狀態的API已經配置好了(通過NvMSetRamBlockStatusApi或NvMBlockUseSetRamBlockStatus), NvM模塊在寫入一個RAM塊或NvM模塊中的RAM鏡像時(在顯式同步的情況下),NvM模塊應將其視為有效且被修改,即在NvM_WriteAll期間,NvM模塊應將每個永久RAM塊寫入NV內存。
?
如果修改RAM塊狀態的API已經配置好了(通過vmsetramblockstatusapi或
NvMBlockUseSetRamBlockStatus) NvM模塊在讀取RAM塊時將其視為無效的,即在NvM_ReadAll期間,NvM模塊將每個NVRAM塊復制到RAM中,如果配置了相應的NVRAM塊。
?
如果塊讀取嘗試失敗,則應用程序負責在下一次寫嘗試之前提供有效的數據。
如果一個RAM塊成功地復制到NV內存,那么RAM塊的狀態將被設置為“有效/未修改”。
?
3.19. 1 The VALID / UNCHANGED state
這種狀態意味著RAM塊的內容要么與相應的NV塊的內容相同,要么——如果應用程序已經訪問了RAM塊——還沒有表明潛在的變化。對于DATASET塊,這些條件適用于最后處理的實例的RAM內容。另外,最后一個塊操作是成功的,并且該塊沒有被請求無效。
?
要進入 VALID / UNCHANGED狀態,至少必須發生以下任一情況:
1)?NvM_ReadAll()成功讀取塊
2)?該塊的NvM_ReadBlock成功完成
3)塊的NvM_WriteBlock成功完成
4)?NvM_WriteAll()寫塊成功
?
同時滿足以下條件時,VALID / UNCHANGED狀態被保存:
-- 對BlockID的最后一次讀或寫是成功的(沒有錯誤,也沒有獲取默認數據)
-- 應用程序沒有表明RAM塊自上次讀或寫以來的潛在變化
?
3.19.2 The VALID / CHANGED state
這種狀態意味著RAM塊的內容可能與相應的NV塊的內容不同。對于DATASET塊,此條件適用于最后處理的實例的RAM內容。此外,對該塊的最后一個操作是成功的,并且該塊沒有被請求無效。塊所有者可以通知塊的潛在RAM內容發生了變化,從而導致塊狀態變為VALID / CHANGED。
?
要進入 VALID / CHANGED狀態,至少必須發生以下任一情況:
1. NvM_SetRamBlockStatus被調用時為TRUE
2. 對該塊調用NvM_WriteBlock
3.NvM_WriteAll也將處理該塊
4. 調用該塊的NvM_ReadBlock會給出默認數據
5. 為塊調用的NvM_RestoreBlockDefaults函數成功完成
6. 當處理該塊時,NvM_ReadAll給出默認數據
7. NvM_ValidateAll成功處理了該塊
?
滿足以下任一條件時,VALID / CHANGED狀態被保存:
-- 塊所有者指出了RAM塊的潛在變化
-- 在上次讀取時,會(隱式或顯式地)為塊檢索默認數據
?
3.19.3 The INVALID / UNCHANGED state
這種狀態意味著NV塊無效。對于DATASET塊,這意味著NV塊內容對于處理的最后一個實例無效。
?
要進入 INVALID / UNCHANGED狀態,至少必須發生以下任一情況:
1. 調用NvM_SetRamBlockStatus時為該塊設置FALSE
2. NvM_ReadBlock表示用戶請求塊無效
3.NvM_ReadBlock表示塊的數據損壞(如果配置了CRC)
4. NvM_ReadBlock表示該塊的StaticID錯誤(如果配置了)
5. 該塊的NvM_WriteBlock完成不成功
6. NvM_WriteAll寫塊不成功
7. 該塊的NvM_InvalidateNvBlock成功完成
8. 該塊的NvM_EraseNvBlock成功完成
?
滿足以下任一條件時,INVALID / UNCHANGED狀態被保存:
-- 塊的狀態在當時是未知的(早期初始化,直到ReadAll或第一個操作請求一個給定的塊)
-- 該塊被檢測到損壞或錯誤的StaticID
-- 對該塊的最后一次成功操作是無效的
-- 當前讀取失敗,沒有默認數據
--- 對該塊的最后一次成功操作是刪除操作
?
3.20 應用程序和NVRAM Manager之間的通信和隱式同步
為了最小化鎖/解鎖的開銷或使用其他同步方法,應用程序和NvM模塊之間的通信必須遵循下面描述的嚴格的步驟序列。這確保了應用程序和NvM模塊之間的可靠通信,避免了RAM塊中的數據損壞,并保證了適當的同步。
?
此訪問模型假設雙方參與了與RAM塊的通信:應用程序和NvM模塊。
?
如果多個應用程序都在使用同一個RAM塊,NvM模塊就不能確保RAM塊的數據完整性。在這種情況下,應用程序必須同步它們對RAM塊的訪問,并且必須保證在NVRAM期間不會發生對RAM塊不合適的訪問操作。
?
特別是當幾個應用程序通過使用(不同的)臨時RAM塊來共享一個NVRAM塊時,應用程序之間的同步會變得更加復雜,而且NvM模塊也不會處理這個問題。在使用回調作為通知方法的情況下,可能會發生這樣的情況:應用程序獲得一個通知,盡管該請求尚未由該應用程序發起。所有申請必須遵守以下規則。
?
3.20.1 寫請求(NvM_WriteBlock or NvM_WritePRAMBlock)
應用程序和NVRAM?Manager之間的隱式同步在寫請求時必須遵守以下規則:
1)應用程序用NvM模塊必須寫入的數據填充RAM塊
2)應用程序發出NvM_WriteBlock或NvM_WritePRAMBlock請求,將控制權轉移給NvM模塊。
3)從現在開始,應用程序不得修改RAM塊,直到發出或通過輪詢獲得請求的成功或失敗。在此期間,可以讀取RAM塊的內容。
4)應用程序可以使用輪詢來獲取請求的狀態,也可以通過回調函數異步獲得通知。
5)在完成NvM模塊操作后,RAM塊可用于修改。
?
3.20.2 讀請求(NvM_ReadBlock or NvM_ReadPRAMBlock)
在應用程序和NVRAM?Manager之間進行隱式同步時,應用程序必須遵守以下規則:
1)應用程序提供了一個RAM塊,必須用NvM模塊側的NVRAM數據來填充它。
2)應用程序發出NvM_ReadBlock請求,將控制權轉移給NvM模塊。
3)從現在開始,在請求成功或失敗被通知或通過輪詢派生之前,應用程序不能讀寫RAM塊。
4)應用程序可以使用輪詢來獲取請求的狀態,也可以通過回調函數得到通知。
5)在完成NvM模塊操作之后,RAM塊就可以使用新數據供應用程序使用。
3.20.3 恢復默認請求(NvM_RestoreBlockDefaults and NvM_RestorePRAMBlockDefaults)
在恢復應用程序和NVRAM?Manager之間隱式同步的默認請求時,應用程序必須遵守以下規則:
1)?應用程序提供了一個RAM塊,它必須用來自NvM模塊端的ROM數據填充。
2)應用程序發出NvM_RestoreBlockDefaults或NvM_RestorePRAMBlockDefaults請求,將控制權轉移到NvM模塊。
3)從現在開始,在請求成功或失敗被通知或通過輪詢派生之前,應用程序不能讀寫RAM塊。
4)?應用程序可以使用輪詢來獲取請求的狀態,也可以通過回調函數得到通知。
5)?在完成NvM模塊操作之后,RAM塊就可以與ROM數據一起供應用程序使用。
3.20.4 多塊讀請求 (NvM_ReadAll)
如果使用EcuM Fixed,這個請求只能由ECU狀態管理器觸發;如果在系統啟動時使用EcuM Flex,則只能由集成代碼觸發。這個請求用啟動所需的數據填充所有配置的永久RAM塊。
?
如果請求失敗或請求處理僅部分成功,NVRAMManager將此條件信號給DEM,并向EcuM返回一個錯誤。DEM和EcuM必須決定采取進一步的措施。這些步驟在DEM和ECU狀態管理器的模塊中處理。
?
在應用程序和NVRAM?Manager之間進行隱式同步的多塊讀請求時,應用程序必須遵守以下規則:
ECU狀態管理器發出NvM_ReadAll。
-- ECU狀態管理器可以使用輪詢來獲取請求的狀態,也可以通過回調函數得到通知。
-- 在NvM_ReadAll過程中,一個單獨的塊回調(如果配置)將在處理完一個NVRAM塊之后被調用。這些回調使RTE能夠單獨啟動每個SW-C。
?
3.20.5 多塊寫請求(NvM_WriteAll)
這個請求只能由ECU狀態管理器在系統關閉時觸發。這個請求將所有修改后的永久RAM塊的內容寫入NV內存。通過僅在ECU關閉期間調用該請求,ECU狀態管理器可以確保在操作結束之前沒有SW組件能夠修改RAM塊中的數據。這些措施在EcuM中處理。
在應用程序和NVRAM管理器之間進行隱式同步的多塊寫請求時,應用程序必須遵守以下規則:
1. EcuM發出NvM_WriteAll請求,該請求將控制權轉移給NvM模塊。
2. EcuM可以使用輪詢來獲取請求的狀態,也可以通過回調函數得到通知。
3.20.6 刪除操作 (NvM_CancelWriteAll)
這個請求取消了一個掛起的NvM_WriteAll請求。這是一個異步請求,可以調用它來終止一個掛起的NvM_WriteAll請求。
?
NvM_CancelWriteAll請求只能被EcuM使用。
3.20.7 管理塊的修改 Modification of administrative blocks
為了管理目的,管理塊是每個配置NVRAM塊的一部分。
?
如果NVRAM塊有一個待處理的單塊操作,應用程序不允許調用任何修改管理塊的操作,如NvM_SetDataIndex, NvM_SetBlockProtection, NvM_SetRamBlockStatus,直到待處理的作業完成。
3.21 NVRAM塊的正常和擴展運行時準備
根據兩個配置參數NvMDynamicConfiguration和NvMResistantToChangedSw, NVRAM管理器在啟動過程中會以不同的方式運行,例如在處理請求 NvM_ReadAll()時。
?
如果NVRAM NvMDynamicConfiguration設置為FALSE, NVRAM管理器將忽略存儲的配置ID,繼續正常運行時準備NVRAM塊。在這種情況下,RAM塊應檢查其有效性。如果RAM塊內容被檢測為無效,則應檢查NV塊的有效性。一個被檢測到有效的NV塊將被復制到指定的RAM塊中。如果檢測到無效的NV塊,將加載默認數據。如果NvMDynamicConfiguration設置為TRUE,并且檢測到配置ID不匹配,則需要對那些配置了NvMResistantToChangedSw(FALSE)的NVRAM塊進行擴展運行準備。在這種情況下,默認數據應該加載獨立的有效性分配RAM或NV塊。
?
3.22 應用程序和NVRAM管理器之間的通信和顯式同步
與應用程序和NvM模塊之間的隱式同步相比,顯式同步機制是可選的(即可配置的)。它是通過NvM模塊中的RAM鏡像實現的。通過NvM模塊調用的回調例程,應用程序在兩個方向上傳輸數據。
?
以下是對這種機制的簡短分析:
-- 優點是應用程序可以以更好的方式控制它們的數據。它們負責從NvM模塊的RAM鏡像中復制一致的數據,因此它們知道時間點。RAM塊不會因為并發訪問而處于不一致的狀態。
-- 缺點是額外的RAM需要與使用這種機制的最大NVRAM塊相同的大小,并且每個操作都需要在兩個RAM位置之間進行額外的拷貝。
?
這種機制特別允許不同應用程序共享NVRAM塊,如果有一個模塊對這些應用程序進行同步,并且從NvM模塊的角度來看,它是NVRAM塊的所有者。
?
對于每個NVRAM塊,都應該有可能通過參數NvMBlockUseSyncMechanism來配置顯式同步機制的使用。
?
如果沒有配置塊使用顯式的同步機制,NvM模塊不能分配RAM鏡像。
?
如果至少有一個塊被配置為使用顯式同步機制,NvM模塊應該只分配一個RAM鏡像。這個RAM鏡像不能超過配置為使用顯式同步機制的最長NVRAM塊的大小。
?
NvM模塊應該使用內部鏡像作為所有讀寫NVRAM塊的RAM塊的操作的緩沖區,這些NVRAM塊帶有NvMBlockUseSyncMechanism== TRUE。該緩沖區不能用于其他NVRAM塊。
?
NvM模塊需要調用NvMWriteRamBlockToNvM例程,以便使用NvMBlockUseSyncMechanism== TRUE將所有NVRAM塊的數據從RAM塊復制到鏡像。這個例程不能用于其他NVRAM塊。
?
NvM模塊需要調用NvM的NvMReadRamBlockFromNvM例程,以便用NvMBlockUseSyncMechanism == TRUE將所有NVRAM塊的數據從鏡像復制到RAM塊。這個例程不能用于其他NVRAM塊。
?
在單個塊請求過程中,如果例程NvMReadRamBlockFromNvM返回E_NOT_OK,那么NvM模塊應該重試例程調用NvMRepeatMirrorOperations次數。之后,單塊讀作業將塊特定的請求結果設置為NVM_REQ_NOT_OK,并向DEM報告NVM_E_REQ_FAILED。
?
在NvM例程返回E_NOT_OK的情況下,NvM模塊應該在下次調用NvM_MainFunction時重試例程調用。
?
在單個塊請求過程中,如果例程NvMWriteRamBlockToNvM返回E_NOT_OK,那么NvM模塊將重試例程調用NvMRepeatMirrorOperations次數。之后單塊寫作業將塊特定的請求結果設置為NVM_REQ_NOT_OK,并向DEM報告NVM_E_REQ_FAILED。
?
在這種情況下,NvMWriteRamBlockToNvM例程返回E_NOT_OK, NvM模塊應該在下次調用NvM_MainFunction時重試例程調用。
?
在一個多塊請求(NvM_WriteAll)中,如果例程NvMWriteRamBlockToNvM返回E_NOT_OK,那么NvM模塊將重試例程調用NvMRepeatMirrorOperations次數。之后,函數NvM_WriteAll的任務將block特定請求結果設置為NVM_REQ_NOT_OK,并向DEM報告NVM_E_REQ_FAILED。
?
在一個多塊請求(NvM_ReadAll)中,如果例程NvMReadRamBlockFromNvM返回E_NOT_OK,那么NvM模塊應該重試例程調用NvMRepeatMirrorOperations次數。之后NvM_ReadAll函數的任務將block特定請求結果設置為NVM_REQ_NOT_OK,并向DEM報告nvm_req_failed。
?
如果一個塊為它配置了顯式的同步,那么它一定沒有配置永久RAM映像。
?
3.22.1 寫請求(NvM_WriteBlock or NvM_WritePRAMBlock)
在寫請求過程中,應用程序和NVRAM?Manager之間必須遵循以下規則進行顯式同步:
1)?應用程序用NvM模塊必須寫入的數據填充RAM塊。
2) 應用程序發出NvM_WriteBlock或NvM_WritePRAMBlock請求。
3) 應用程序可能會修改內存塊,直到例程NvMWriteRamBlockToNvM被NvM模塊調用。
4)?如果例程NvMWriteRamBlockToNvM被NvM模塊調用,那么應用程序必須提供一個一致的RAM塊副本到NvM模塊請求的目的地。應用程序可以使用返回值E_NOT_OK來表示數據不一致。NvM模塊將接受這個NvMRepeatMirrorOperations次數,然后推遲請求并繼續它的下一個請求。
5)?延續僅當數據復制到NvM模塊時:
6)?從現在開始,應用程序可以再次讀寫RAM塊。
7)?應用程序可以使用輪詢來獲取請求的狀態,也可以通過回調例程異步獲得通知。
?
注意:如果請求了NvM_WriteBlock或NvM_WritePRAMBlock,但還沒有被NvM模塊處理,應用程序可能會將多個寫請求組合到一個RAM塊的不同位置。如果沒有調用回調例程NvMWriteRamBlockToNvM,則請求未被處理。
3.22.2 讀請求 (NvM_ReadBlock or NvM_ReadPRAMBlock)
在應用程序和NVRAM?Manager之間進行顯式同步時,應用程序必須遵守以下規則:
1)應用程序提供了一個RAM塊,必須用NvM模塊側的NVRAM數據來填充它。
2)應用程序發出NvM_ReadBlock或NvM_ReadPRAMBlock請求。
3)應用程序可能會修改RAM塊,直到NvM模塊調用NvMReadRamBlockFromNvM例程。
4)如果例程NvMReadRamBlockFromNvM被NvM模塊調用,那么應用程序將數據從NvM模塊指定的目的地復制到RAM塊。應用程序可以使用返回值E_NOT_OK來表示沒有復制數據。NvM模塊將接受這個NvMRepeatMirrorOperations次數,然后推遲請求并繼續它的下一個請求。
5)只有從NvM模塊復制數據時才會延續:
6)現在,應用程序在RAM塊中查找NV塊值。
7)應用程序可以使用輪詢來獲取請求的狀態,也可以通過回調例程得到通知。
?
注意:如果請求了NvM_ReadBlock或NvM_ReadPRAMBlock,但還沒有被NvM模塊處理,應用程序可能會將多個讀請求組合到一個NV塊的不同位置。如果回調例程NvMReadRamBlockFromNvM沒有被調用,請求就沒有被處理。
注意:NvM_RestoreBlockDefaults和NvM_RestorePRAMBlockDefaults的工作原理與NvM_ReadBlock類似。
?
3.22.3 多塊讀請求(NvM_ReadAll)
這個請求只能由EcuM在系統啟動時觸發。
這個請求用啟動所需的數據填充所有配置的永久RAM塊。
如果請求失敗或請求處理僅部分成功,NVRAMManager將此條件信號給DEM,并向EcuM返回一個錯誤。DEM和EcuM必須決定采取進一步的措施。這些步驟在DEM和EcuM中處理。
正常的操作:
1)?EcuM發出NvM_ReadAll。
2)?EcuM可以使用輪詢來獲取請求的狀態,也可以通過回調函數得到通知。
3)在NvM_ReadAll任務中,如果為一個塊配置了同步回調(NvM_ReadRamBlockFromNvm),它將被NvM模塊調用。在這個回調中,應用程序將從NvM模塊給出的目的地復制數據到RAM塊。應用程序可以使用返回值E_NOT_OK來表示沒有復制數據。NvM模塊將接受這個NvMRepeatMirrorOperations次數,然后報告讀取操作失敗。
4)現在,如果讀取操作成功,應用程序將在RAM塊中查找NV塊值。
5)?在NvM_ReadAll過程中,一個單獨的塊回調(如果配置)將在處理完一個NVRAM塊之后被調用。這些回調使RTE能夠單獨啟動每個SW-C。
?
3.22.4 多塊寫請求(NvM_WriteAll)
這個請求只能由EcuM在系統關閉時觸發。這個請求將所有修改后的永久RAM塊的內容寫入NV內存。通過僅在ECU關閉期間調用該請求,EcuM可以確保在操作結束之前沒有SW組件能夠修改RAM塊中的數據。這些措施在EcuM中處理。
正常的操作:
1)ECU狀態管理器發出NvM_WriteAll請求,該請求將控制權轉移給NvM模塊。
2)在NvM_WriteAll作業期間,如果為一個塊配置了一個同步回調(NvM_WriteRamBlockToNvM),它將被NvM模塊調用。在這個回調中,應用程序必須提供一個一致的副本將RAM塊發送到NvM模塊請求的目的地。應用程序可以使用返回值E_NOT_OK來表示數據不一致。NvM模塊將接受這個NvMRepeatMirrorOperations次數,然后報告寫操作失敗。
3)現在應用程序可以再次讀寫RAM塊了。
4)ECU狀態管理器可以使用輪詢來獲取請求的狀態,也可以通過回調函數得到通知。
3.23 靜態塊ID檢查
注意:NVRAM?Manager存儲NV塊頭,包括靜態塊ID在NV塊每次寫入NV內存的時候。當讀取一個塊時,將其靜態塊ID與請求的塊ID進行比較。這允許檢測導致讀取錯誤塊的硬件故障。
?
NVRAM?Manger應該在每次將塊寫入NV內存時存儲塊頭的靜態塊ID字段。
?
NVRAM?Manger應該在每次從NV內存讀取區塊時檢查區塊頭。
?
如果靜態塊ID檢查失敗,則向DEM報告失敗的NVM_E_WRONG_BLOCK_ID。
?
如果靜態塊ID檢查失敗,則啟動讀取錯誤恢復。
?
提示:配置時需要檢查,確保所有的Static Block id都是唯一的。
?
3.24 讀重試
如果NVRAM?Manger在從NV內存讀取操作期間檢測到失敗,CRC錯誤,那么在繼續讀取冗余NV塊之前,將進行一次或多次額外的讀取嘗試,如NVM_MAX_NUM_OF_READ_RETRIES配置的那樣。
?
如果NVRAM?Manger在從NV內存讀取操作期間檢測到失敗,CRC錯誤,那么在繼續讀取ROM塊之前,將進行一次或多次額外的讀取嘗試,如NVM_MAX_NUM_OF_READ_RETRIES所配置的。
?
如果NVRAM?Manger在從NV內存讀取操作中檢測到失敗,靜態塊ID檢查,然后在繼續讀取冗余的NV塊之前,根據NVM_MAX_NUM_OF_READ_RETRIES配置,進行一次或多次額外的讀取嘗試。
?
如果NVRAMManger在從NV內存讀取操作中檢測到一個失敗,一個靜態塊ID檢查,然后在繼續讀取ROM塊之前,根據NVM_MAX_NUM_OF_READ_RETRIES配置,進行一次或多次額外的讀取嘗試。
?
3.25 寫校驗
當一個RAM Block被寫入NV內存時,NV塊會被立即讀回來,并與RAM Block中的原始內容進行比較,前提是該行為被NVM_WRITE_VERIFICATION激活。
?
RAM Block中的原始內容與回讀的塊的比較應分步驟進行,以保證讀取和比較的字節數不大于配置參數NVM_WRITE_VERIFICATION_DATA_SIZE所指定的字節數。
?
如果RAM Block中的原始內容與讀回來的內容不相同,那么將向DEM報告生產代碼錯誤NVM_E_VERIFY_FAILED。
?
如果RAM塊中的原始內容與回讀不相同,則應按照本文檔的規定執行寫重試。
?
如果回讀操作失敗,則不應執行讀重試。
?
如果RAM塊中的原始內容與回讀不相同,對于初始的寫嘗試以及所有配置的重試,則NvM應將請求結果設置為NVM_REQ_NOT_OK。
?
3.26 比較NvM中的NV數據
為了避免在NV內存中進行不必要的寫操作,如果特定RAM塊的NV數據在運行時沒有更新,NvM模塊提供了一種基于CRC的比較機制,可以在處理寫作業時應用。
?
NvM模塊應該提供一個選項,通過實現基于CRC的比較機制來跳過寫入未改變的數據。
?
注意:一般來說,有一個風險,RAM塊的一些改變的內容導致相同的CRC作為初始內容,所以更新可能會丟失,如果使用這個選項。因此,這個選項應該只用于可以容忍這種風險的區塊。
?
對于每個NVRAM塊,都應該有可能通過參數NvMBlockUseCRCCompMechanism配置基于CRC比較機制的使用。
?
NvM模塊應該為NVRAM塊提供基于CRC的比較功能,且參數NvMCalcRamBlockCrc和NvMBlockUseCrc設置為true。
?
3.27 NvM和BswM交互
當NvM需要通知BswM一個多塊請求狀態變化時,它應該使用BswM API BswM_NvM_CurrentJobMode()。
?
如果NvMBswMMultiBlockJobStatusInformation為true, NvM將不會調用配置的多塊回調。
?
當NvM需要通知BswM單個塊請求接受(正在等待中)和結果時,它應該使用BswM API BswM_NvM_CurrentBlockMode()。
?
如果NvMBswMMultiBlockJobStatusInformation為true,當NvM接受一個多塊操作時,NvM應該通過調用BswM_NvM_CurrentJobMode(具有相關服務ID,作為模式,為NVM_REQ_PENDING)來通知BswM接受的多塊操作正在等待。
?
如果NvMBswMMultiBlockJobStatusInformation為true,當一個多塊操作結束或被取消時,NvM將通過調用BswM_NvM_CurrentJobMode,將多塊操作的結果通知給BswM,該BswM使用相關的服務ID和作為模式的多塊操作的結果。
?
如果NvMBswMBlockStatusInformation為true,當NvM接受單個塊操作時,NvM應該通過調用BswM_NvM_CurrentBlockMode(帶有相關的block ID和作為模式的NVM_REQ_PENDING)來通知BswM接受的單個塊操作正在等待。
?
如果NvMBswMBlockStatusInformation為true,當單個塊操作完成或被取消時,NvM將通過調用BswM_NvM_CurrentBlockMode將單個塊操作的結果通知BswM,該BswM調用帶有相關塊ID的BswM_NvM_CurrentBlockMode,作為模式,表示單個塊操作的結果。
?
如果NvMBswMBlockStatusInformation為true,并且NvM有一個正在進行的多塊操作,對于每一個由于多塊操作而處理的塊,NvM應該在開始處理該待處理的塊時通知BswM,通過調用BswM_NvM_CurrentBlockMode與相關的塊ID和作為模式的NVM_REQ_PENDING。
?
如果NvMBswMBlockStatusInformation為true,并且NvM有一個正在進行的多塊操作,對于每一個由于多塊操作而處理的塊,NvM應該通過調用BswM_NvM_CurrentBlockMode來通知BswM該塊處理完成的結果,該BswM使用相關的塊ID和作為模式的單塊操作的結果。
?
3.28 塊鎖定情況下的NvM行為
NvM_SetBlockLockStatus API服務只能被BSW組件使用,它沒有作為服務發布在SWC-Description中。因此,它將不能通過RTE訪問。
?
如果該API被調用時參數Locked為TRUE, NVM必須保證與BlockId標識的NVRAM塊相關的NV內容不會被任何請求修改。在NvM_WriteAll過程中,Block應該被跳過,其他的請求,如NvM_WriteBlock, NvM_WritePRAMBlock, NvM_InvalidateNvBlock, NvM_EraseNvBlock,應該被拒絕。
?
如果API被調用時參數Locked為TRUE, NVM應該保證在下次啟動時,在處理NvM_ReadBlock或NvM_ReadPRAMBlock時,這個NVRAM塊應該從NV內存中加載。
?
如果Locked參數的值為FALSE,則NVM必須保證該NVRAM塊按照AUTOSAR的規定正常處理。
?
使用該服務的設置不能被NvM_SetRamBlockStatus或NvM_SetBlockProtection改變。
?
3.28.1 用例
通過診斷服務為NVRAM塊保存新數據到NV內存。這些數據應在下一次ECU啟動時提供給swc (s),即它們既不能被來自swc的請求覆蓋,也不能在關機期間被永久RAM塊的數據覆蓋(NvM_WriteAll)。
?
3.28.2 使用(DCM)
1)DCM請求NvM_SetBlockLockStatus(
2)?DCM請求NvM_WriteBlock(
3)DCM輪詢完成寫請求(使用NvM_GetErrorStatus())
4)?當成功(NVM_REQ_OK), DCM發出NvM_SetBlockLockStatus(
審核編輯:湯梓紅
評論
查看更多