NvM#1 : Introduction to Managing nonvolatile data in AUTOSAR
Introduction
In AUTOSAR, the NvRAM Manager (NvM ) module handles all the nonvolatile memory of the ECU. SWC’s interacts only with the NvM for reading or writing nonvolatile memory. All the necessary abstraction and protection of the non volatile memory is handle by the NvM.
MemIf and its underlying modules, Ea and Fee, handle the abstraction of the memory devices in the ECU.
NvM is independent of the hardware underneath. It deals with the nonvolatile memory as abstract memory blocks only. Each block has a unique handle (or block ID) number and administrative data.
Application cannot access nonvolatile memory on its own. It needs NvM to provide all the necessary interfaces. Even with those interfaces, application can interact only with the RAM copy of the block. NvM performs the consistency checks and synchronizes data between the RAM and NV memory.
NvM interacts with the following AUTOSAR modules,
EcuC — for initialization, startup and shutdown
SchM — for scheduling during the normal operation of the ECU
MemIf — for accessing the abstracted memory devices
Dem — for logging faults related to NvM operations
Crc — for integrity and consistency checks on data
Apart from these modules, NvM also interacts with modules like BswM, Det and Csm. All the SWCs (application) that use non volatile memory interact with NvM through RTE.
The component model of NvM module defines 4 types of Basic Storage Objects. A NvRAM block will consist of these Basic Storage Objects. AUTOSAR defines these objects as
RAM Block — represents the RAM part of the NvRAM block.
NV Block — represents the non volatile part of the NvRAM block.
ROM Block — represents the ROM part of the NvRAM block. This is an optional component. This used to define the default data for the NV block. Application provides this default value.
Administrative Block — it is the part of NvRAM block that defines the properties of the NvRAM block. This block is only for the internal use of the NvRAM module. This is not accessible to any other module outside of NvRAM Manager.
The NvRAM block supports one of the Block Management Types supported by AUTOSAR. These types are
Native Block Management — There are 1 NV Block, 1 RAM Block, 0..1 ROM Block and 1 Administrative Block
Redundant Block Management — There are 2 NV Block, 1 RAM Block, 0..1 ROM Block and 1 Administrative Block. There are 2 copies of the NV block. This provides resilience against data corruption.
Dataset Block Management — There are 1..n (n<256) NV Blocks, 1 RAM Block, 0..m ROM Blocks and 1 Administrative Block. A Dataset Block is an array of blocks of NV/ROM. Application can access only one of the elements of the dataset at one time.
NvM Initialization
In AUTOSAR, EcuM module initializes the NvM module. Before EcuM can do that, it is necessary to initialize all the modules that NvM is dependent on. General approach is to go bottom up with the sequence of initializations. First with the device drivers of internal nonvolatile memory devices. Followed by the communication drivers for external nonvolatile devices. Then the external nonvolatile devices itself. Then the initialization of nonvolatile memory abstraction modules like FEE/EA. Once the memory devices are ready then MemIf is initialized . Finally in the end NvM is initialized and the non volatile memory is ready to use.
The initialization of NvM is divided into two steps. First step is to initialize the internal state machine and queue of the NvM. Once it is done, the second step is to load all the NV data from nonvolatile memory to RAM. Depending on the size of data, this can take a long time. It may not be suitable for the initialization sequence of an ECU to spend a long time fetching all the data at power on. Here it is important to be selective about the blocks that get fetched immediately on power on.
For the first step of initialization EcuM invokes NvM_Init().
For the second step of initialization EcuM/BswM invokes NvM_ReadAll(). All the NvRAM blocks with NVM_SELECT_BLOCK_FOR_READALL enabled will be queued.Then NvM_MainFunction() will process these blocks asynchronously and load them into RAM. Before reloading a block’s NV data, it first checks if the RAM block data is still valid. This can only be assured if the block has a checksum. In case of valid RAM data, the NV data will not be reloaded. At power on as there are no valid data in RAM all the NV blocks will be loaded.
NvM_MainFunction() is run periodically by the BSW scheduler. This is where all the NvM module jobs are queued for processing.
States of a RAM Block
The state of a RAM Block is defined in terms of its validity (VALID/INVALID) and whether its content has been modified(CHANGED/UNCHANGED).
VALID/UNCHANGED:
The state implies that the contents of RAM block are same as the contents of NV Block.
A RAM block is in this state if the last read or write operation was successful and since then the application has not indicated any change. This is the normal good state of a RAM block.
VALID/CHANGED:
This state implies that the contents of the RAM Block differs from the NV Block.
A RAM block is in this state if the application indicates a change in the RAM block or,
Default data was retrieved (implicitly or explicitly) for the block upon last read operation.
INVALID/UNCHANGED:
This state implies that the contents of the RAM block is unknown or invalid. This is the default state of all the RAM blocks at initialization. Only after the block has been read successfully it moves out of this state.
A RAM block can move to this state by a write operation also. This happens,
if it has been erased or
the write operation has failed or
it has been invalidated by the application.
If the NvM reads a RAM block and finds that the CRC does not match with the CRC of the NV block, it changes the state of the RAM block to INVALID/UNCHANGED.
Lets take an example of a simple NvM Block. DCM uses this block to store the logistics data. At power on, the block will be in INVALID/UNCHANGED state by default. Assume that the block is configured to be read at initialization. Its next state will be decide by the result of NvM_ReadAll during the initialization.
The block will move to VALID/UNCHANGED state if it was read successfully by Nvm_ReadAll. Or it may go to VALID/CHANGED state if the read failed and default value was loaded.
If a read request fails and no default value is restored, the state changes to INVALID/UNCHANGED.
When the DCM needs to write to the block, it will call NvM_WriteBlock. This will change the state to VALID/CHANGED. Until the block write is complete RAM block will be in this state.
If the write fails, the block will be in INVALID/UNCHANGED
If the write succeeds, the block will be in VALID/UNCHANGED
Types of RAM blocks
There are two types of RAM blocks, Permanent RAM Block and Non-Permanent RAM Block.
Permanent RAM Block — this is a fixed RAM location where the RAM Block of the NV Block is stored. Only one application and the NV RAM Manager share variable to update the RAM copy of the NV Block.
Non-Permanent RAM Block — In some cases, more than one application may need to use a single NV block. In this case, both the applications will keep their separate copies of the NV block in the RAM. These RAM blocks are not shared amongst the applications and not even with the NV RAM Manager module.
NvM does not manage a Non-Permanent RAM Block. Even the block descriptor table does not list the Non-Permanent RAM Blocks of a NvM Block. NvM_ReadAll and NvM_WriteAll will not read or write to a Non-Permanent RAM Block.
Synchronization Mechanism
The communication between application and NvM follows a simple set of rules. This keeps the NVRAM block and NV block in sync and prevents data corruption. This simple mechanism minimizes the overhead caused by an explicit synchronization mechanism.
When the application needs to write data to the NV block it first updates the NVRAM block. Then the application initiates a NV block write. While the data is being written, application should not write to the RAM block. Application can still read it while the write is being processed. The status of the write operation can be fetched by polling for the status of the block. Or application can specify a callback to get notified from NvM once the process is complete. While the NV block is being updated by NvM, application needs to wait for it to complete before it can write to it again.
When the application requests a read from the NvM it needs to wait for the read request to complete. It should not read the RAM block until the read operation is notified to be complete by the NvM.
Synchronization becomes complex when a NV block is shared by many applications.
In Explicit synchronization, NvM defines a RAM mirror which it uses to exchange data with the application. The application maintains a local copy of the data while the NvM uses a RAM mirror.
As usual, application can initiate write operation with a call to NvM_WriteBlock. NvM is in charge of the operation after this. It invokes a callback referred by configuration parameter NvMWriteRamBlockToNvCallback. This callback then copies the data from application to its RAM mirror. Application can modify its data till that point in time the callback occurs. This allows the application to change its data even after initiating a write.
During read operation NvM module’s mirror updates the application data area . This is again done via the callback configured using NvMReadRamBlockFromNvCallback parameter.
The advantage is that applications can control their RAM block in an efficient way. They are responsible for copying consistent data to and from the NvM module’s RAM mirror. Using ReadRamBlockFromNvM / WriteRamBlockToNvM callbacks is essential for this mechanism. Application has to ensure data integrity of RAM block while copying data to/from RAM mirror.
The drawbacks here are the need for extra RAM space and the extra copy between two RAM locations for every operation.
The size of the RAM mirror needs to be equal to the largest NVRAM block that is using the explicit synchronization.
This mechanism especially enables the sharing of NVRAM blocks by different applications.
It makes sense to not have a permanent RAM block for such a NV block that is being shared by many applications. NvM will ignore it during the synchronization operations.