blob: e089fccbce5227f05fd114b3bd4d1a42bc896638 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef __SYS_FCB2_H_
#define __SYS_FCB2_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* \defgroup FCB2 Flash circular buffer.
* @{
*/
#include <inttypes.h>
#include <limits.h>
#include <assert.h>
#include <syscfg/syscfg.h>
#include <os/os_mutex.h>
#include <flash_map/flash_map.h>
#define FCB2_MAX_LEN (CHAR_MAX | CHAR_MAX << 7) /* Max length of element */
#define FCB2_SECTOR_OLDEST UINT16_MAX
struct fcb2;
/**
* Entry location point to sector, and offset within that sector.
*/
struct fcb2_entry {
struct flash_sector_range *fe_range; /* ptr to area within fcb->f_ranges */
uint16_t fe_sector; /* sector number in fcb flash */
uint16_t fe_data_len; /* size of data area */
uint32_t fe_data_off; /* start of data in sector */
uint16_t fe_entry_num; /* entry number in sector */
};
/* Number of bytes needed for fcb_sector_entry on flash */
#define FCB2_ENTRY_SIZE 6
#define FCB2_CRC_LEN 2
/**
* State structure for flash circular buffer version2.
*/
struct fcb2 {
/* Caller of fcb2_init() fills this in */
uint32_t f_magic; /* As placed on the disk */
uint8_t f_version; /* Current version number of the data */
uint8_t f_scratch_cnt; /* How many sectors should be kept empty */
uint8_t f_range_cnt; /* Number of elements in range array */
uint16_t f_sector_cnt; /* Number of sectors used by fcb */
uint16_t f_oldest_sec; /* Index of oldest sector */
struct flash_sector_range *f_ranges;
/* Flash circular buffer internal state */
struct os_mutex f_mtx; /* Locking for accessing the FCB data */
struct fcb2_entry f_active;
uint16_t f_active_id;
};
/**
* Error codes.
*/
#define FCB2_OK 0
#define FCB2_ERR_ARGS -1
#define FCB2_ERR_FLASH -2
#define FCB2_ERR_NOVAR -3
#define FCB2_ERR_NOSPACE -4
#define FCB2_ERR_NOMEM -5
#define FCB2_ERR_CRC -6
#define FCB2_ERR_MAGIC -7
#define FCB2_ERR_VERSION -8
/**
*
* Initialize FCB for use.
*
* @param fcb Fcb to initialize. User specific fields of structure
* must be set before calling this.
*
* @return 0 on success. Otherwise one of FCB2_XXX error codes.
*/
int fcb2_init(struct fcb2 *fcb);
/**
* Initialize fcb for specific flash area
*
* Function initializes FCB structure with data taken from specified flash
* area.
* If FCB was not initialized before in this area, area will be erased.
*
* @param fcb Fcb to initialize
* @param flash_area_id flash area for this fcb
* @param magic User defined magic value that is stored in each
* flash sector used by fcb
* @param version version of fcb
*
* @return 0 on success. Otherwise one of FCB2_XXX error codes.
*/
int fcb2_init_flash_area(struct fcb2 *fcb, int flash_area_id, uint32_t magic,
uint8_t version);
/**
* fcb2_append() reserves space for an entry within FCB. When writing the
* contents for the entry, fcb2_write() with fcb_entry filled by.
* fcb2_append(). When you're finished, call fcb2_append_finish() with
* loc as argument.
*
* @param fcb FCB this entry is being appended to.
* @param len Size of the entry being added
* @param loc Will be filled with fcb2_entry where data will be
* written to
*
* @return 0 on success. Otherwise one of FCB2_XXX error codes.
*/
int fcb2_append(struct fcb2 *fcb, uint16_t len, struct fcb2_entry *loc);
/**
* Write entry data to location indicated by loc. User must've called
* fcb2_append() before adding data to entry to populate loc. Should not
* be called after fcb2_append_finish() for this entry has been called.
*
* @param loc Where this entry will be written
* @param off Offset within entry area where to write the data
* @param buf Pointer to data being written
* @param len Number of bytes to write
*
* @return 0 on success. Otherwise one of FCB2_XXX error codes.
*/
int fcb2_write(struct fcb2_entry *loc, uint16_t off, const void *buf,
uint16_t len);
/**
* Finalize writing data for entry.
*
* @param append_loc Location of the entry
*
* @return 0 on success. Otherwise one of FCB2_XXX error codes.
*/
int fcb2_append_finish(struct fcb2_entry *append_loc);
/**
* Callback routine getting called when walking through FCB entries.
* Entry data can be read by using fcb2_read().
*
* @param loc Location of the entry
* @param arg void * which was passed as arg when calling fcb2_walk()
*
* @return 0 if walk should continue, non-zero if walk should stop
*/
typedef int (*fcb2_walk_cb)(struct fcb2_entry *loc, void *arg);
/**
* Iterate over all entries within FCB. Caller passes callback function to
* call for every valid entry. Entries are walked from oldest to newest.
*
* @param fcb FCB to iterate
* @param sector Sector ID where walk should start.
* Use FCB2_SECTOR_OLDEST to start from beginning.
* @param cb Callback to call for the entries.
* @param cb_arg void * to pass to callback.
*
* @return 0 on success. Otherwise one of FCB2_XXX error codes.
*/
int fcb2_walk(struct fcb2 *fcb, int sector, fcb2_walk_cb cb, void *cb_arg);
/**
* Walk through entries within FCB from oldest to newest.
* fcb_getnext() finds the next valid entry forward from loc, and fills in
* the location of that entry.
*
* @param fcb FCB to walk
* @param loc FCB entry location. To get the oldest entry
* set loc->fe_range to NULL, and fe_entry_num to 0.
*
* @return 0 on success. Otherwise one of FCB2_XXX error codes.
*/
int fcb2_getnext(struct fcb2 *fcb, struct fcb2_entry *loc);
/**
* Walk through entries within FCB from newest to oldest.
* fcb_getprev() finds the previous valid entry backwards from loc, and fills in
* the location of that entry.
*
* @param fcb FCB to walk
* @param loc FCB entry location. To get the newest entry
* set loc->fe_range to NULL.
*
* @return 0 on success. Otherwise one of FCB2_XXX error codes.
*/
int fcb2_getprev(struct fcb2 *fcb, struct fcb2_entry *loc);
/**
* Read entry data belonging pointed by loc.
*
* @param loc FCB entry to read
* @param off Offset within entry area
* @param buf Pointer to area where to populate the data
* @param len Number of bytes to read.
*
* @return 0 on success. Otherwise one of FCB2_XXX error codes.
*/
int fcb2_read(struct fcb2_entry *loc, uint16_t off, void *buf, uint16_t len);
/**
* Erases the data from oldest sector.
*
* @param fcb FCB where to erase the sector
*
* @return 0 on success. Otherwise one of FCB2_XXX error codes.
*/
int fcb2_rotate(struct fcb2 *fcb);
/**
* Start using the scratch block.
*
* @param fcb
*
* @return 0 on success. Otherwise one of FCB2_XXX error codes.
*/
int fcb2_append_to_scratch(struct fcb2 *fcb);
/**
* How many sectors are unused.
*/
int fcb2_free_sector_cnt(struct fcb2 *fcb);
/**
* Whether FCB has any data.
*
* @param fcb FCB to inspect
*
* @return 1 if area is empty, 0 if not
*/
int fcb2_is_empty(struct fcb2 *fcb);
/**
* Element at offset *entries* from last position (backwards).
*
* @param fcb FCB to inspect
* @param entries How many entries to look backwards
* @param last_n_entry location of entry being returned
*
* @return 0 on success. Otherwise one of FCB2_XXX error codes.
*/
int fcb2_offset_last_n(struct fcb2 *fcb, uint8_t entries,
struct fcb2_entry *last_n_entry);
/**
* Erase sector in FCB
*
* @param fcb FCB to use
* @param sector sector number to erase 0..f_sector_cnt
*
* return 0 on success, error code on failure
*/
int fcb2_sector_erase(const struct fcb2 *fcb, int sector);
/**
* Get total size of FCB
*
* @param fcb FCB to inspect
*
* @return FCB's size in bytes
*/
int fcb2_get_total_size(const struct fcb2 *fcb);
/**
* Empty the FCB
*
* @param fcb FCB to clear
*
* @return 0 on success. Otherwise one of FCB2_XXX error codes.
*/
int fcb2_clear(struct fcb2 *fcb);
/**
* Usage report for a given FCB sector. Returns number of elements and the
* number of bytes stored in them.
*
* @param fcb FCB to inspect
* @param sector Sector to inspect within FCB
* @param elemsp Pointer where number of elements should be stored
* @param bytesp Pointer where number of bytes used should be stored
*/
int fcb2_area_info(struct fcb2 *fcb, int sector, int *elemsp, int *bytesp);
#ifdef __cplusplus
}
/**
* @} FCB2
*/
#endif
#endif /* __SYS_FLASHVAR_H_ */
/**
* @} FCB2
*/