NvM Overview
Memory operations on an ECU are achieved through the NvM. Learn how to use the module here
In the past weeks, we have covered the very basics of the memory stack, which contains the NvM (NVRAM Manager) on top, the Basic Software component used for memory interactions within the ECU. Although we already told you how useful the memory stack is, in the article Memory Stack Overview (opens in a new tab), let's refresh.
It's very common in the product lifecycle the need to store and read data persistently. The easiest example which is right under your nose is the diagnostics in your vehicle. Every time a problem is detected within your vehicle, it gets stored "somehow", for your mechanic (or you, in your spare time) to read, right? That's when the NvM comes in. In this specific case, the DEM (Diagnostic Event Manager) interacts with the NvM to store the diagnostic errors detected while you drive (you can learn more about the DEM here, in DEM Overview (opens in a new tab)). This is not limited to diagnostics, though. There are multiple instances where your application needs to access and modify data, to recalibrate sensors or actuators and even use the resume mode of XCP (which you can learn more about in What is XCP (opens in a new tab)).
In sum, the NvM handles the reading and writing to non-volatile memory. It provides you API's to perform synchronous and asynchronous operations, along with service ports to interact with it in the application layer (you can learn more about interfaces and ports in Types of Interfaces and Ports (opens in a new tab)). Now, let's dive deep into the NvM.
The NvM defines internally basic storage objects, which are the blocks where your non-volatile memory gets stored:
-
NV Block - Represents a memory region containing your NV-data and an optional CRC value, which can be used to check memory integrity.
-
RAM Block - A memory region in RAM which can also contain a CRC. It can contain temporary or permanent user data. When the latter option is chosen, the address is known on configuration time. The blocks do not need to be located into a contiguous address range.
-
ROM Block - Resides in the ROM and provides default data when the block is empty or damaged.
-
Administrative Block - Located in the RAM, contains a block index used in association with dataset NV-blocks. It stores the attributes and error status of the associated NV-block, along with validity status. This block is invisible to the application.
There are 3 blocks of NvM block management, which define the number of NV blocks associated, along with administrative blocks. They differ in reliabily against data corruption, mostly:
-
Native NvM Block - The simplest type. It provides you a block with minimal overhead. Contains a single NV-block, RAM block, optionally a ROM block, and an administrative block.
-
Redundant NvM Block - Additionally to the latter, it provides mechanisms against data corruption. Contains an extra NV-block, in comparison to a native NvM block, adding redundancy.
-
Dataset NvM Block - An array of equally-sized blocks (NV or ROM). The index position of each block inside it is provided in the administrative block. The maximum number of blocks is 255, in the sum of NV and ROM blocks.
Regarding the setup of NvM, the ECUM (ECU State Manager) is the only module that can initialize the NvM, through the API NvM_Init. Another API is needed in order to initiaize the RAM data blocks, NvM_ReadAll, which is also responsibility of the ECUM. You can take a look at these and other API's here:
-
NvM_Init - Initializes the NvM module. It shall not initialize the underlying modules of the memory stack. That is also responsibility of the ECUM, and should be done prior to this function call.
-
NvM_ReadAll - Initiaizes the RAM data blocks. The most important blocks that need to be ready at an early point in ECU initialization should have a lower index, in order to be processed first. You would do this, for example, to the NvM block for the DEM.
-
NvM_WriteAll - Shutdown procedure for the NvM, which is also invoked by the ECUM on shutdown. Synchronizes the contents of the permanent NvM blocks.
As you can see, the NvM interacts a lot with the ECUM, as other BSW modules to, specially in initialization and shutdown. If you want to learn more about mode management, you can check our article Mode Management (opens in a new tab).
Lastly, let's look at the most important API's and ports that you can use for the NvM:
-
Std_ReturnType NvM_ReadBlock(NvM_BlockIdType BlockId, uint8* NvM_DestPtr) - Read an NvM block into NvM_DstPtr.
-
Std_ReturnType NvM_WriteBlock(NvM_BlockIdType BlockId, const uint8* NvM_SrcPtr) - Write into an NvM block. It checks for block protection or if the block is meant to be written only once. You can also avoid having two different sets of data in a redundant block, by calling the API NvM_InvalidateNvBlock before writing to the block.
-
Std_ReturnType NvM_InvalidateNvBlock(NvM_BlockIdType BlockId) - Invalidates an non-volatile block, meaning you will be unable to read the block anymore.
-
Std_ReturnType NvM_EraseNvBlock(NvM_BlockIdType BlockId) - Erase an NV block. If the block is redundant, both will be erased.
-
Std_ReturnType NvM_RestoreBlockDefaults(NvM_BlockIdType BlockId, uint8* NvM_DestPtr) - Restores the block to the default values. It can be used as an error recovery mechanism.
-
Std_ReturnType NvM_GetErrorStatus(NvM_BlockIdType BlockId, uint8* RequestResultPtr) - Retrieves the error status of the NvM block, stored in the administrative information of the block.
-
Std_ReturnType NvM_SetBlockProtection(NvM_BlockIdType BlockId, boolean ProtectionEnabled) - Sets or resets the write protection on the NvM block.
When it comes to ports and interfaces, you have at your disposal a service interface to all block-related services, with the exception of NvM_SetBlockProtection, and you can have a Client-Server interface, for notification callbacks. You can also have a port for a CS interface regarding the administrative services for a block. To read and write data you have a Sender-Receiver interface, as we covered in previous articles.
NvData sender (left) and NvData receiver (right) ports symbol
As some final notes, we hope this article provided you with a thorhough understanding of the NvM module, and hope you are ready to use it in your next application. If you want to learn about the other stacks in the Autosar layered architecture, we already covered the watchdog and communication stack, respectively in Watchdog Stack Overview (opens in a new tab) and Communication Stack Overview (opens in a new tab). See you next time!
Author: Micael Coutinho (opens in a new tab)
References:
© AutosarToday —@LinkedIn