Skip to content

Commit 8b923ca

Browse files
committed
[nrf fromlist] fs: introduce ZMS a new Memory storage system
ZMS is the abreviation of Zephyr Memory Storage. It is a storage developed to target especially the non erasable devices. The new memory storage system inherit from the NVS storage multiple features and introduce new ones : * Inherited features : - light key-value based storage - cache for entries - Wear Leveling of flash memory - Resilience to power failures * New features : - cycle counter for non erasable devices (instead of erase emulation) - Keys up to 32-bit - Built-in support of CRC32 for data - Small size data (<= 8 bytes) integrated within entries Upstream PR: zephyrproject-rtos/zephyr#77930 Signed-off-by: Riadh Ghaddab <[email protected]> (cherry picked from commit fdf44235cc7dbd148236034d11dfed4060912ba7)
1 parent 98134f8 commit 8b923ca

File tree

7 files changed

+2110
-0
lines changed

7 files changed

+2110
-0
lines changed

include/zephyr/fs/zms.h

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

subsys/fs/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ endif()
2525

2626
add_subdirectory_ifdef(CONFIG_FCB ./fcb)
2727
add_subdirectory_ifdef(CONFIG_NVS ./nvs)
28+
add_subdirectory_ifdef(CONFIG_ZMS ./zms)
2829

2930
if(CONFIG_FUSE_FS_ACCESS)
3031
zephyr_library_named(FS_FUSE)

subsys/fs/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,5 +99,6 @@ endif # FILE_SYSTEM
9999

100100
rsource "fcb/Kconfig"
101101
rsource "nvs/Kconfig"
102+
rsource "zms/Kconfig"
102103

103104
endmenu

subsys/fs/zms/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#SPDX-License-Identifier: Apache-2.0
2+
3+
zephyr_sources(zms.c)

subsys/fs/zms/Kconfig

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#Zephyr Memory Storage ZMS
2+
3+
#Copyright (c) 2024 BayLibre SAS
4+
5+
#SPDX-License-Identifier: Apache-2.0
6+
7+
config ZMS
8+
bool "Zephyr Memory Storage"
9+
select CRC
10+
help
11+
Enable support of Zephyr Memory Storage.
12+
13+
if ZMS
14+
15+
config ZMS_LOOKUP_CACHE
16+
bool "ZMS lookup cache"
17+
help
18+
Enable ZMS cache to reduce the ZMS data lookup time.
19+
Each cache entry holds an address of the most recent allocation
20+
table entry (ATE) for all ZMS IDs that fall into that cache position.
21+
22+
config ZMS_LOOKUP_CACHE_SIZE
23+
int "ZMS Storage lookup cache size"
24+
default 128
25+
range 1 65536
26+
depends on ZMS_LOOKUP_CACHE
27+
help
28+
Number of entries in ZMS lookup cache.
29+
It is recommended that it should be a power of 2.
30+
Every additional entry in cache will add 8 bytes in RAM
31+
32+
config ZMS_DATA_CRC
33+
bool "ZMS DATA CRC"
34+
help
35+
Enables DATA CRC
36+
37+
config ZMS_CUSTOM_BLOCK_SIZE
38+
bool "Custom buffer size used by ZMS for reads and writes"
39+
default n
40+
help
41+
ZMS uses internal buffers to read/write and compare stored data.
42+
Increasing the size of these buffers should be done carefully in order to not
43+
overflow the stack.
44+
Increasing this buffer means as well that ZMS could work with storage devices
45+
that have larger write-block-size which decreases ZMS performance
46+
47+
config ZMS_MAX_BLOCK_SIZE
48+
int "ZMS internal buffer size"
49+
default 32
50+
depends on ZMS_CUSTOM_BLOCK_SIZE
51+
help
52+
Changes the internal buffer size of ZMS
53+
54+
module = ZMS
55+
module-str = zms
56+
source "subsys/logging/Kconfig.template.log_config"
57+
58+
endif # ZMS

0 commit comments

Comments
 (0)