mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-29 18:11:05 +00:00
The CONFIG_FLASH_NVMEM option implements persistent, reliable storage
regions in flash. This adds CONFIG_FLASH_NVMEM_VARS, which uses one of
those storage regions for free-form variables.
Refer to the comments in include/nvmem_vars.h and common/nvmem_vars.c
for usage and implementation details.
BUG=chrome-os-partner:61107
BRANCH=none
TEST=make runtests
This CL includes a number of new tests, specifically for this feature.
No target boards use this feature yet so there's nothing to test on
actual hardware, but the test/nvmem_vars executable includes console
commands ("get", "set", "print") to try it out.
Change-Id: I8597415dc3b00a1462f5b164eeb5073129030525
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/414194
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
88 lines
3.3 KiB
C
88 lines
3.3 KiB
C
/* Copyright 2016 The Chromium OS Authors. All rights reserved.
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#ifndef __EC_INCLUDE_NVMEM_VARS_H
|
|
#define __EC_INCLUDE_NVMEM_VARS_H
|
|
|
|
/*
|
|
* CONFIG_FLASH_NVMEM provides persistent, atomic-update storage in
|
|
* flash. The storage is logically divided into one or more "user regions", as
|
|
* configured in board.h and board.c
|
|
*
|
|
* CONFIG_FLASH_NVMEM_VARS stores a set of <KEY, VALUE> tuples in the nvmem
|
|
* user region designated by CONFIG_FLASH_NVMEM_VARS_USER_NUM (in board.h)
|
|
*
|
|
* Tuples are stored and managed using this struct:
|
|
*/
|
|
|
|
struct tuple {
|
|
uint8_t key_len; /* 1 - 255 */
|
|
uint8_t val_len; /* 1 - 255 */
|
|
uint8_t flags; /* RESERVED, will be zeroed */
|
|
uint8_t data_[0]; /* Opaque. Don't look here. */
|
|
};
|
|
|
|
/*
|
|
* Both KEY and VALUE can be any binary blob between 1 and 255 bytes (flash
|
|
* memory is limited, so if you need longer values just use two keys and
|
|
* concatenate the blobs). Zero-length KEYs or VALUEs are not allowed.
|
|
* Assigning a zero-length VALUE to a KEY just deletes that tuple (if it
|
|
* existed).
|
|
*
|
|
* The expected usage is:
|
|
*
|
|
* 1. At boot, call initvars() to ensure that the variable storage region is
|
|
* valid. If it isn't, this will initialize it to an empty set.
|
|
*
|
|
* 2. Call getenv() or setenv() as needed. The first call to either will copy
|
|
* the storage regsion from flash into a RAM buffer. Any changes made with
|
|
* setenv() will affect only that RAM buffer.
|
|
*
|
|
* 3. Call writevars() to commit the RAM buffer to flash and free it.
|
|
*
|
|
* CAUTION: The underlying CONFIG_FLASH_NVMEM implementation allows access by
|
|
* multiple tasks, provided each task access only one user region. There is no
|
|
* support for simultaneous access to the *same* user region by multiple tasks.
|
|
* CONFIG_FLASH_NVMEM_VARS stores all variables in one user region, so if
|
|
* variable access by multiple tasks is required, the tasks should establish
|
|
* their own locks or mutexes to fit their usage. In general that would mean
|
|
* aquiring a lock before calling getvar() or setvar(), and releasing it after
|
|
* calling writevars().
|
|
*/
|
|
|
|
/*
|
|
* Initialize the persistent storage. This checks the user region to ensure
|
|
* that all tuples are valid and that there is one additional '\0' at the end.
|
|
* If any discrepancies are found, it erases all values. This should return
|
|
* EC_SUCCESS unless there is a problem writing to flash.
|
|
*/
|
|
int initvars(void);
|
|
|
|
/*
|
|
* Look up a key, return a pointer to the tuple. If the key is not found,
|
|
* return NULL. WARNING: The returned pointer is only valid until the next call
|
|
* to setvar() or writevars(). Use it or lose it.
|
|
*/
|
|
const struct tuple *getvar(const uint8_t *key, uint8_t key_len);
|
|
|
|
/* Use these to access the data components of a valid struct tuple pointer */
|
|
const uint8_t *tuple_key(const struct tuple *);
|
|
const uint8_t *tuple_val(const struct tuple *);
|
|
|
|
/*
|
|
* Save the tuple in the RAM buffer. If val is NULL or val_len is 0, the
|
|
* tuple is deleted (if it existed). Returns EC_SUCCESS or error code.
|
|
*/
|
|
int setvar(const uint8_t *key, uint8_t key_len,
|
|
const uint8_t *val, uint8_t val_len);
|
|
|
|
/*
|
|
* Commit any changes made with setvar() to persistent memory, and invalidate
|
|
* the RAM buffer. Return EC_SUCCESS or error code on failure.
|
|
*/
|
|
int writevars(void);
|
|
|
|
#endif /* __EC_INCLUDE_NVMEM_VARS_H */
|