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