AUTOSAR —— NVM 2

本文根据AUTOSAR4.4(Classic Platform)(https://www.autosar.org/standards/classic-platform/classic-platform-440/)标准中的 :

AUTOSAR_SRS_MemoryServices.pdf

AUTOSAR_SWS_NVRAMManager.pdf

两篇文章整理。仅为个人理解,不当之处,还请指正,感谢!

目录

1 NVM模块与其他模块的交互关系

2 关于priority

2.1 优先级分为:

2.2 SWS标准中:7.1.5 Scan order / priority scheme(待整理)

3 General Bahevior(对应SWS中7.2)

3.1 功能需求 (对应7.2.1 Functional requirements)

3.2 Design Note (SWS中7.2.2,本章中子目录直接使用SWS中目录)

7.2.2.1 NVRAM manager startup

7.2.2.2 NVRAM manager shutdown

7.2.2.3 (Quasi) parallel write access to the NvM module

7.2.2.4 NVRAM block consistency check(一致性检查)

7.2.2.5 Error recovery

7.2.2.9 Detection of an incomplete write operation to a NV block(检测没有完成的write 操作)

7.2.2.10 Termination of a single block request (单块请求的结束)

7.2.2.11 Termination of a multi block request(多块请求的结束)

7.2.2.12 General handling of asynchronous requests/ job processing

7.2.2.13 NVRAM block write protection 

7.2.2.14  Validation and modification of RAM block data

7.2.2.15 Communication and implicit synchronization between application and NVRAM manager (通信:APP和NvM之间的隐式同步机制)

7.2.2.17 Communication and explicit synchronization between applicationand NVRAM manager

7.2.2.18 Static Block ID Check

7.2.2.19    Read Retry

7.2.2.20 Write Verification

7.2.2.21 Comparing NV data in NvM

7.2.2.22 NvM and BswM interaction(交互)

7.2.2.23 NvM behaviour in case of Block locked


 


1 NVM模块与其他模块的交互关系

RTE :NVM module 通过RTE和上层Application进行通信(待完善);

DEM:诊断,错误报告;

DET:诊断,错误报告;

BSWM:启动

SCHM:任务调度;

MemIF:通过MEMIF层和下层的Dee/Ea进行通信;

CRC:使用CRFC进行数据校验;

 

2 关于priority

NVM module 支持基于优先级的任务处理(support a priority based job processing )。配置参数  NvMJobPrioritization 控制由县级的启用/禁用。

2.1 优先级分为:

1. Immediate priorrity (Prio = 0)

2. Normal Priority(Prio =1~255(高——>低), 数字越大,优先级越低)

如果配置时启用了任务优先级(即JobPrioritization == ON),则NVM在处理移步请求时会有两个Job Queue:
1. high   priority queue:   仅用作 immediate write job;
2. normal priority queue: 用作normal priority 的 read/write/erase job 和 immediate  read/erase;

2.2 SWS标准中:7.1.5 Scan order / priority scheme(待整理)
 

  1. 1. 源自NvM_ReadAll和NvM_WriteAll的多块请求的job 队列长度应为1(只有一个作业排队)
  2. NvM模块不应使用其他请求来中断NvM_ReadAll的job(此规则的唯一例外是immediate priority的write job,该作业将抢占正在运行的读/写作业。 随后将由NvM模块恢复/重新启动抢占作业。)
  3. NvM模块应该在运行 NvM_WriteAl l期间对其他的 write/read job进行排队,待 WriteAll 执行完成后再行处理。
  4. NvM模块应该在运行 NvM_ReadAll 期间对其他的 write job 进行排队,待 ReadAll 执行完成后行处理。
  5. NvM_WriteAll 可以通过调用 NvM_CancelWriteAll 来取消。调用 NvM_CancelWriteAll 后,当前正在处理的block会一直执行直到完成,但是不再执行后续的block write 操作(如果请求因完成相关的NVRAM块而过时,则允许将请求出列)。
  6. 被抢占的job随后会被恢复(或重启)。这适用于single block和 multi block request。

 

3 General Bahevior(对应SWS中7.2)

3.1 功能需求 (对应7.2.1 Functional requirements)

  1. 对每一个异步请求来说,job执行完毕后可以使用notification(比如 Job End Notification,NVM需要提供这个callback的接口)来通知任务结果,当然这个notification是可以通过配置来启用/禁用的。
  2. 在AUTOSAR架构中,只有 NvM module可以直接访问 non-valitile memory,其他模块只能访问NvM,禁止其他模块直接访问non-valitile memory;
  3. NvM模块只提供隐式(implicit)方式来访问NVRAM Block和RAM.即,NvM  module将数据从NVRAM 拷贝到RAM中;
  4. App可以在给定的限制条件直接访问RAM数据;
    1. [SWS_NvM_00385] ⌈The NvM module shall queue all asynchronous “single block” read/write/control requests if the block with its specific ID is not already queued or currently in progress (multitasking restrictions). ⌋ ( )
      对于所有的异步单块请求,如果请求对应的blockID还未进入队列或者正在处理,NvM module可以将其进行入队操作(queue)。 
  5. NvM对于移步请求的处理采用Queue的形式,只要Queue没有溢出,NvM module就可以 接受多个异步单块请求。
  6. NvM会从queue中提取最高优先级请求并按序列化方式处理。
  7. 对于存储在NV memory中数据NvM会提供隐式的 consistency / integrity checks
  8. 如果在配置时没有 default ROM data 或 NvMInitBlockCallback,则App负责提供默认初始化数据。在这种情况下,App必须使用 NvM_GetErrorStatus(first initialization) 来区分第一次初始化和数据损坏(corrupted data )。
  9. 在NvM_ReadAll()期间,NvM module 可以
    • 通过校验计算(CRC)来检测损坏的RAM数据。
    • 通过测试 administrative block 中数据的有效性(validity)来检测无效的数据;
    • 如果NvM module在NV block中检测到不可恢复的错误,则NvM应该将 default data 拷贝到RAM中;
  10. 如果NvM module要使用OS service,则NvM module 应该只能使用BSM Scheduler。

 

3.2 Design Note (SWS中7.2.2,本章中子目录直接使用SWS中目录)

7.2.2.1 NVRAM manager startup

  1. NvM_Init() 将由 BSW Mode Manager(简称BswM)调用;
  2. 考虑到启动时间的约束,NVRAM Block的初始化不是在NvM_Init() 完成,而是在NvM_ReadAll()内完成,同样,NvM_ReadAll() 也是 由 BswM 调用;
  3. 下层驱动(underlying driver)和存储器硬件抽象(memory hardware abstraction)模块的初始化也将由 BswM来完成,而非在NvM_Init()内完成;
  4. SWC要负责检查由NvM startup 产生的global error/status information 由使用NvM的。
  5. BswM可以使用NvM_GetErrorStatus() (polling 模式下) 或者 callback notification (前提是要启用NvM_MultiBlockCallback )来导出NvM startup 产生的global error/status information。
    1. 如果是polling模式:使用NvM_GetErrorStatus()这个API得到的结果 global error/status information 可以是NVM_REQ_OK 或 NVM_REQ_NOT_OK (during startup NVM_REQ_PENDING);
    2. 如果是启用了callback,则NVM每处理完一个NVRAM block 就会自动通知SWC其处理结果,结果值同上(如果为readall期间的每一个NVRAM block都配置了callback,这些callback会由RTE启动)
  6. NvM不会走动永久保存dataset 类型的NVRAM Block 的 data index。SWC要使用NvM_GetErrorStatus(blockID)来检查其负责的所有block的error/status information来确保相关RAM block的有效性。
  7. 对于 dataset 类型的NVRAM Block,SWC要使用 NvM_SetDataIndex()来为其中所有的block设置合适的索引位置(比如:SWC可以将当前的索引位置存储在一个特定的NVRAM block中),使用NvM_GetDataIndex()来获得当前的索引位置。

综上:

a. NvM module  的startup是由 BswM 调用 NvM_Init() 和 NvM_ReadAll()来完成的。其中, NvM_ReadAll完成所有 NVRAM Block(当然配置为在readall期间启用)的初始化。下层驱动和硬件抽象模块的初始化也是由BswM来完成。

b. 要想得到 startup的结果要看NvM获得异步请求结果的方式。如果是在polling 模式下,就使用 NvM_GetErrorStatus 来获得 startup 的 error/status information,如果是为NVRAM Block启用了callback则在每个block结束请求时会自动返回其结果。startup 可能的结果为 NVM_REQ_OK 或 NVM_REQ_NOT_OK (during startup NVM_REQ_PENDING);

c. 对于 dataset 类型的NVRAM Block ,SWC要负责管理 NV block的 dataindex。

 

7.2.2.2 NVRAM manager shutdown
 

  1. NvM module 的 shutdown 由 BswM调用 NvM_WriteAll()来实现;

 

7.2.2.3 (Quasi) parallel write access to the NvM module


[SWS_NvM_00162] ⌈The NvM module shall receive the requests via an asynchronous interface using a queuing mechanism. The NvM module shall process all requests serially depending on their priority. ⌋ (SRS_Mem_00013, SRS_Mem_00034) 

NvM module 使用queue来接收所有的异步写请求(即,接收到异步写请求后就将其入队),然后根据请求的优先级逐个处理。

 

7.2.2.4 NVRAM block consistency check(一致性检查)

  1. NvM module 通过计算NV Block的CRC(implicit techniques)来检查数据的一致性;
  2. 可以为每一个NvM block 单独配置CRC校验,相关配置参数有2个: NvMBlockUseCrc 和 NvMCalcRamBlockCrc;
  3. 如果NvMWriteBlockOnce = TRUE,则必须使得 NvMBlockUseCrc = TRUE,同时 NvMBlockWriteProt = FALSE, 从而使用户可以插在CRC检查失败的情况下,能够将数据写入NVRAM块。
  4. 如果启用了  NvMBlockUseCrc 和 NvMCalcRamBlockCrc ,用户要为用到的最大的CRC分配存储空间 ;

7.2.2.5 Error recovery
 

  1. NvM module 要提供错误恢复(数据恢复)机制,具体的恢复方式取决于 NVRAM block management type(Native, Redundant, Dataset),错误恢复包括 read 失败的错误恢复和write 失败的错误恢复,其中:

    1. error recovery on read(读失败是时的错误恢复)包括以下方式:

      1. 加载 default values(ROM 或者 block callback(后者一般也认为属于ROM形式)),适用于任何 三种管理类型。 ROM block对应的配置参数为NvMRomBlockDataAddress,block callback 对应的 配置参数为 NvMInitBlockCallback ;

      2. Redundant NVRAM Block:将 2nd NV block中的数据读到RAM中;

      3. ReadAll(startup)期间,如果配置了 RAM block CRC,则在NVRAM Block验证失败时,提供错误恢复(如果不配置CRC就不提供错误恢复(待求证)?如果是这样,则一定程度上CRC必不可少);

    2. error recovery on Writ(读失败是时的错误恢复)包括以下方式

      1. 重写(write retries),适用于任何 三种管理类型;

  2. 基于ROM 的错误恢复(即将ROM中的数据拷贝到RAM中)包括 implicit recovery and explicit recovery 两种,不论使用哪种方式,相关 NV block的数据都保持不变(即不会对NV block做改写操作):

    1. Implicit recovery(7.2.2.7):不使用API,NvM模块默认提供。

    2. explicit recovery:用户可以直接调用restore 的2个API。

  3. Implicit recovery

    1. 在Readall,NvM_ReadBlock ,NvM_ReadPRAMBlock 期间要使得 Implicit recovery 生效,需要同时具备以下3个条件:
      1.  配置了ROM(ROM block或者 callback);
      2.  Permanent RAM block state 或者 RAM mirror(explicit synchronization)的 state is invalid 并且 CRC 不一致(即CRC校验为 mismatch);
      3. 重读 NV block 失败;
    2. 对于 Native 和 redundant 类型的 NVRAM block,在调用NvM_ReadBlock ,NvM_ReadPRAMBlock 时会提供implicit recovery。

    3.   在Readall,NvM_ReadBlock ,NvM_ReadPRAMBlock 期间,在以下几种情况下 Implicit recovery 不生效:
      1. 压根没有为NVRAM Block 配置ROM,则没有隐式恢复;

      2. 配置了ROM,但是Permanent RAM 或者 RAM mirror 的 block state is valid and CRC 一致(即CRC match),则没有隐式恢复;

      3. 配置了ROM并且Permanent RAM 或者 RAM mirror 的 block state is invalid and CRC 不一致(即CRC mismatch),但是重读 NV block 成功,则没有隐式恢复;

         

  4. explicit recovery 

    1. NVM 模块提供两个API: NvM_RestoreBlockDefaults, NvM_RestorePRAMBlockDefaults来显示的将数据从ROM 拷贝到RAM中。

7.2.2.9 Detection of an incomplete write operation to a NV block(检测没有完成的write 操作)

  1. 检测对NV block的写操作没有执行完毕是  memory hardware abstraction  这一层的任务,而非NvM。NvM 通过memory hardware abstraction 来获知 NV block 目前的状态(  invalid /inconsistent /not readable)
  2. SW-Cs may use NvM_InvalidateNvBlock to prevent lower layers from delivering old data。
     

7.2.2.10 Termination of a single block request (单块请求的结束)

  1. 所有异步请求(当然,除了NvM_CancelWriteAll)的结果都会通过NVRAM Block的 Administrative block中的 error/status field 来标明。即,每个NVRAM Block的异步请求执行完毕后,都会更新 Administrative block 的 error/status信息(类似于一个标志位)。
  2. 可以选择为每一个 NVRAM Block 配置参数 NvMSingleBlockCallback 来启用 notification这个callback 函数。这个函数的作用是在每个NVRAM Block 的异步请求终止时通知用户该异步请求的结果(对于NvM_ReadAll也适用。因为readall 是逐个读取的,每读取完一个NVRAM  block, 就调用notification 通知用户结果)


7.2.2.11 Termination of a multi block request(多块请求的结束)
 

  1. NvM应该使用一个单独的变量(a separate variable)来存储多块请求的结果。多块请求包括 (NvM_ReadAll, NvM_WriteAll,NvM_CancelWriteAll, NvM_ValidateAll)。
  2. 多块请求的结果应表示常见的错误/状态信息.
  3. 函数NvM_GetErrorStatus 应结合 block 0 返回异步多块请求(包括NvM_CancelWriteAll)的最新错误/状态信息。
  4. 多块请求在处理完每个NVRAM Block时,应更新其Administrative block 中的 error/status field 来指示该NVRAN block 的错误/状态信息。
  5. 可以通过启用配置参数 NvMMultiBlockCallback 来启用 multiblock notification 这个callback 函数来通知用户多块请求的结果。
     

7.2.2.12 General handling of asynchronous requests/ job processing
 

  1. 在一个request中,每次计算CRC时,如果该NVRAM Block的长度超过NvMCrcNumOfBytes这个配置参数所对应的字节数,NvM模块会分几步来计算CRC;
  2. NvM模块使用CRC 模块对外发布的initial value来进行CRC计算;
  3. 多个并发单个块请求应该是可排队的(即NvM同时收到多个单块请求,会对其进行排队处理(Queue));
  4.  immediate priority (crash data) 会中断 normal priority asynchronous request/job;
  5. App调用NVM 模块的异步请求后,NvM模块会将该请求加入queueu,如果:
    1. 加入该请求导致作业队列溢出,则请求返回值为:E_NOT_OK;
    2. 如果顺利入队,请求返回值为:E_OK;
    3. 如果请求被顺利入队,且还没有处理完成,则 request result = NVM_REQ_PENDING;
    4. 如果该请求已被成功处理,则 request result = NVM_REQ_OK;

 

7.2.2.13 NVRAM block write protection 

NvM 模块提供几种不同类型的写保护,写保护只是针对NV block,并不影响RAM中数据的修改。

  1. 写保护类型主要有两种:
    1. 配置参数:NvMWriteBlockOnce;
    2. 配置参数:NvMBlockWriteProt;
    3. 除此之外,还有一个API:NvM_SetBlockProtection();
  2. NvMWriteBlockOnce 的优先级大于NvMBlockWriteProt。NvM_SetBlockProtection() 是否可用,只取决于 NvMWriteBlockOnce 这个配置参数.
  3. 只要 NvMWriteBlockOnce == FALSE,不管 NvMBlockWriteProtection 这个参数是否启用,用户就可以使用NvM 模块的NvM_SetBlockProtection()这个API来启用/禁用 写保护;反之,只要 NvMWriteBlockOnce == TRUE,不管 NvMBlockWriteProt 这个参数是否启用,都不能使用NvM_SetBlockProtection()这个API来改变写保护。
  4. 如果为NVRAM block 配置 NvMBlockWriteProt == TRUE,则启用写保护,且可以使用API来撤销写保护。
  5. 如果对一个 NVRAM Block 配置了 NvMWriteBlockOnce == TRUE, 则其 NV block 就执行进行一次write操作(i.e in case of a blank NV device),且不能使用API来撤销写保护。NvM将拒绝在第一次读取请求之前发出的任何写入/擦除/无效请求。
  6. NVRAM block的 NvMWriteBlockOnce 的标志位 位于其Administrative  block中,在reset 时,该标志位会被清除(cleared)。为了重新激活写保护,在对 NVRAM 进行任何 write/ erase/ invalidate 操作之前,应该先读取该NVRAM,以确保为 valid and consistent 类型的block设置写保护(即:如果该NVRAM Block在reset之后是不可读的,即为 invalid and inconsistent ,则再为其设置写保护是没有意义的)。reset之后的第一次读操作可以是单块读请求,也可以作为readall的一部分(即:如果为一个NVRAM Block 启用了writeonce, 有两种方式可以在reset之后先读取该block:1)检查到复位重启后调用readblock 这个单块请求来读取该block; 或者2)将该block 配置为 readall 期间读取)。

 

7.2.2.14  Validation and modification of RAM block data

本章将提供有关NVRAM manager status bits(状态位)内部处理的概要信息。 根据不同的API调用,除了第8.1.3章中的规范项目外,还应描述对RAM块状态的影响。 下图描绘了RAM块的状态(state)转换。

 

初始化(上电)之前,RAM block的状态为 UNINITIALIZED。上电后,RAM的状态为 INVALID/UNCHANGED。 在 ReadAll 执行完毕后,RAM状态会变为 VALID/UNCHANGED(此状态不允许执行WriteAll)。如果调用NvM_SetRamBlockStatus,则可以离开此状态。 如果发生CRC错误,则RAM的状态会再次变为INVALID,通过隐式或显式的错误恢复机制可以离开INVALID状态。
在错误恢复之后,RAM会处于VALID / CHANGED状态,因为此时RAM的内容与NVRAM (NV Block)中的内容不同了。

配置参数 NvMSetRamBlockStatusApi 所对应的API用来修改 RAM block status。

  1. 如果配置期间禁用 NvMSetRamBlockStatusApi ,则:
    1. NvM在将数据写到 NV Block之后,会将RAM block / RAM Mirror 的状态视为 VALID/CHANGED(during NvM_WriteAll, the NvM module shall write each permanent RAM block to NV memory.); 
    2. NVM在从NV block 读取数据后,会将RAM 的状态视为  INVALID(during NvM_ReadAll, the NvM module
      shall copy each NVRAM block to RAM if configured accordingly
      )。
  2. 如果块读取失败,则App负责在下次写入之前提供有效数据。
  3. 如果成功将RAM中数据复制到NV memory中,则RAM状态应在之后设置为valid/unmodified。

 

  • The VALID / UNCHANGED state

此状态意味着要么RAM block的内容与相应NV blokc的内容相同,要么 App已访问RAM块且未指示潜在的更改。 对于DATASET块,这些条件适用于上次处理的实例的RAM内容(最后一个块操作成功,并且块未被请求无效)。

要进入此状态,以下请求至少有一个成功:

1. NvM_ReadAll() read successfully the block
2. NvM_ReadBlock finished successfully for the block
3. NvM_WriteBlock finished successfully for the block
4. NvM_WriteAll() wrote successfully the block
 

此状态会在以下情况下保留:

最后一次读取或写入BlockID成功(没有错误,也没有检索默认数据),同时 自上次读取或写入以来,应用程序未指示RAM块的潜在更改

 

  • The VALID / CHANGED state

此状态意味着RAM block的内容可能与相应的NV block中的内容不同。 对于DATASET块,此条件适用于上次处理的实例的RAM内容(最后一个块操作成功,并且块未被请求无效)。 App通知修改RAM内容可以将RAM状态变为VALID / CHANGED。

 

要进入此状态,至少要发生以下之一:

1. NvM_SetRamBlockStatus called with TRUE for the block
2. NvM_WriteBlock is called for the block
3. NvM_WriteAll will also process the block
4. NvM_ReadBlock called for the block gives default data
5. NvM_RestoreBlockDefaults called for the block finishes successfully
6. NvM_ReadAll gives default data when processign the block
7. NvM_ValidateAll processed successfully the block
 

此状态会在以下情况下保留:

App通知修改RAM内容,或者 读失败后恢复默认数据(包括显示恢复和隐式恢复)

 

  • The INVALID / UNCHANGED state

此状态意味着NV block 是无效的(invalid)。对于DATASET块,此状态意味着之前处理的最后一个NV Bloc内容是无效的。

要进入此状态,至少要发生以下之一:

1. NvM_SetRamBlockStatus called with FALSE for the block
2. NvM_ReadBlock indicates invalidation by user request for the block
3. NvM_ReadBlock indicates corrupted data (if CRC configured) for the block
4. NvM_ReadBlock indicates wrong StaticID (if configured) for the block
5. NvM_WriteBlock finished non-successfully for the block
6. NvM_WriteAll non-successful write for the block
7. NvM_InvalidateNvBlock finished successfully for the block
8. NvM_EraseNvBlock finished successfully for the block
 

此状态会在以下情况下保留(or):

1. 块的状态未知(早期初始化,直到ReadAll执行完成或者对某个特定的block。执行完第一个请求);
2. 块被检测为已损坏或具有错误的StaticID;
3. 当前读取失败,且没有默认数据;
4.  块最后一次成功操作是 invalidate operation;
5. 块的最后一次成功操作是 erase operation;

 

7.2.2.15 Communication and implicit synchronization between application and NVRAM manager (通信:APP和NvM之间的隐式同步机制)

如果多个应用程序使用相同的RAM块,则确保RAM块的数据完整性不是NvM的模块的工作。 在这种情况下,应用程序必须同步它们对RAM块的访问,并且必须保证在NVRAM操作期间不会发生对RAM块的不适当访问(详情见下文)。
特别是如果多个应用程序通过使用(不同的)临时RAM块共享NVRAM block时,则应用程序之间的同步变得更加复杂,这种情况同样不是由 NvM模块来处理。 在使用回调作为通知方法的情况下,可能发生尽管此应用程序尚未启动请求,但应用程序仍会收到请求的通知。
所有申请都必须遵守以下规则。

7.2.2.15.1 Write requests (NvM_WriteBlock or NvM_WritePRAMBlock)

  1. App将数据放在RAM中,由NvM模块写入NV block;
  2. App调用 NvM_WriteBlock 或NvM_WritePRAMBlock 发起请求;
  3. App调用API后在该请求执行完毕(周到请求的结果通知)前,App不能修改RAM中的内容。在这期间RAM中的内容可能被读取;
  4. App 可以使用polling 去获取请求的状态或者使用经过callback函数被通知请求的结果;
  5. NvM模块的操作完成后,RAM可以被修改;

7.2.2.15.2 Read requests (NvM_ReadBlock or NvM_ReadPRAMBlock)

  1. App提供RAM block来存放从NVRAM block(NV Block)中读取的数据;
  2. App调用 NvM_ReadBlock 发起请求;
  3. 从现在开始在请求结束前App 不能读、写RAM block;
  4. App 可以使用polling 去获取请求的状态或者使用经过callback函数被通知请求的结果;
  5. NvM模块的操作完成后,App可以再次使用RAM block;

7.2.2.15.3 Restore default requests (NvM_RestoreBlockDefaults and NvM_RestorePRAMBlockDefaults)

  1. App提供RAM block来存放从NVRAM block(NV Block)中读取的数据;
  2. App调用 NvM_RestoreBlockDefaults or NvM_RestorePRAMBlockDefaults 发起请求;
  3. 从现在开始在请求结束前App 不能读、写RAM block;
  4. App 可以使用polling 去获取请求的状态或者使用经过callback函数被通知请求的结果;
  5. NvM模块的操作完成后,ROM中的数据被读到RAM 中,App可以再次使用RAM block;

 

7.2.2.15.4 Multi block read requests (NvM_ReadAll)


该请求只在system startup 期间由 BSW Mode Manager(简称BswM) 触发。该请求将NVRAM Block(配置时选择在readall之间读取)中 NV block的数据读到 permanent RAM当中。

如果该请求失败或者只有部分 NVRAM block 读取成功,NvM会将该情况报告给DEM并 return error to  BswM 。 DEM 和 BswM来决定下一步要采取的措施,这在两者的规范中有明确。

该请求要循序:

  1. BswM调用Readall发起请求;
  2. BswM可以使用polling 去获取请求的状态或者使用经过callback函数被通知请求的结果;
  3. 在ReadAll期间,当个NVRAM block处理完成后会调用 single block callback。这些回调使RTE能够单独启动每个SW-C。

 

7.2.2.15.5 Multi block write requests (NvM_WriteAll)


该请求只在system shuutdown 期间由 BSW Mode Manager(简称BswM) 触发。该请求将NVRAM Block(配置时选择在readall之间读取) permanent RAM中修改过的数据写到 NV block当中。

通过仅在ECU关闭期间调用此请求,BSWM可以确保在操作结束之前没有SWC能够修改RAM块中的数据。 这些措施超出了NvM模块的范围,其在BSWM规范中有要求。

该请求要循序:

  1. BswM调用Writeall发起请求;
  2. BswM可以使用polling 去获取请求的状态或者使用经过callback函数被通知请求的结果;

 

7.2.2.15.6 Cancel Operation (NvM_CancelWriteAll)
该请求取消处于pending 状态的 NvM_WriteAll 请求,且只能由 BswM调用。

 

7.2.2.15.7 Modification of administrative blocks

administrative block 是每个NVRAM block的一部分用作 管理该block。

如果NVRAM 当前有一个单块请求处于pending状态,在pending状态结束前,则App不能调用任何修改 administrative block 的请求(like  NvM_SetDataIndex, NvM_SetBlockProtection, NvM_SetRamBlockStatus)

 

7.2.2.16 Normal and extended runtime preparation of NVRAM blocks

NvM在 readall期间的处理过程取决于两个配置参数:NvMDynamicConfiguration 和 NvMResistantToChangedSw。


如果 NvMDynamicConfiguration == FALSE,NvM 就会进入 normal runtime preparation。即readall 期间忽略存储的 configuration ID 直接读取所有的NVRAM block(配置为在readall期间读取)。首先,NvM会检查RAM的有效性。如果RAM ==  invalid,则会继续检查NV block的有效性:如果NV block==valid,则会将数据从NV block 读取到RAM中。如果 NV block==invalid,则会将default data 拷贝到RAM中。

如果 NvMDynamicConfiguration == TRUE,且检测到 configuration ID为mismatch,如果NVRAN block 被配置为 NvMResistantToChangedSw == FALSE,则NVM在readall期间会执行 extended runtime preparation,即不管RAM或 NV block的是否有效,直接为RAM 加载 defaults。

 

7.2.2.17 Communication and explicit synchronization between applicationand NVRAM manager
 

显示同步机制是可以配置的。启用显示同步后,数据在App 和NvM之间通过callback函数流转。

  • 显示同步的利弊分析:

           好处:App可以更好的控制自己的数据。App知道什么时间将数据写入或读出,从而更好地保持数据的一致性。

          坏处:额外的RAM需要和使用显示同步机制的最大的NVRAM block 大小相同,且每一词读写操作数据都要在两个RAM之间(RAM和RAM Mirrior)额外进行一次;

  • 适用场景:显示同步尤其适用于多个App共同访问一个NVRAM block 的场景。从NvM的角度来看,需要有一个模块作为这个NVRAM Block的owner并负责同步这些App。
  1. 可以通过配置参数 NvMBlockUseSyncMechanism 为每一个 NVRAM Block启用显示同步机制;
  2. 如果没有NVRAM block启用显示同步机制,则NvM模块不能分配RAM Mirror;
  3. 如果至少有一个NVRAM block q被配置为使用显式同步机制,则NvM模块应仅分配一个RAM Mirror。 此RAM镜像不得超过使用显式同步机制的最长NVRAM block的大小。
  4. NNRAM Block 启用显示同步后,NvM使用内部Mirror作为这些block读写的buffer。且这个buffer不能给其他禁用显示同步的NVRAM block使用。
  5. NNRAM Block 启用显示同步后,NvM会使用 NvMReadRamBlockFromNvM()这个callback 来将数据从RAM Mirror 拷贝到RAM中;如果操作失败,API返回 E_NOT_OK,NvM 会在下一次 NvM_MainFunction()中重复该过程,重复的最大次数可以通过配置参数 NvMRepeatMirrorOperations 来设置。如果达到操作次数上限后还是失败,则NvM会将NVRAM block 中特定的请求结果设置为 NVM_REQ_NOT_OK,并报告该错误给DEM,错误码为:NVM_E_REQ_FAILED 。该过程同时适用于单块请求和多块请求。
     
  6. 如果为一个NVRAM Block启用了显式同步,那就不能再给它配置 permanent RAM。

 

7.2.2.17.1 Write requests (NvM_WriteBlock or NvM_WritePRAMBlock) 对比 7.2.2.15.1


显示同步的 write 请求要遵循以下规则:

  1. App将数据放在RAM中,由NvM将数据写入NV block;
  2. App调用 NvM_WriteBlock or NvM_WritePRAMBlock;
  3. 在NvM模块调用 NvMWriteRamBlockToNvM 前,App仍可以修改RAM中的数据;
  4. NvM模块调用NvMWriteRamBlockToNvM后,App必须提供RAM块 blovk的一致副本到NvM模块请求地点。
    App可以使用返回值E_NOT_OK来表示数据不一致。 NvM模块将接受NvMRepeatMirrorOperations次,然后推迟请求并继续其下一个请求。
  5. 仅在将数据复制到NvM模块后继续;
  6. 将数据复制到NvM后,App可以再次读写RAM块。
  7. App可以使用轮询来获取请求的状态,也可以通过回调例程异步通知。

 

7.2.2.17.2 Read requests (NvM_ReadBlock or NvM_ReadPRAMBlock) 对比7.2.2.15.1


显示同步的 read 请求要遵循以下规则:

  1. App 提供RAM block来存放从NvM模块读到的数据;
  2. App调用 NvM_ReadBlock or NvM_ReadPRAMBlock;
  3. 在NvM模块调用 NvMReadRamBlockFromNvM之前,App仍可以修改RAM Block;
  4. NvM调用 NvMReadRamBlockFromNvM()后,App就将数据从NvM给定的地点拷贝到RAM中。App可以使用返回值 E_NOT_OK 来表示数据没有拷贝完成。NvM模块会接受NvMRepeatMirrorOperations次,然后推迟请求并继续其下一个请求。
  5. 仅在将数据从NvM模块拷贝出来后继续;
  6. 将数据复制到NvM后,App可以再次读写RAM块。
  7. App可以使用轮询来获取请求的状态,也可以通过回调例程异步通知。

 

显示同步中,NvM_RestoreBlockDefaults and NvM_RestorePRAMBlockDefaults 的工作机制和隐式同步相同。
 

7.2.2.17.3 Multi block read requests (NvM_ReadAll)

该请求只在system startup 期间由 BSW Mode Manager(简称BswM) 触发。该请求将NVRAM Block(配置时选择在readall之间读取)中 NV block的数据读到 permanent RAM当中。

如果该请求失败或者只有部分 NVRAM block 读取成功,NvM会将该情况报告给DEM并 return error to  BswM 。 DEM 和 BswM来决定下一步要采取的措施,这在两者的规范中有明确。

正常操作:

  1. BswM调用Readall发起请求;
  2. BswM可以使用polling 去获取请求的状态或者使用经过callback函数被通知请求的结果;
  3. 在ReadAll期间,NvM会调用 NvMReadRamBlockFromNvM(被配置)后,App就将数据从NvM给定的地点拷贝到RAM中。App可以使用返回值 E_NOT_OK 来表示数据拷贝没有完成。NvM模块会接受NvMRepeatMirrorOperations次,然后报告读请求失败。
  4. 如果读请求成功,NV block 中的数据会被拷贝到RAM中;
  5. 处理完一个NVRAM block会调用 single block callback。这些回调使RTE能够单独启动每个SW-C。
  6. 处理完最后一个NVRAM block并调用它的 single block callback后,multi block callback (if configured) will be invoked。

 

7.2.2.17.4 Multi block write requests (NvM_WriteAll)
 

该请求只在system shuutdown 期间由 BSW Mode Manager(简称BswM) 触发。该请求将NVRAM Block(配置时选择在readall之间读取) permanent RAM中修改过的数据写到 NV block当中。

通过仅在ECU关闭期间调用此请求,BSWM可以确保在操作结束之前没有SWC能够修改RAM块中的数据。 这些措施超出了NvM模块的范围,其在BSWM规范中有要求。

正常操作:

  1. BswM调用Writeall发起请求;
  2. NvM模块调用NvMWriteRamBlockToNvM后,App必须提供RAM块 blovk的一致副本到NvM模块请求地点。
  3. App可以使用返回值E_NOT_OK来表示数据不一致。 NvM模块将接受NvMRepeatMirrorOperations次,然后报告读请求失败。
  4. 现在App又可以读、写RAM;
  5. App可以使用polling来获取请求的状态,也可以通过回调例程异步通知。

 

7.2.2.18 Static Block ID Check
 

Static Block ID fild位于NV Block Header中,NV Block Header时NV block的一部分。NvM每次写 NV memory时,会将Static Block ID 一并写入。当每次读取block的时候,会将NV block中存储的 tatic Block ID与请求的block ID进行比较。如果Static Block ID检测失败,NvM会报告 NVM_E_WRONG_BLOCK_ID 给DEM。同时激活 read error recovery。

此步骤的目的在于可以检测硬件故障导致的读取错误。

 

7.2.2.19    Read Retry

如果在read期间从NV memory检测到 CRC错误 / Static Block ID错误,则在继续读取ROM defaults / redundant NV Block之前,NvM会进行重读(次数取决于配置参数:NVM_MAX_NUM_OF_READ_RETRIES)。

 

7.2.2.20 Write Verification

配置参数为NVM_WRITE_VERIFICATION。如果启用,再将数据从RAM 写入NV memory之后,NV block中的数据会被立即会读并与RAM中的原始数据进行比较。

  1. RAM块中的原始内容与会读数据之间的比较应分步执行,以便读取和比较的字节数不大于配置参数NVM_WRITE_VERIFICATION_DATA_SIZE指定的字节数;
  2. 如果原始数据和会会读数据不一致,NvM会将 NVM_E_VERIFY_FAILED 报告给DEM,同时会进行重写操作;
  3. 如果回读失败,不会进行重读操作;
  4. 如果RAM Block中的原始内容与回读不同,对于初始重写以及所有已配置的重写,则NvM都会将请求结果设置为NVM_REQ_NOT_OK。(意思是只要发生重写,请求结果就是 NOT_OK?

 

7.2.2.21 Comparing NV data in NvM

如果运行期间没有更新RAM中的NV data,则不需要执行实际的写入操作。则NvM会提供基于CRC的比较机制跳过写入操作,以此来避免不必要的写操作。

风险:如果RAM中的内容的确改变了,但是CRC未变,则基于CRC的比较机智将会跳过实际的写入操作,因而导致变化的内容没有写到NV memory中。

对每一个MVRAN block来说,如果 NvMBlockUseCrc == TRUE,可以通过配置参数 NvMBlockUseCRCCompMechanism来启用CRC比较机制;

 

7.2.2.22 NvM and BswM interaction(交互)

  1. NvM模块可以使用BswM的API:BswM_NvM_CurrentJobMode()来通知BswM关于多块请求(readall,writeall)的状态变化和单块请求的结果(包括 being pending,说明单块请求被接受)。
  2. 如果 NvMBswMMultiBlockJobStatusInformation == TRUE(启用),则:
    1. NvM就不会调用已经配置的 multiblock callback(即:二者二选一,不能同时使用);
    2. NvM接受多块请求,多块请求执行完毕,或者多块请求被取消后,NvM会调用BswM_NvM_CurrentJobMode()来通知BswM当前请求的结果,通知信息中包括请求类型(readall /writeall)和请求结果(like :NVM_REQ_PENDING);
    3. NvM模块接受单块请求,多块请求执行完毕,或者多块请求被取消后,NvM会调用BswM_NvM_CurrentJobMode()来通知BswM请求的结果,通知信息中包括相关的Block ID和请求结果(like :NVM_REQ_PENDING);
    4. NvM正在执行多块请求时,每开始处理一个Block时,NvM都会调用BswM_NvM_CurrentJobMode()来通知BswM当前block处于Pending状态;每结束一个block,会再次调用BswM_NvM_CurrentJobMode()来通知BswM 该block 的处理结果。

7.2.2.23 NvM behaviour in case of Block locked

NvM_SetBlockLockStatus()这个API只供vBSW component 使用,不能通过RTE调用(SWC不能使用)。

一. NvM_SetBlockLockStatus说明:

  1. 如果启用锁状态 即NvM_SetBlockLockStatus(BVRAM block ID, TRUE),则:
    1. 任何请求不能改变该NVRAM block中的 NV内容。在writeall期间,该 NVRAM block会被跳过;访问该NVRAM 的其他请求,比如NvM_WriteBlock, NvM_WritePRAMBlock,NvM_InvalidateNvBlock, NvM_EraseNvBlock,会直接被拒绝(API返回E_NOT_OK);
    2. 在下一次start-up,在处理NvM_ReadBlock() 或NvM_ReadPRAMBlock(),时,该NVRAM block会被正常读取;
  2. 如果禁用锁状态,即NvM_SetBlockLockStatus(BVRAM block ID, FALSE),该NVRAM block可以被正常操作。
  3. 使用NvM_SetBlockLockStatus()进行的设置不能由NvM_SetRamBlockStatus()或NvM_SetBlockProtection()更改。

二. NvM_SetBlockLockStatus()的 use case:

通过诊断服务将新数据由NVRAM block保存到NV memory中。 这些数据在ECU下次启动时提供给SW-C,使用NvM_SetBlockLockStatus()将其锁住,使得这些数据既不会被源自SW-C的请求覆盖,也不会在shun-down期间被permanent RAM 中的的数据覆盖(NvM_WriteAll);

三. Usage (by DCM) :

1. DCM 调用 NvM_SetBlockLockStatus(<BlockId>, FALSE), 使得NVRAM Block 可以进行write操作;
2. DCM 调用 NvM_WriteBlock(<blockId>, <DataBuffer>)
3. DCM 调用NvM_GetErrorStatus() 轮询write 的完成情况;
4. write完成 (NVM_REQ_OK)后,DCM 会再次调用 NvM_SetBlockLockStatus(<BlockId>, TRUE)。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 25
    点赞
  • 165
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值