Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
/tests/lib/bluetooth/ble_racp/ @nrfconnect/ncs-bm
/tests/lib/bluetooth/ble_radio_notif/ @nrfconnect/ncs-bm
/tests/subsys/bluetooth/services/ @nrfconnect/ncs-bm @nrfconnect/ncs-bm-test
/tests/subsys/fs/bm_zms/ @nrfconnect/ncs-bm @rghaddab
/tests/subsys/fs/ @nrfconnect/ncs-bm @rghaddab
/tests/subsys/kmu/ @nrfconnect/ncs-eris
/tests/subsys/storage/bm_storage/ @nrfconnect/ncs-bm

Expand Down
4 changes: 2 additions & 2 deletions doc/nrf-bm/libraries/bm_zms.rst
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,11 @@ Mounting the storage system
Mounting the storage system starts by checking that the file system properties are correct, such as the sector_size and sector_count.
Then, the ``bm_zms_mount`` function must be called to make the storage ready.

To mount the file system, the following elements in the ``bm_zms_fs`` structure must be initialized:
To mount the file system, the following members in the struct :c:struct:`bm_zms_fs_config` must be set:

.. code-block:: c

struct bm_zms_fs {
struct bm_zms_fs_config {
/** File system offset in non-volatile memory **/
off_t offset;

Expand Down
18 changes: 18 additions & 0 deletions doc/nrf-bm/release_notes/release_notes_changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,24 @@ Libraries

* Added missing Kconfig dependencies.

* :ref:`lib_bm_zms` library:

* Added the struct :c:struct:`bm_zms_fs_config` for configuring a Zephyr Memory Storage file system instance at initialization.

* Updated:

* The :c:func:`bm_zms_register` function to return ``-EFAULT`` instead of ``-EINVAL`` when the input parameters are ``NULL``.
* The :c:func:`bm_zms_mount` function to return ``-EFAULT`` when the input parameter ``fs`` is ``NULL``.
* The :c:func:`bm_zms_clear` function to return ``-EFAULT`` when the input parameter ``fs`` is ``NULL``.
* The :c:func:`bm_zms_write` function to return ``-EFAULT`` when the input parameter ``fs`` is ``NULL``.
* The :c:func:`bm_zms_delete` function to return ``-EFAULT`` when the input parameter ``fs`` is ``NULL``.
* The :c:func:`bm_zms_read` function to return ``-EFAULT`` when the input parameter ``fs`` is ``NULL``.
* The :c:func:`bm_zms_read_hist` function to return ``-EFAULT`` when the input parameter ``fs`` is ``NULL``.
* The :c:func:`bm_zms_get_data_length` function to return ``-EFAULT`` when the input parameter ``fs`` is ``NULL``.
* The :c:func:`bm_zms_calc_free_space` function to return ``-EFAULT`` when the input parameter ``fs`` is ``NULL``.
* The :c:func:`bm_zms_active_sector_free_space` function to return ``-EFAULT`` when the input parameter ``fs`` is ``NULL``.
* The :c:func:`bm_zms_mount` function to expect an additional input parameter of type pointer to struct :c:struct:`bm_zms_fs_config` for configuring a Zephyr Memory Storage file system instance at initialization.

* :ref:`lib_peer_manager` library:

* Updated:
Expand Down
26 changes: 24 additions & 2 deletions include/bm/fs/bm_zms.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@ struct bm_zms_fs {
#endif
};

/** Configuration for Zephyr Memory Storage file system structure initialization. */
struct bm_zms_fs_config {
/** File system offset in flash. */
off_t offset;
/** Storage system is split into sectors. The sector size must be a multiple of
* `erase-block-size` if the device has erase capabilities.
*/
uint32_t sector_size;
/** Number of sectors in the file system. */
uint32_t sector_count;
};

/**
* @}
*/
Expand All @@ -123,23 +135,25 @@ typedef void (*bm_zms_cb_t)(bm_zms_evt_t const *p_evt);
* @param fs Pointer to the file system structure.
*
* @retval 0 on success.
* @retval -EFAULT if @p fs or @p cb are NULL.
* @retval -ENOMEM if no more callback slots are available.
* @retval -EINVAL if @p fs or @p cb are NULL.
*/
int bm_zms_register(struct bm_zms_fs *fs, bm_zms_cb_t cb);

/**
* @brief Mount a BM_ZMS file system.
*
* @param fs Pointer to the file system.
* @param config Pointer to the configuration for file system initialization.
*
* @retval 0 If the initialization is queued successfully.
* @retval -EFAULT if @p fs is NULL.
* @retval -ENOMEM if the internal fifo is full.
* @retval -EBUSY if an initialization is already executing.
* @retval -EINVAL if any of the sector layout is invalid.
* @retval -EIO if the backend storage initialization failed.
*/
int bm_zms_mount(struct bm_zms_fs *fs);
int bm_zms_mount(struct bm_zms_fs *fs, const struct bm_zms_fs_config *config);

/**
* @brief Clear the BM_ZMS file system from device. The BM_ZMS file system must be re-mounted after
Expand All @@ -148,6 +162,7 @@ int bm_zms_mount(struct bm_zms_fs *fs);
* @param fs Pointer to the file system.
*
* @retval 0 if the clear operation is queued successfully.
* @retval -EFAULT if @p fs is NULL.
* @retval -EACCES if @p fs is not mounted.
* @retval -EIO if there is an internal error.
*/
Expand All @@ -168,6 +183,7 @@ int bm_zms_clear(struct bm_zms_fs *fs);
* @return Number of bytes queued for write. On success, it will be equal to the number of bytes
* requested to be written or 0.
* On error, returns negative value of error codes defined in `errno.h`.
* @retval -EFAULT if @p fs is NULL.
* @retval -EACCES if BM_ZMS is still not initialized.
* @retval -EIO if there is an internal error.
* @retval -EINVAL if @p len is invalid.
Expand All @@ -181,6 +197,7 @@ ssize_t bm_zms_write(struct bm_zms_fs *fs, uint32_t id, const void *data, size_t
* @param id ID of the entry to be deleted.
*
* @retval 0 if the delete operation is queued.
* @retval -EFAULT if @p fs is NULL.
* @retval -EACCES if BM_ZMS is still not initialized.
* @retval -EIO if there is an internal error.
*/
Expand All @@ -199,6 +216,7 @@ int bm_zms_delete(struct bm_zms_fs *fs, uint32_t id);
* one.
* On error, returns negative value of error codes defined in `errno.h`.
* @retval Number of bytes read (> 0) on success.
* @retval -EFAULT if @p fs is NULL.
* @retval -EACCES if BM_ZMS is still not initialized.
* @retval -EIO if there is a memory read/write error.
* @retval -ENOENT if there is no entry with the given @p id.
Expand All @@ -219,6 +237,7 @@ ssize_t bm_zms_read(struct bm_zms_fs *fs, uint32_t id, void *data, size_t len);
* this indicates not all bytes were read, and more data is available.
* On error, returns negative value of error codes defined in `errno.h`.
* @retval Number of bytes read (> 0) on success.
* @retval -EFAULT if @p fs is NULL.
* @retval -EACCES if BM_ZMS is still not initialized.
* @retval -EIO if there is a memory read/write error.
* @retval -ENOENT if there is no entry with the given @p id and history counter.
Expand All @@ -234,6 +253,7 @@ ssize_t bm_zms_read_hist(struct bm_zms_fs *fs, uint32_t id, void *data, size_t l
* @return Data length contained in the ATE. On success, it will be equal to the number of bytes
* in the ATE. On error, returns negative value of error codes defined in `errno.h`.
* @retval Length of the entry with the given @p id (> 0) on success.
* @retval -EFAULT if @p fs is NULL.
* @retval -EACCES if BM_ZMS is still not initialized.
* @retval -EIO if there is a memory read/write error.
* @retval -ENOENT if there is no entry with the given @p id and history counter.
Expand All @@ -250,6 +270,7 @@ ssize_t bm_zms_get_data_length(struct bm_zms_fs *fs, uint32_t id);
* Calculating the free space is a time-consuming operation, especially on SPI flash.
* On error, returns negative value of error codes defined in `errno.h`.
* @retval Number of free bytes (>= 0) on success.
* @retval -EFAULT if @p fs is NULL.
* @retval -EACCES if BM_ZMS is still not initialized.
* @retval -EIO if there is a memory read/write error.
*/
Expand All @@ -261,6 +282,7 @@ ssize_t bm_zms_calc_free_space(struct bm_zms_fs *fs);
* @param fs Pointer to the file system.
*
* @retval Number of free bytes (>= 0) in the current active sector.
* @retval -EFAULT if @p fs is NULL.
* @retval -EACCES if BM_ZMS is still not initialized.
*/
ssize_t bm_zms_active_sector_free_space(struct bm_zms_fs *fs);
Expand Down
10 changes: 6 additions & 4 deletions lib/bluetooth/peer_manager/modules/peer_data_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,11 +351,13 @@ uint32_t pds_init(void)
return NRF_ERROR_INTERNAL;
}

fs.offset = PEER_MANAGER_PARTITION_OFFSET;
fs.sector_size = CONFIG_PM_BM_ZMS_SECTOR_SIZE;
fs.sector_count = (PEER_MANAGER_PARTITION_SIZE / CONFIG_PM_BM_ZMS_SECTOR_SIZE);
struct bm_zms_fs_config config = {
.offset = PEER_MANAGER_PARTITION_OFFSET,
.sector_size = CONFIG_PM_BM_ZMS_SECTOR_SIZE,
.sector_count = (PEER_MANAGER_PARTITION_SIZE / CONFIG_PM_BM_ZMS_SECTOR_SIZE),
};

err = bm_zms_mount(&fs);
err = bm_zms_mount(&fs, &config);
if (err) {
LOG_ERR("Could not initialize NVM storage. bm_zms_mount() returned %d.", err);
return NRF_ERROR_RESOURCES;
Expand Down
10 changes: 6 additions & 4 deletions samples/peripherals/bm_zms/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,14 @@ int main(void)
goto idle;
}

fs.offset = BM_ZMS_PARTITION_OFFSET;
fs.sector_size = CONFIG_BM_ZMS_SECTOR_SIZE;
fs.sector_count = (BM_ZMS_PARTITION_SIZE / CONFIG_BM_ZMS_SECTOR_SIZE);
struct bm_zms_fs_config config = {
.offset = BM_ZMS_PARTITION_OFFSET,
.sector_size = CONFIG_BM_ZMS_SECTOR_SIZE,
.sector_count = (BM_ZMS_PARTITION_SIZE / CONFIG_BM_ZMS_SECTOR_SIZE),
};

for (i = 0; i < CONFIG_BM_ZMS_ITERATIONS_MAX; i++) {
rc = bm_zms_mount(&fs);
rc = bm_zms_mount(&fs, &config);
if (rc) {
LOG_ERR("Storage Init failed, rc=%d", rc);
goto idle;
Expand Down
2 changes: 1 addition & 1 deletion scripts/ci/license_allow_list.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,5 @@ Apache-2.0: |
^nrf-bm/subsys/mgmt/mcumgr/transport/src/smp_uart.c
^nrf-bm/subsys/fs/bm_zms/
^nrf-bm/include/bm/fs/bm_zms.h
^nrf-bm/tests/subsys/fs/bm_zms/
^nrf-bm/tests/subsys/fs/bm_zms_ztest/
^nrf-bm/.ruff.toml
36 changes: 34 additions & 2 deletions subsys/fs/bm_zms/bm_zms.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
#define NRFX_CRITICAL_SECTION_EXIT(...)
#endif

#if CONFIG_UNITY
#define __ALIGN(x) __aligned(x)
#endif

LOG_MODULE_REGISTER(bm_zms, CONFIG_BM_ZMS_LOG_LEVEL);

static zms_op_t cur_op; /* Current bm_zms operation. */
Expand Down Expand Up @@ -328,7 +332,7 @@ int bm_zms_register(struct bm_zms_fs *fs, bm_zms_cb_t cb)
int i;

if (!fs || !cb) {
return -EINVAL;
return -EFAULT;
}

for (i = 0; i < CONFIG_BM_ZMS_MAX_USERS; i++) {
Expand Down Expand Up @@ -1686,6 +1690,10 @@ int bm_zms_clear(struct bm_zms_fs *fs)
uint32_t rc;
zms_op_t cur_clear_op;

if (!fs) {
return -EFAULT;
}

if (!fs->init_flags.initialized) {
LOG_ERR("zms not initialized");
return -EACCES;
Expand Down Expand Up @@ -2006,13 +2014,21 @@ static int zms_init(void)
return rc;
}

int bm_zms_mount(struct bm_zms_fs *fs)
int bm_zms_mount(struct bm_zms_fs *fs, const struct bm_zms_fs_config *config)
{
int ret;
uint32_t rc;
size_t write_block_size;
zms_op_t cur_init_op;

if (!fs || !config) {
return -EFAULT;
}

fs->offset = config->offset;
fs->sector_size = config->sector_size;
fs->sector_count = config->sector_count;

/* Initialize BM Storage */
fs->zms_bm_storage.start_addr = fs->offset;
fs->zms_bm_storage.end_addr = fs->offset + fs->sector_size * fs->sector_count;
Expand Down Expand Up @@ -2118,6 +2134,10 @@ ssize_t bm_zms_write(struct bm_zms_fs *fs, uint32_t id, const void *data, size_t
zms_op_t cur_write_op;
uint32_t rc;

if (!fs) {
return -EFAULT;
}

if (!fs->init_flags.initialized) {
LOG_ERR("zms not initialized");
return -EACCES;
Expand Down Expand Up @@ -2235,6 +2255,10 @@ ssize_t bm_zms_read_hist(struct bm_zms_fs *fs, uint32_t id, void *data, size_t l
uint32_t computed_data_crc;
#endif

if (!fs) {
return -EFAULT;
}

if (!fs->init_flags.initialized) {
LOG_ERR("zms not initialized");
return -EACCES;
Expand Down Expand Up @@ -2360,6 +2384,10 @@ ssize_t bm_zms_calc_free_space(struct bm_zms_fs *fs)
ssize_t free_space = 0;
const uint32_t second_to_last_offset = (2 * fs->ate_size);

if (!fs) {
return -EFAULT;
}

if (!fs->init_flags.initialized) {
LOG_ERR("zms not initialized");
return -EACCES;
Expand Down Expand Up @@ -2458,6 +2486,10 @@ ssize_t bm_zms_calc_free_space(struct bm_zms_fs *fs)

ssize_t bm_zms_active_sector_free_space(struct bm_zms_fs *fs)
{
if (!fs) {
return -EFAULT;
}

if (!fs->init_flags.initialized) {
LOG_ERR("ZMS not initialized");
return -EACCES;
Expand Down
28 changes: 28 additions & 0 deletions tests/subsys/fs/bm_zms_unity/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#
# Copyright (c) 2025 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})

project(bm_zms_unity)

cmock_handle(${ZEPHYR_BASE}/include/zephyr/sys/crc.h)
cmock_handle(${ZEPHYR_NRF_BM_MODULE_DIR}/include/bm/storage/bm_storage.h)

target_include_directories(app PRIVATE ${ZEPHYR_NRF_BM_MODULE_DIR}/include)

target_compile_definitions(app PRIVATE
CONFIG_BM_ZMS_MAX_USERS=8
CONFIG_BM_ZMS_OP_QUEUE_SIZE=16
)

# Generate and add test file
test_runner_generate(src/unity_test.c)
target_sources(app PRIVATE src/unity_test.c)

# Unit under test
target_sources(app PRIVATE ${ZEPHYR_NRF_BM_MODULE_DIR}/subsys/fs/bm_zms/bm_zms.c)
6 changes: 6 additions & 0 deletions tests/subsys/fs/bm_zms_unity/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#
# Copyright (c) 2025 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#
CONFIG_UNITY=y
Loading