| 
 | 1 | +/*  ZMS: Zephyr Memory Storage  | 
 | 2 | + *  | 
 | 3 | + * Copyright (c) 2024 BayLibre SAS  | 
 | 4 | + *  | 
 | 5 | + * SPDX-License-Identifier: Apache-2.0  | 
 | 6 | + */  | 
 | 7 | +#ifndef ZEPHYR_INCLUDE_FS_ZMS_H_  | 
 | 8 | +#define ZEPHYR_INCLUDE_FS_ZMS_H_  | 
 | 9 | + | 
 | 10 | +#include <zephyr/drivers/flash.h>  | 
 | 11 | +#include <sys/types.h>  | 
 | 12 | +#include <zephyr/kernel.h>  | 
 | 13 | +#include <zephyr/device.h>  | 
 | 14 | +#include <zephyr/toolchain.h>  | 
 | 15 | + | 
 | 16 | +#ifdef __cplusplus  | 
 | 17 | +extern "C" {  | 
 | 18 | +#endif  | 
 | 19 | + | 
 | 20 | +/**  | 
 | 21 | + * @brief Zephyr Memory Storage (ZMS)  | 
 | 22 | + * @defgroup zms Zephyr Memory Storage (ZMS)  | 
 | 23 | + * @ingroup file_system_storage  | 
 | 24 | + * @{  | 
 | 25 | + * @}  | 
 | 26 | + */  | 
 | 27 | + | 
 | 28 | +/**  | 
 | 29 | + * @brief Zephyr Memory Storage Data Structures  | 
 | 30 | + * @defgroup zms_data_structures Zephyr Memory Storage Data Structures  | 
 | 31 | + * @ingroup zms  | 
 | 32 | + * @{  | 
 | 33 | + */  | 
 | 34 | + | 
 | 35 | +/**  | 
 | 36 | + * @brief Zephyr Memory Storage File system structure  | 
 | 37 | + */  | 
 | 38 | +struct zms_fs {  | 
 | 39 | +	/** File system offset in flash **/  | 
 | 40 | +	off_t offset;  | 
 | 41 | +	/** Allocation table entry write address.  | 
 | 42 | +	 * Addresses are stored as uint64_t:  | 
 | 43 | +	 * - high 4 bytes correspond to the sector  | 
 | 44 | +	 * - low 4 bytes are the offset in the sector  | 
 | 45 | +	 */  | 
 | 46 | +	uint64_t ate_wra;  | 
 | 47 | +	/** Data write address */  | 
 | 48 | +	uint64_t data_wra;  | 
 | 49 | +	/** Storage system is split into sectors, each sector size must be multiple of erase-blocks  | 
 | 50 | +	 *  if the device has erase capabilities  | 
 | 51 | +	 */  | 
 | 52 | +	uint32_t sector_size;  | 
 | 53 | +	/** Number of sectors in the file system */  | 
 | 54 | +	uint32_t sector_count;  | 
 | 55 | +	/** Current cycle counter of the active sector (pointed by ate_wra)*/  | 
 | 56 | +	uint8_t sector_cycle;  | 
 | 57 | +	/** Flag indicating if the file system is initialized */  | 
 | 58 | +	bool ready;  | 
 | 59 | +	/** Mutex */  | 
 | 60 | +	struct k_mutex zms_lock;  | 
 | 61 | +	/** Flash device runtime structure */  | 
 | 62 | +	const struct device *flash_device;  | 
 | 63 | +	/** Flash memory parameters structure */  | 
 | 64 | +	const struct flash_parameters *flash_parameters;  | 
 | 65 | +	/** Size of an Allocation Table Entry */  | 
 | 66 | +	size_t ate_size;  | 
 | 67 | +#if CONFIG_ZMS_LOOKUP_CACHE  | 
 | 68 | +	/** Lookup table used to cache ATE address of a written ID */  | 
 | 69 | +	uint64_t lookup_cache[CONFIG_ZMS_LOOKUP_CACHE_SIZE];  | 
 | 70 | +#endif  | 
 | 71 | +};  | 
 | 72 | + | 
 | 73 | +/**  | 
 | 74 | + * @}  | 
 | 75 | + */  | 
 | 76 | + | 
 | 77 | +/**  | 
 | 78 | + * @brief Zephyr Memory Storage APIs  | 
 | 79 | + * @defgroup zms_high_level_api Zephyr Memory Storage APIs  | 
 | 80 | + * @ingroup zms  | 
 | 81 | + * @{  | 
 | 82 | + */  | 
 | 83 | + | 
 | 84 | +/**  | 
 | 85 | + * @brief Mount a ZMS file system onto the device specified in @p fs.  | 
 | 86 | + *  | 
 | 87 | + * @param fs Pointer to file system  | 
 | 88 | + * @retval 0 Success  | 
 | 89 | + * @retval -ERRNO errno code if error  | 
 | 90 | + */  | 
 | 91 | +int zms_mount(struct zms_fs *fs);  | 
 | 92 | + | 
 | 93 | +/**  | 
 | 94 | + * @brief Clear the ZMS file system from device.  | 
 | 95 | + *  | 
 | 96 | + * @param fs Pointer to file system  | 
 | 97 | + * @retval 0 Success  | 
 | 98 | + * @retval -ERRNO errno code if error  | 
 | 99 | + */  | 
 | 100 | +int zms_clear(struct zms_fs *fs);  | 
 | 101 | + | 
 | 102 | +/**  | 
 | 103 | + * @brief Write an entry to the file system.  | 
 | 104 | + *  | 
 | 105 | + * @note  When @p len parameter is equal to @p 0 then entry is effectively removed (it is  | 
 | 106 | + * equivalent to calling of zms_delete). It is not possible to distinguish between a deleted  | 
 | 107 | + * entry and an entry with data of length 0.  | 
 | 108 | + *  | 
 | 109 | + * @param fs Pointer to file system  | 
 | 110 | + * @param id Id of the entry to be written  | 
 | 111 | + * @param data Pointer to the data to be written  | 
 | 112 | + * @param len Number of bytes to be written (maximum 64 KB)  | 
 | 113 | + *  | 
 | 114 | + * @return Number of bytes written. On success, it will be equal to the number of bytes requested  | 
 | 115 | + * to be written. When a rewrite of the same data already stored is attempted, nothing is written  | 
 | 116 | + * to flash, thus 0 is returned. On error, returns negative value of errno.h defined error codes.  | 
 | 117 | + */  | 
 | 118 | +ssize_t zms_write(struct zms_fs *fs, uint32_t id, const void *data, size_t len);  | 
 | 119 | + | 
 | 120 | +/**  | 
 | 121 | + * @brief Delete an entry from the file system  | 
 | 122 | + *  | 
 | 123 | + * @param fs Pointer to file system  | 
 | 124 | + * @param id Id of the entry to be deleted  | 
 | 125 | + * @retval 0 Success  | 
 | 126 | + * @retval -ERRNO errno code if error  | 
 | 127 | + */  | 
 | 128 | +int zms_delete(struct zms_fs *fs, uint32_t id);  | 
 | 129 | + | 
 | 130 | +/**  | 
 | 131 | + * @brief Read an entry from the file system.  | 
 | 132 | + *  | 
 | 133 | + * @param fs Pointer to file system  | 
 | 134 | + * @param id Id of the entry to be read  | 
 | 135 | + * @param data Pointer to data buffer  | 
 | 136 | + * @param len Number of bytes to be read (or size of the allocated read buffer)  | 
 | 137 | + *  | 
 | 138 | + * @return Number of bytes read. On success, it will be equal to the number of bytes requested  | 
 | 139 | + * to be read. When the return value is less than the number of bytes requested to read this  | 
 | 140 | + * indicates that ATE contain less data than requested. On error, returns negative value of  | 
 | 141 | + * errno.h defined error codes.  | 
 | 142 | + */  | 
 | 143 | +ssize_t zms_read(struct zms_fs *fs, uint32_t id, void *data, size_t len);  | 
 | 144 | + | 
 | 145 | +/**  | 
 | 146 | + * @brief Read a history entry from the file system.  | 
 | 147 | + *  | 
 | 148 | + * @param fs Pointer to file system  | 
 | 149 | + * @param id Id of the entry to be read  | 
 | 150 | + * @param data Pointer to data buffer  | 
 | 151 | + * @param len Number of bytes to be read  | 
 | 152 | + * @param cnt History counter: 0: latest entry, 1: one before latest ...  | 
 | 153 | + *  | 
 | 154 | + * @return Number of bytes read. On success, it will be equal to the number of bytes requested  | 
 | 155 | + * to be read. When the return value is larger than the number of bytes requested to read this  | 
 | 156 | + * indicates not all bytes were read, and more data is available. On error, returns negative  | 
 | 157 | + * value of errno.h defined error codes.  | 
 | 158 | + */  | 
 | 159 | +ssize_t zms_read_hist(struct zms_fs *fs, uint32_t id, void *data, size_t len, uint32_t cnt);  | 
 | 160 | + | 
 | 161 | +/**  | 
 | 162 | + * @brief Gets the data size that is stored in an entry with a given id  | 
 | 163 | + *  | 
 | 164 | + * @param fs Pointer to file system  | 
 | 165 | + * @param id Id of the entry that we want to get its data length  | 
 | 166 | + *  | 
 | 167 | + * @return Data length contained in the ATE. On success, it will be equal to the number of bytes  | 
 | 168 | + * in the ATE. On error, returns negative value of errno.h defined error codes.  | 
 | 169 | + */  | 
 | 170 | +ssize_t zms_get_data_length(struct zms_fs *fs, uint32_t id);  | 
 | 171 | +/**  | 
 | 172 | + * @brief Calculate the available free space in the file system.  | 
 | 173 | + *  | 
 | 174 | + * @param fs Pointer to file system  | 
 | 175 | + *  | 
 | 176 | + * @return Number of bytes free. On success, it will be equal to the number of bytes that can  | 
 | 177 | + * still be written to the file system.  | 
 | 178 | + * Calculating the free space is a time consuming operation, especially on spi flash.  | 
 | 179 | + * On error, returns negative value of errno.h defined error codes.  | 
 | 180 | + */  | 
 | 181 | +ssize_t zms_calc_free_space(struct zms_fs *fs);  | 
 | 182 | + | 
 | 183 | +/**  | 
 | 184 | + * @brief Tell how many contiguous free space remains in the currently active ZMS sector.  | 
 | 185 | + *  | 
 | 186 | + * @param fs Pointer to the file system.  | 
 | 187 | + *  | 
 | 188 | + * @return Number of free bytes.  | 
 | 189 | + */  | 
 | 190 | +size_t zms_sector_max_data_size(struct zms_fs *fs);  | 
 | 191 | + | 
 | 192 | +/**  | 
 | 193 | + * @brief Close the currently active sector and switch to the next one.  | 
 | 194 | + *  | 
 | 195 | + * @note The garbage collector is called on the new sector.  | 
 | 196 | + *  | 
 | 197 | + * @warning This routine is made available for specific use cases.  | 
 | 198 | + * It collides with the ZMS goal of avoiding any unnecessary flash erase operations.  | 
 | 199 | + * Using this routine extensively can result in premature failure of the flash device.  | 
 | 200 | + *  | 
 | 201 | + * @param fs Pointer to the file system.  | 
 | 202 | + *  | 
 | 203 | + * @return 0 on success. On error, returns negative value of errno.h defined error codes.  | 
 | 204 | + */  | 
 | 205 | +int zms_sector_use_next(struct zms_fs *fs);  | 
 | 206 | + | 
 | 207 | +/**  | 
 | 208 | + * @}  | 
 | 209 | + */  | 
 | 210 | + | 
 | 211 | +#ifdef __cplusplus  | 
 | 212 | +}  | 
 | 213 | +#endif  | 
 | 214 | + | 
 | 215 | +#endif /* ZEPHYR_INCLUDE_FS_ZMS_H_ */  | 
0 commit comments