NVMEMDRV
Detailed Description
NVM Non-volatile Memory Wear-Leveling Driver.
-
Deprecated:
- This driver is deprecated and marked for removal in a later release. New code should use NVM3 .
Introduction
This driver allows you to store application data in NVM. The driver supports wear leveling to maximize the lifetime of the underlying NVM system. CCITT CRC16 is used for data validation.
The size and layout of the data objects to be managed by this driver must be known at compile-time. Object may be composed of any primitive data type (8, 16 or 32-bit).
This driver consists of the files
nvm.c
,
nvm.h
and
nvm_hal.h
. Additionally, a implementation of
nvm_hal.c
is required for the specific NVM system to be used. A implementation of
nvm_hal.c
for EFM32/EZR32/EFR32 Flash memory is included with this driver. Driver configuration parameters and specification of the data objects are located in nvm_config.c and nvm_config.h.
Configuration Options
The files nvm_config.c and nvm_config.h contains compile-time configuration parameters and a specification of the user data structures to be managed by the driver, and how these are mapped to pages. A page can be of type normal or wear. A wear page can only contain a single object, but they provide better performance and drastically increase the lifetime of the memory if the object is known to have a low update frequency.
nvm_config.c implements an user data example. The arrays colorTable, coefficientTable, etc are defined and assigned to NVM pages. A pointer to each page is assigned to the page table nvmPages. The page table also contain a page type specifier. A page is either of type nvmPageTypeNormal or nvmPageTypeWear. Pages of type nvmPageTypeNormal are written to the unused page with the lowest erase count. For pages of type nvmPageTypeWear, the data is first attempted fitted in a already used page. If this fails, then a a new page is selected based on the lowest erase count. Pages of type nvmPageTypeWear can only contain one data object.
In nvm_config.h, driver features can be enabled or disabled. The following parameters may require special attention:
- NVM_MAX_NUMBER_OF_PAGES: Maximum number of NVM pages allocated to the driver.
- NVM_PAGES_SCRATCH: Configure extra pages to allocate for data security and wear leveling.
- NVM_PAGE_SIZE: Page size for the NVM system. Default is the size of the flash.
Users have to be aware of the following limitations:
- Maximum 254 objects in a page.
- Maximum 256 pages allocated to the driver. The default is 32 pages.
Note that the different EFM32/EZR32/EFR32 families have different page sizes. Please refer to the reference manual for details.
The API
This section contain brief descriptions of the functions defined by the API. You will find detailed information on input and output parameters and return values by clicking on the hyperlinked function names. Most functions return an error code or ECODE_EMDRV_NVM_OK is returned on success. See
ecode.h
and
nvm.h
for other error codes.
Your application code must include one header file:
nvm.h
.
The application may define the data objects allocated in RAM (and defined in nvm_config.c) as extern if direct access to these objects is required, eg:
extern uint32_t colorTable[];
The driver requires that the NVM system is erased by calling NVM_Erase() before the driver initialization function NVM_Init() is called. NVM_Init() requires a parameter to the configuration data. A pointer to the configuration data can be obtained by calling NVM_ConfigGet().
NVM_Write() takes two parameters, a page ID and a object ID. These two parameters must correspond to the definition of the user data in nvm_config.c. For example, colorTable is assigned to page 1 in the example version of nvm_config.c. To write the data in colorTable to NVM, call NVM_Write(MY_PAGE_1, COLOR_TABLE_ID).
NVM_Read() reads the a data object or an entire page in NVM back to the structures defined for the page in RAM.
Example
#include "em_chip.h" #include "em_gpio.h" #include "nvm.h" // Data object extern declarations matching the example data defined in nvm_config.c extern uint32_t colorTable[]; extern uint8_t coefficientTable[]; extern uint8_t primeNumberTable[]; extern uint16_t bonusTable[]; extern uint8_t privateKeyTable[]; extern uint16_t transformTable[]; extern int32_t safetyTable[]; extern uint8_t bigEmptyTable[450]; extern int8_t smallNegativeTable[]; extern uint16_t shortPositiveTable[]; extern uint32_t singleVariable; // Object and page IDs maching the data defined in nvm_config.c typedef enum { COLOR_TABLE_ID, COEFFICIENT_TABLE_ID, PRIME_NUMBER_TABLE_ID, BONUS_TABLE_ID, PRIVATE_KEY_TABLE_ID, TRANSFORM_TABLE_ID, SINGLE_VARIABLE_ID, SAFETY_TABLE_ID, BIG_EMPTY_TABLE_ID, SMALL_NEGATIVE_TABLE_ID, SHORT_POSITIVE_TABLE_ID } NVM_Object_Ids; typedef enum { MY_PAGE_1, MY_PAGE_2, MY_PAGE_3, MY_PAGE_4, MY_PAGE_5, MY_PAGE_6, } NVM_Page_Ids; CHIP_Init(); // Erase all pages managed by the driver and set the erase count // for each page to 0. To retain the erase count, pass NVM_ERASE_RETAINCOUNT. NVM_Erase(0); if (ECODE_EMDRV_NVM_NO_PAGES_AVAILABLE == NVM_Init(NVM_ConfigGet()) { // The driver could not initialize any pages } // Write all pages to NVM NVM_Write(MY_PAGE_1, NVM_WRITE_ALL_CMD)); NVM_Write(MY_PAGE_2, NVM_WRITE_ALL_CMD)); NVM_Write(MY_PAGE_3, NVM_WRITE_ALL_CMD)); NVM_Write(MY_PAGE_4, NVM_WRITE_ALL_CMD)); NVM_Write(MY_PAGE_5, NVM_WRITE_ALL_CMD)); NVM_Write(MY_PAGE_6, NVM_WRITE_ALL_CMD)); // Set some data elements to 0 for (i = 0; i < 4; i++) { bonusTable[i] = 0; primeNumberTable[i] = 0; } // Read back from NVM and check NVM_Read(MY_PAGE_1, NVM_READ_ALL_CMD)); NVM_Read(MY_PAGE_4, PRIME_NUMBER_TABLE_ID)); for (i = 0; i < 4; i++) { if (bonusTable[i] == 0) { // Should not happen because bonusTable[] in NVM should contain the // constants set in nvm_config.c } if (primeNumberTable[i] == 0) { // Should not happen because primeNumberTable[] in NVM should contain the // constants set in nvm_config.c } }
Macros |
|
#define | ECODE_EMDRV_NVM_ADDR_INVALID ( ECODE_EMDRV_NVM_BASE | 0x00000001) |
Invalid address.
|
|
#define | ECODE_EMDRV_NVM_ALIGNMENT_INVALID ( ECODE_EMDRV_NVM_BASE | 0x00000002) |
Invalid data alignment.
|
|
#define | ECODE_EMDRV_NVM_DATA_INVALID ( ECODE_EMDRV_NVM_BASE | 0x00000003) |
Invalid input data or format.
|
|
#define | ECODE_EMDRV_NVM_ERROR ( ECODE_EMDRV_NVM_BASE | 0x00000007) |
General error.
|
|
#define | ECODE_EMDRV_NVM_NO_PAGES_AVAILABLE ( ECODE_EMDRV_NVM_BASE | 0x00000005) |
Initialization didn't find any pages available to allocate.
|
|
#define | ECODE_EMDRV_NVM_OK ( ECODE_OK ) |
Success return value.
|
|
#define | ECODE_EMDRV_NVM_PAGE_INVALID ( ECODE_EMDRV_NVM_BASE | 0x00000006) |
Could not find the page specified.
|
|
#define | ECODE_EMDRV_NVM_WRITE_LOCK ( ECODE_EMDRV_NVM_BASE | 0x00000004) |
A write is currently in progress.
|
|
#define | NVM_ERASE_RETAINCOUNT 0xffffffffUL |
#define | NVM_PAGE_TERMINATION { NULL, 0, (NVM_Object_Ids) 0 } |
#define | NVM_READ_ALL_CMD 0xff |
#define | NVM_WRITE_ALL_CMD 0xff |
#define | NVM_WRITE_NONE_CMD 0xfe |
Functions |
|
Ecode_t | NVM_Erase (uint32_t eraseCount) |
Erase the entire allocated NVM area.
|
|
Ecode_t | NVM_Init (NVM_Config_t const *nvmConfig) |
Initialize the NVM manager.
|
|
Ecode_t | NVM_Read (uint16_t pageId, uint8_t objectId) |
Read an object or an entire page.
|
|
Ecode_t | NVM_Write (uint16_t pageId, uint8_t objectId) |
Write an object or a page.
|
|
Macro Definition Documentation
#define ECODE_EMDRV_NVM_OK ( ECODE_OK ) |
Success return value.
Return/error codes
Definition at line
47
of file
nvm.h
.
Referenced by NVM_Erase() , NVM_Init() , NVM_Read() , and NVM_Write() .
#define NVM_ERASE_RETAINCOUNT 0xffffffffUL |
Retains the registered erase count when eraseing a page.
Definition at line
64
of file
nvm.h
.
Referenced by NVM_Erase() .
#define NVM_PAGE_TERMINATION { NULL, 0, (NVM_Object_Ids) 0 } |
Structure defining end of pages table.
Definition at line
67
of file
nvm.h
.
#define NVM_READ_ALL_CMD 0xff |
#define NVM_WRITE_ALL_CMD 0xff |
#define NVM_WRITE_NONE_CMD 0xfe |
All objects are copied from the old page.
Definition at line
59
of file
nvm.h
.
Function Documentation
Ecode_t NVM_Erase | ( | uint32_t |
eraseCount
|
) |
Erase the entire allocated NVM area.
Use this function to erase the entire non-volatile memory area allocated to the NVM system. It is possible to set a fixed erase count for all the pages, or retain the existing one. To retain the erase count might not be advisable if an error has occurred since this data may also have been damaged.
- Parameters
-
[in] eraseCount
Specifies which erase count to set for the blank pages. Pass NVM_ERASE_RETAINCOUNT to retain the erase count.
- Returns
- Returns the result of the erase operation.
Definition at line
354
of file
nvm.c
.
References
ECODE_EMDRV_NVM_ERROR
,
ECODE_EMDRV_NVM_OK
,
NVM_ERASE_RETAINCOUNT
,
NVMHAL_PageErase()
,
NVMHAL_Read()
, and
NVMHAL_Write()
.
Ecode_t NVM_Init | ( | NVM_Config_t const * |
config
|
) |
Initialize the NVM manager.
Use this function to initialize and validate the NVM. Should be run on startup. The result of this process is then returned in the form of a Ecode_t.
If ECODE_EMDRV_NVM_OK is returned, everything went according to plan and you can use the API right away. If ECODE_EMDRV_NVM_NO_PAGES_AVAILABLE is returned this is a device that validates, but is empty. The proper way to handle this is to first reset the memory using NVM_Erase, and then write any initial data.
If a ECODE_EMDRV_NVM_ERROR, or anything more specific, is returned something irreparable happened, and the system cannot be used reliably. A simple solution to this would be to erase and reinitialize, but this will then cause data loss.
- Parameters
-
[in] config
Pointer to structure defining NVM area.
- Returns
- Returns the result of the initialization.
Definition at line
184
of file
nvm.c
.
References
ECODE_EMDRV_NVM_ERROR
,
ECODE_EMDRV_NVM_NO_PAGES_AVAILABLE
,
ECODE_EMDRV_NVM_OK
,
NVMHAL_Init()
, and
NVMHAL_Read()
.
Ecode_t NVM_Read | ( | uint16_t |
pageId,
|
uint8_t |
objectId
|
||
) |
Read an object or an entire page.
Use this function to read an object or an entire page from memory. It takes a page id and an object id (or the NVM_READ_ALL constant to read everything) and reads data from flash and puts it in the memory locations given in the page specification.
- Parameters
-
[in] pageId
Identifier of the page to read from. [in] objectId
Identifier of the object to read. Can be set to NVM_READ_ALL to read an entire page.
- Returns
- Returns the result of the read operation.
Definition at line
768
of file
nvm.c
.
References
ECODE_EMDRV_NVM_DATA_INVALID
,
ECODE_EMDRV_NVM_OK
,
ECODE_EMDRV_NVM_PAGE_INVALID
,
NVM_READ_ALL_CMD
, and
NVMHAL_Read()
.
Ecode_t NVM_Write | ( | uint16_t |
pageId,
|
uint8_t |
objectId
|
||
) |
Write an object or a page.
Use this function to write an object or an entire page to NVM. It takes a page and an object and updates this object with the data pointed to by the corresponding page entry. All the objects in a page can be written simultaneously by using NVM_WRITE_ALL instead of an object ID. For normal pages it simply finds an unused page in flash with the lowest erase count and copies all objects belonging to this page updating objects defined by objectId argument. For wear pages, this function tries to find spare place in already used page and write object here. If there is no free space, it uses a new page while invalidating previously used one.
- Parameters
-
[in] pageId
Identifier of the page you want to write to NVM. [in] objectId
Identifier of the object you want to write. May be set to NVM_WRITE_ALL to write the entire page to memory.
- Returns
- Returns the result of the write operation.
Definition at line
428
of file
nvm.c
.
References
ECODE_EMDRV_NVM_ERROR
,
ECODE_EMDRV_NVM_OK
,
NVM_WRITE_ALL_CMD
,
NVMHAL_Read()
, and
NVMHAL_Write()
.