mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
272 lines
7.9 KiB
C
272 lines
7.9 KiB
C
/*
|
|
* Copyright (C) 2018 Acutam Automation, LLC
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
|
|
/**
|
|
* @defgroup sys_eepreg EEPROM registration
|
|
* @ingroup sys
|
|
* @brief eepreg provides a facility to easily manage the locations of
|
|
* data stored in EEPROM via a meta-data registry.
|
|
*
|
|
* The structure of the meta-data registry is intended to make it easy to
|
|
* detect the exact layout of existent data so that automatic tools may be
|
|
* written to migrate legacy data to new formats. It also allows the addition
|
|
* and removal of new entries dynamically.
|
|
*
|
|
* @note Names are used as identifiers and must be unique! It is also
|
|
* recommended to keep them as short as possible (while still being unique and
|
|
* human readable), as many systems have very small amounts of EEPROM.
|
|
* Disemvowelment can shorten long names while still retaining readability.
|
|
*
|
|
* @code {unparsed}
|
|
* The layout of the EEPROM used looks like this:
|
|
* EEPROM_RESERV_CPU_LOW
|
|
* EEPROM_RESERV_BOARD_LOW
|
|
* Registry magic number ("RIOTREG")
|
|
* Registry end pointer
|
|
* Registry entry 1 meta-data length (1 byte)
|
|
* Registry entry 1 name (unterminated)
|
|
* Registry entry 1 data pointer
|
|
* Registry entry 2 meta-data length
|
|
* Registry entry 2 name
|
|
* Registry entry 2 data pointer
|
|
* ... (new registry meta-data may be added in ascending order)
|
|
* unused space
|
|
* ... (new data locations may be added in descending order)
|
|
* Entry 2 data
|
|
* Entry 1 data
|
|
* EEPROM_RESERV_BOARD_HI
|
|
* EEPROM_RESERV_CPU_HI
|
|
* @endcode
|
|
*
|
|
* Pointer length is dependent on the size of the available EEPROM (see
|
|
* EEPREG_PTR_LEN below).
|
|
*
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief eepreg interface definitions
|
|
*
|
|
* @author Matthew Blue <matthew.blue.neuro@gmail.com>
|
|
*/
|
|
|
|
#ifndef EEPREG_H
|
|
#define EEPREG_H
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "periph_cpu.h"
|
|
#include "periph_conf.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#ifndef EEPROM_RESERV_CPU_LOW
|
|
/**
|
|
* @brief EEPROM reserved near beginning for use by CPU and related
|
|
*
|
|
* Change with care, as it may make existing data difficult to migrate
|
|
*/
|
|
#define EEPROM_RESERV_CPU_LOW (0U)
|
|
#endif
|
|
|
|
#ifndef EEPROM_RESERV_CPU_HI
|
|
/**
|
|
* @brief EEPROM reserved near end for use by CPU and related
|
|
*
|
|
* Change with care, as it may make existing data difficult to migrate
|
|
*/
|
|
#define EEPROM_RESERV_CPU_HI (0U)
|
|
#endif
|
|
|
|
#ifndef EEPROM_RESERV_BOARD_LOW
|
|
/**
|
|
* @brief EEPROM reserved near beginning for use by board and related
|
|
*
|
|
* Change with care, as it may make existing data difficult to migrate
|
|
*/
|
|
#define EEPROM_RESERV_BOARD_LOW (0U)
|
|
#endif
|
|
|
|
#ifndef EEPROM_RESERV_BOARD_HI
|
|
/**
|
|
* @brief EEPROM reserved near end for use by board and related
|
|
*
|
|
* Change with care, as it may make existing data difficult to migrate
|
|
*/
|
|
#define EEPROM_RESERV_BOARD_HI (0U)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Size in bytes of pointer meta-data in EEPROM
|
|
*/
|
|
#if (EEPROM_SIZE > 0x1000000)
|
|
#define EEPREG_PTR_LEN (4U)
|
|
#elif (EEPROM_SIZE > 0x10000)
|
|
#define EEPREG_PTR_LEN (3U)
|
|
#elif (EEPROM_SIZE > 0x100)
|
|
#define EEPREG_PTR_LEN (2U)
|
|
#else
|
|
#define EEPREG_PTR_LEN (1U)
|
|
#endif
|
|
|
|
/**
|
|
* @brief Signature of callback for iterating over entries in EEPROM registry
|
|
*
|
|
* @param[in] name name of an entry in the registry
|
|
* @param[in] arg argument for cb
|
|
*
|
|
* @return 0 on success
|
|
* @return < 0 on failure
|
|
*/
|
|
typedef int (*eepreg_iter_cb_t)(char *name, void *arg);
|
|
|
|
/**
|
|
* @brief Load or write meta-data in EEPROM registry
|
|
*
|
|
* This checks to see if relevant meta-data exists in the EEPROM registry, and
|
|
* returns that data position if it exists. If an entry does not exist in the
|
|
* registry, meta-data is written and allocated data space if there is enough
|
|
* remaining. Requesting a different length for an existent entry returns an
|
|
* error.
|
|
*
|
|
* @param[out] pos pointer to position variable
|
|
* @param[in] name name of entry to load or write
|
|
* @param[in] len requested amount of data storage
|
|
*
|
|
* @return 0 on success
|
|
* @return -EIO on EEPROM I/O error
|
|
* @return -ENOSPC on insufficient EEPROM for entry
|
|
* @return -EADDRINUSE on existing entry with different length
|
|
*/
|
|
int eepreg_add(uint32_t *pos, const char *name, uint32_t len);
|
|
|
|
/**
|
|
* @brief Read position meta-data from EEPROM registry
|
|
*
|
|
* This is similar to eepreg_add, except it never writes meta-data.
|
|
*
|
|
* @param[out] pos pointer to position variable
|
|
* @param[in] name name of entry to load
|
|
*
|
|
* @return 0 on success
|
|
* @return -EIO on EEPROM I/O error
|
|
* @return -ENOENT on non-existent registry or entry
|
|
*/
|
|
int eepreg_read(uint32_t *pos, const char *name);
|
|
|
|
/**
|
|
* @brief Write meta-data to EEPROM registry
|
|
*
|
|
* This ignores existing meta-data and always makes a new entry in the
|
|
* registry. Typical use should be through eepreg_add and not eepreg_write.
|
|
* If multiple entries with the same name exist, eepreg functions will find
|
|
* the oldest. Mainly intended for use by migration utilities.
|
|
*
|
|
* @param[out] pos pointer to position variable
|
|
* @param[in] name name of entry to write
|
|
* @param[in] len requested amount of data storage
|
|
*
|
|
* @return 0 on success
|
|
* @return -EIO on EEPROM I/O error
|
|
* @return -ENOSPC on insufficient EEPROM for entry
|
|
*/
|
|
int eepreg_write(uint32_t *pos, const char *name, uint32_t len);
|
|
|
|
/**
|
|
* @brief Remove entry from EEPROM registry and free space
|
|
*
|
|
* This removes an entry from the EEPROM registry and its corresponding data
|
|
* and moves the data and meta-data of entries after removed entry to occupy
|
|
* the freed space. This preserves the structure of the EEPROM registry.
|
|
* Warning: this is a read/write intensive operation! Mainly intended for use
|
|
* by migration utilities.
|
|
*
|
|
* @param[in] name name of entry to remove
|
|
*
|
|
* @return 0 on success
|
|
* @return -EIO on EEPROM I/O error
|
|
* @return -ENOENT on non-existent registry or entry
|
|
*/
|
|
int eepreg_rm(const char *name);
|
|
|
|
/**
|
|
* @brief Iterate over meta-data entries in EEPROM registry
|
|
*
|
|
* This executes a callback over each name in the EEPROM registry. The intended
|
|
* work-flow for migration is to: iterate over each entry, check to see if
|
|
* migration is needed, duplicate using eepreg_write if needed, migrate data to
|
|
* duplicate entry, then delete old entry using eepreg_rm.
|
|
*
|
|
* @note It is safe for the callback to remove the entry it is called with,
|
|
* or to add new entries.
|
|
*
|
|
* @param[in] cb callback to iterate over entries
|
|
* @param[in] arg argument for cb
|
|
*
|
|
* @return 0 on success
|
|
* @return -EIO on EEPROM I/O error
|
|
* @return -ENOENT on non-existent registry
|
|
* @return return value of cb when cb returns < 0
|
|
*/
|
|
int eepreg_iter(eepreg_iter_cb_t cb, void *arg);
|
|
|
|
/**
|
|
* @brief Check for the presence of meta-data registry
|
|
*
|
|
* @return 0 on success
|
|
* @return -EIO on EEPROM I/O error
|
|
* @return -ENOENT on non-existent registry
|
|
*/
|
|
int eepreg_check(void);
|
|
|
|
/**
|
|
* @brief Clear existing meta-data registry
|
|
*
|
|
* This removes any existing meta-data registry by writing a new registry with
|
|
* no entries.
|
|
*
|
|
* @return 0 on success
|
|
* @return -EIO on EEPROM I/O error
|
|
*/
|
|
int eepreg_reset(void);
|
|
|
|
/**
|
|
* @brief Calculate data length from meta-data in EEPROM registry
|
|
*
|
|
* @note This information is typically already available to code that has
|
|
* called eepreg_add.
|
|
*
|
|
* @param[out] len pointer to length variable
|
|
* @param[in] name name of entry to load or write
|
|
*
|
|
* @return 0 on success
|
|
* @return -EIO on EEPROM I/O error
|
|
* @return -ENOENT on non-existent registry or entry
|
|
*/
|
|
int eepreg_len(uint32_t *len, const char *name);
|
|
|
|
/**
|
|
* @brief Calculate length of remaining EEPROM free space
|
|
*
|
|
* @param[out] len pointer to length variable
|
|
*
|
|
* @return 0 on success
|
|
* @return -EIO on EEPROM I/O error
|
|
* @return -ENOENT on non-existent registry
|
|
*/
|
|
int eepreg_free(uint32_t *len);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
/** @} */
|
|
|
|
#endif /* EEPREG_H */
|