| /* |
| * 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 |
| */ |