NVRAM Manager(NVM)模块详细介绍

NVRAM Manager(NVM)模块详细介绍,第1张

 

前言

存储协议栈负责ECU中非易失性数据的存储管理。存储协议栈的分享包括NVMMemIEaFeaEepFls模块的详细介绍及代码分析,具体的项目实战请关注本号的后续文章,本篇为NVRAM Manager(NVM)模块详细介绍篇(二)。


 

NVRAM Manager(NVM)模块详细介绍,e67939c6-3481-11ed-ba43-dac502259ad0.png,第2张

 

正文

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_OKNVM_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索引。软件组件应该检查他们负责的所有块的特定错误/状态,使用带有特定块idNvM_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块都是可配置的,依赖于可配置的参数NvMBlockUseCrcNvMCalcRamBlockCrc

 

NVRAM块的NvMWriteBlockOnce = TRUE时,应该启用NVRAM块校验NvMBlockUseCrc。当NVRAM块的NvMWriteBlockOnce = TRUE时,应该禁用NVRAM块的NvMBlockWritePort,以便在CRC检查失败的情况下,用户可以向NVRAM块写入数据。

 

根据可配置参数NvMBlockUseCrcNvMCalcRamBlockCrc, NvM模块将为使用的最大CRC分配内存。

 

提示:NvM用户必须不知道关于CRC内存(例如大小,位置)的任何东西,为他们的数据在RAM块。

 

3.10 错误恢复 Error Recovery

NvM模块应该提供错误恢复的技术。错误恢复取决于NVRAM块管理类型

NvM模块通过加载默认值,为每一种NVRAM块管理类型提供读取时的错误恢复。

 

NvM模块将通过加载RAM块的默认值,在读取块管理类型为 NVM_BLOCK_REDUNDANTNVRAM块时提供错误恢复。

 

无论NVRAM块管理类型如何,NvM模块都应该通过执行写重试来提供写时的错误恢复。

 

RAM块重新验证失败的情况下,NvM模块应在启动时为所有配置了RAMCRCNVRAM块提供读取错误恢复。

 

3.11 ROM数据恢复RAM

NV块出现不可恢复的数据不一致时,NvM模块应提供隐式和显式恢复技术,将ROM数据恢复到相应的RAM

 

3.12 使用ROM默认数据隐式恢复RAM

在隐式恢复过程中,相应NV块的数据内容保持不变

 

在启动(NvM_ReadAll的一部分)时不提供隐式恢复,当没有配置ROM块时(通过参数NvMRomBlockDataAddressNvMInitBlockCallback),每个NVRAM块都不提供NvM_ReadBlockNvM_ReadPRAMBlock

 

在以下情况下,在启动(NvM_ReadAll的一部分)NVRAM块的NvM_ReadBlockNvM_ReadPRAMBlock不会提供隐式恢复: 1&&2

1) 配置了ROM(通过参数nvromblockdataaddress或参数NvMInitBlockCallback)

2NvM模块中的永久RAM块或RAM镜像的内容(在显式同步的情况下)状态是有效的,CRC(数据)是一致的。

 

在以下情况下,在启动(NvM_ReadAll的一部分)NVRAM块的NvM_ReadBlockNvM_ReadPRAMBlock不会提供隐式恢复: 1&&2&&3

1) 配置了ROM(通过参数nvromblockdataaddress或参数NvMInitBlockCallback)

2NvM模块中的永久RAM块或RAM镜像的内容(在显式同步的情况下)无效,CRC(数据)不一致。

3) 从NV成功读取尝试。

 

在以下情况下隐式恢复应该在启动时(NvM_ReadAll的一部分)或者NVRAM块的NvM_ReadBlockNvM_ReadPRAMBlock时被提供

1)配置了ROM(通过参数nvromblockdataaddress或参数NvMInitBlockCallback)

2NvM模块中的永久RAM块状态或RAM镜像的内容(在显式同步的情况下)是无效的,CRC(数据)不一致。

3)从NV读取失败。

 

隐式恢复应该在NvM_ReadBlock()NvM_ReadPRAMBlock()请求NVM_BLOCK_NATIVENVM_BLOCK_REDUNDANT类型的NVRAM块时提供。

 

3.13 使用ROM默认数据显式恢复RAM

对于使用ROM块数据的显式恢复,NvM模块应该提供NvM_RestoreBlockDefaultsNvM_RestorePRAMBlockDefaults函数来将ROM数据恢复到相应的RAM块。

 

NvM_RestoreBlockDefaultsNvM_RestorePRAMBlockDefaults函数不会修改对应NV块的数据内容。

 

提示:应用程序每次需要将ROM数据恢复到相应的RAM时,使用NvM_RestoreBlockDefaultsNvM_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_

_ API

 

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 == TRUENVRAM块,NvM模块只能向相关的NV内存写入一次,即在空白NV设备的情况下。

 

对于配置了NvMWriteBlockOnce == TRUENVRAM块,NvM模块不允许使用NvM_SetBlockProtection功能显式地禁用写保护。

 

对于配置了MVM_WRITE_BLOCK_ONCE (TRUE)的块,NvM将拒绝第一个读请求之前的任何写/擦除/无效请求

 

注意:如果重置,NvM管理块中配置了NVM_WRITE_BLOCK_ONCE (TRUE)的块的写保护标志将被清除。为了重新激活该保护,必须在第一个写/擦除/失效请求被处理之前读取该块,以便设置写保护仅对有效且一致的块有效。第一个读请求可以作为单个块请求完成,也可以作为NvM_ReadAll的一部分完成。

 

3.19 验证和修改RAM块数据

下图描述了RAM块的状态转换。

 

NVRAM Manager(NVM)模块详细介绍,e6adb0a2-3481-11ed-ba43-dac502259ad0.png,第3张

由于进入和保持一种状态可以基于多种条件,而把它们都放在上面的图中会让人难以理解,所以在下面的小节中会提供更详细的解释。INVALID / CHANGED状态没有详细说明,因为它永远无法到达(如上图所示)

 

在初始化之后,RAM块的状态是INVALID/UNCHANGED,直到通过NvM_ReadAll更新它,这将导致转换到VALID/UNCHANGED状态。在这个状态下,不允许WriteAll。如果调用了NvM_SetRamBlockStatus,这个状态是左边的。如果发生CRC错误,RAM块再次改变到无效状态,这可以通过隐式或显式错误恢复机制离开。错误恢复后,块的状态是VALID/CHANGED,因为RAM的内容不同于NVRAM内容。

 

如果修改RAM块状态的API已经配置好了(通过NvMSetRamBlockStatusApiNvMBlockUseSetRamBlockStatus)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_WriteBlockNvM_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_RestoreBlockDefaultsNvM_RestorePRAMBlockDefaults请求,将控制权转移到NvM模块。

3从现在开始,在请求成功或失败被通知或通过轮询派生之前,应用程序不能读写RAM块。

4 应用程序可以使用轮询来获取请求的状态,也可以通过回调函数得到通知。

5 在完成NvM模块 *** 作之后,RAM块就可以与ROM数据一起供应用程序使用。

3.20.4 多块读请求 (NvM_ReadAll

如果使用EcuM Fixed,这个请求只能由ECU状态管理器触发;如果在系统启动时使用EcuM Flex,则只能由集成代码触发。这个请求用启动所需的数据填充所有配置的永久RAM块。

 

如果请求失败或请求处理仅部分成功,NVRAMManager将此条件信号给DEM,并向EcuM返回一个错误。DEMEcuM必须决定采取进一步的措施。这些步骤在DEMECU状态管理器的模块中处理。

 

在应用程序和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块的正常和扩展运行时准备

根据两个配置参数NvMDynamicConfigurationNvMResistantToChangedSw, NVRAM管理器在启动过程中会以不同的方式运行,例如在处理请求 NvM_ReadAll()时。

 

如果NVRAM NvMDynamicConfiguration设置为FALSE, NVRAM管理器将忽略存储的配置ID,继续正常运行时准备NVRAM块。在这种情况下,RAM块应检查其有效性。如果RAM块内容被检测为无效,则应检查NV块的有效性。一个被检测到有效的NV块将被复制到指定的RAM块中。如果检测到无效的NV块,将加载默认数据。如果NvMDynamicConfiguration设置为TRUE,并且检测到配置ID不匹配,则需要对那些配置了NvMResistantToChangedSw(FALSE)NVRAM块进行扩展运行准备。在这种情况下,默认数据应该加载独立的有效性分配RAMNV块。

 

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模块需要调用NvMNvMReadRamBlockFromNvM例程,以便用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_WriteBlockNvM_WritePRAMBlock请求。

3 应用程序可能会修改内存块,直到例程NvMWriteRamBlockToNvMNvM模块调用。

4 如果例程NvMWriteRamBlockToNvMNvM模块调用,那么应用程序必须提供一个一致的RAM块副本到NvM模块请求的目的地。应用程序可以使用返回值E_NOT_OK来表示数据不一致。NvM模块将接受这个NvMRepeatMirrorOperations次数,然后推迟请求并继续它的下一个请求。

5 延续仅当数据复制到NvM模块时:

6 从现在开始,应用程序可以再次读写RAM块。

7 应用程序可以使用轮询来获取请求的状态,也可以通过回调例程异步获得通知。

 

注意:如果请求了NvM_WriteBlockNvM_WritePRAMBlock,但还没有被NvM模块处理,应用程序可能会将多个写请求组合到一个RAM块的不同位置。如果没有调用回调例程NvMWriteRamBlockToNvM,则请求未被处理。

3.22.2 读请求 (NvM_ReadBlock or NvM_ReadPRAMBlock)

在应用程序和NVRAM Manager之间进行显式同步时,应用程序必须遵守以下规则:

1应用程序提供了一个RAM块,必须用NvM模块侧的NVRAM数据来填充它。

2应用程序发出NvM_ReadBlockNvM_ReadPRAMBlock请求。

3应用程序可能会修改RAM块,直到NvM模块调用NvMReadRamBlockFromNvM例程。

4如果例程NvMReadRamBlockFromNvMNvM模块调用,那么应用程序将数据从NvM模块指定的目的地复制到RAM块。应用程序可以使用返回值E_NOT_OK来表示没有复制数据。NvM模块将接受这个NvMRepeatMirrorOperations次数,然后推迟请求并继续它的下一个请求。

5只有从NvM模块复制数据时才会延续:

6现在,应用程序在RAM块中查找NV块值。

7应用程序可以使用轮询来获取请求的状态,也可以通过回调例程得到通知。

 

注意:如果请求了NvM_ReadBlockNvM_ReadPRAMBlock,但还没有被NvM模块处理,应用程序可能会将多个读请求组合到一个NV块的不同位置。如果回调例程NvMReadRamBlockFromNvM没有被调用,请求就没有被处理。

注意:NvM_RestoreBlockDefaultsNvM_RestorePRAMBlockDefaults的工作原理与NvM_ReadBlock类似。

 

3.22.3 多块读请求(NvM_ReadAll

这个请求只能由EcuM在系统启动时触发。

这个请求用启动所需的数据填充所有配置的永久RAM块。

如果请求失败或请求处理仅部分成功,NVRAMManager将此条件信号给DEM,并向EcuM返回一个错误。DEMEcuM必须决定采取进一步的措施。这些步骤在DEMEcuM中处理。

正常的 *** 作:

1 EcuM发出NvM_ReadAll

2 EcuM可以使用轮询来获取请求的状态,也可以通过回调函数得到通知。

3NvM_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中处理。

正常的 *** 作:

1ECU状态管理器发出NvM_WriteAll请求,该请求将控制权转移给NvM模块。

2NvM_WriteAll作业期间,如果为一个块配置了一个同步回调(NvM_WriteRamBlockToNvM),它将被NvM模块调用。在这个回调中,应用程序必须提供一个一致的副本将RAM块发送到NvM模块请求的目的地。应用程序可以使用返回值E_NOT_OK来表示数据不一致。NvM模块将接受这个NvMRepeatMirrorOperations次数,然后报告写 *** 作失败。

3现在应用程序可以再次读写RAM块了。

4ECU状态管理器可以使用轮询来获取请求的状态,也可以通过回调函数得到通知。

3.23 静态块ID检查

注意:NVRAM Manager存储NV块头,包括静态块IDNV块每次写入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的比较功能,且参数NvMCalcRamBlockCrcNvMBlockUseCrc设置为true

 

3.27 NvMBswM交互

NvM需要通知BswM一个多块请求状态变化时,它应该使用BswM API BswM_NvM_CurrentJobMode()

 

如果NvMBswMMultiBlockJobStatusInformationtrue, NvM将不会调用配置的多块回调。

 

NvM需要通知BswM单个块请求接受(正在等待中)和结果时,它应该使用BswM API BswM_NvM_CurrentBlockMode()

 

如果NvMBswMMultiBlockJobStatusInformationtrue,当NvM接受一个多块 *** 作时,NvM应该通过调用BswM_NvM_CurrentJobMode(具有相关服务ID,作为模式,为NVM_REQ_PENDING)来通知BswM接受的多块 *** 作正在等待。

 

如果NvMBswMMultiBlockJobStatusInformationtrue,当一个多块 *** 作结束或被取消时,NvM将通过调用BswM_NvM_CurrentJobMode,将多块 *** 作的结果通知给BswM,该BswM使用相关的服务ID和作为模式的多块 *** 作的结果。

 

如果NvMBswMBlockStatusInformationtrue,当NvM接受单个块 *** 作时,NvM应该通过调用BswM_NvM_CurrentBlockMode(带有相关的block ID和作为模式的NVM_REQ_PENDING)来通知BswM接受的单个块 *** 作正在等待。

 

如果NvMBswMBlockStatusInformationtrue,当单个块 *** 作完成或被取消时,NvM将通过调用BswM_NvM_CurrentBlockMode将单个块 *** 作的结果通知BswM,该BswM调用带有相关块IDBswM_NvM_CurrentBlockMode,作为模式,表示单个块 *** 作的结果。

 

如果NvMBswMBlockStatusInformationtrue,并且NvM有一个正在进行的多块 *** 作,对于每一个由于多块 *** 作而处理的块,NvM应该在开始处理该待处理的块时通知BswM,通过调用BswM_NvM_CurrentBlockMode与相关的块ID和作为模式的NVM_REQ_PENDING

 

如果NvMBswMBlockStatusInformationtrue,并且NvM有一个正在进行的多块 *** 作,对于每一个由于多块 *** 作而处理的块,NvM应该通过调用BswM_NvM_CurrentBlockMode来通知BswM该块处理完成的结果,该BswM使用相关的块ID和作为模式的单块 *** 作的结果。

 

3.28 块锁定情况下的NvM行为

NvM_SetBlockLockStatus API服务只能被BSW组件使用,它没有作为服务发布在SWC-Description中。因此,它将不能通过RTE访问。

 

如果该API被调用时参数LockedTRUE, NVM必须保证与BlockId标识的NVRAM块相关的NV内容不会被任何请求修改。在NvM_WriteAll过程中,Block应该被跳过,其他的请求,如NvM_WriteBlock, NvM_WritePRAMBlock, NvM_InvalidateNvBlock, NvM_EraseNvBlock,应该被拒绝。

 

如果API被调用时参数LockedTRUE, NVM应该保证在下次启动时,在处理NvM_ReadBlockNvM_ReadPRAMBlock时,这个NVRAM块应该从NV内存中加载。

 

如果Locked参数的值为FALSE,则NVM必须保证该NVRAM块按照AUTOSAR的规定正常处理。

 

使用该服务的设置不能被NvM_SetRamBlockStatusNvM_SetBlockProtection改变。

 

3.28.1 用例

通过诊断服务为NVRAM块保存新数据到NV内存。这些数据应在下一次ECU启动时提供给swc (s),即它们既不能被来自swc的请求覆盖,也不能在关机期间被永久RAM块的数据覆盖(NvM_WriteAll)

 

3.28.2 使用(DCM

1DCM请求NvM_SetBlockLockStatus(FALSE),以重新启用对该块的写入。(之前执行这个过程可能会锁定它)

2 DCM请求NvM_WriteBlock()

3DCM轮询完成写请求(使用NvM_GetErrorStatus())

4 当成功(NVM_REQ_OK)DCM发出NvM_SetBlockLockStatus(TRUE)

  审核编辑:汤梓红

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/dianzi/2997617.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-09-26
下一篇 2022-09-26

发表评论

登录后才能评论

评论列表(0条)

保存