Skip to content

Commit

Permalink
nvmp: a flash_map replacement
Browse files Browse the repository at this point in the history
flash_map is used by several subsystems to allow access to flash devices
in a unified way. Flash_map is by design directed and limited towards
flash devices and does not provide support for other non volatile
memories (e.g. eeprom).

nvmp (non volatile memory and partitioning) is proposed as an
alternative for flash_map that provides a path to solve many problems
that are caused by flash_map (e.g. zephyrproject-rtos#52395, the need to use flash_page
interface for block-size, the ability to override the flash page size
with a multiple, ...). The proposal is easily extended to other types
of memory that would use a dedicated driver solution (e.g. fram, mram,
rram that could have a driver similar to eeprom). It can also be
extended to disks and even files.

nvmp is an alternative for zephyrproject-rtos#67687 and zephyrproject-rtos#70828.

Signed-off-by: Laczen JMS <laczenjms@gmail.com>
  • Loading branch information
Laczen committed Apr 2, 2024
1 parent c97a813 commit 9e44e50
Show file tree
Hide file tree
Showing 12 changed files with 723 additions and 0 deletions.
20 changes: 20 additions & 0 deletions dts/bindings/misc/zephyr,eeprom-nvmp-fixed-partitions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
description: |
This binding is used to describe fixed non volatile partitions on eeprom.
Here is an example:
&eeprom0 {
nvmp_partitions {
compatible = "zephyr,eeprom-nvmp-fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition0: partition@0 {
reg = <0x00000000 0x0000C000>;
};
partition1: partition@c000 {
reg = <0x0000C000 0x00076000>;
};
};
};
compatible: "zephyr,eeprom-nvmp-fixed-partitions"

include: zephyr,nvmp-fixed-partitions.yaml
20 changes: 20 additions & 0 deletions dts/bindings/misc/zephyr,flash-nvmp-fixed-partitions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
description: |
This binding is used to describe fixed non volatile partitions on flash.
Here is an example:
&flash0 {
nvmp_partitions {
compatible = "zephyr,flash-nvmp-fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition0: partition@0 {
reg = <0x00000000 0x0000C000>;
};
partition1: partition@c000 {
reg = <0x0000C000 0x00076000>;
};
};
};
compatible: "zephyr,flash-nvmp-fixed-partitions"

include: zephyr,nvmp-fixed-partitions.yaml
49 changes: 49 additions & 0 deletions dts/bindings/misc/zephyr,nvmp-fixed-partitions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
description: |
This binding is used to describe non volatile partitions.
properties:
"#address-cells":
type: int
description: |
Number of cells required to represent a child node's
reg property address. This must be large enough to
represent the start offset of each partition.
"#size-cells":
type: int
description: |
Number of cells required to represent a child node's
reg property address. This must be large enough to
represent the size of each partition in bytes.
child-binding:
description: |
Each child node of the fixed-partitions node represents
an individual partition. These should usually look like
this:
partition_nodelabel: partition@START_OFFSET {
label = "human-readable-name";
reg = <0xSTART_OFFSET 0xSIZE>;
};
properties:
label:
type: string
description: |
Human readable string describing the partition.
read-only:
type: boolean
description: set this property if the partition is read-only
block-size:
type: int
description: set this property to specify a block-size
write-block-size:
type: int
description: set this property to specify a write-block-size
reg:
type: array
description: |
This should be in the format <OFFSET SIZE>, where OFFSET
is the offset of the partition relative to the base
address of the parent memory, and SIZE is the size of
the partition in bytes.
required: true

include: base.yaml
200 changes: 200 additions & 0 deletions include/zephyr/storage/nvmp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
/*
* Copyright (c) 2024 Laczen
*
* SPDX-License-Identifier: Apache-2.0
*/

/**
* @file
* @brief Public API for non volatile memory and partitions
*/

#ifndef ZEPHYR_INCLUDE_NVMP_H_
#define ZEPHYR_INCLUDE_NVMP_H_

/**
* @brief Abstraction over non volatile memory and its partitions on non
* volatile memory and their drivers
*
* @defgroup nvmp_part_api nvmp interface
* @{
*/

/*
* This API makes it possible to operate on non volatile memory and its
* partitions easily and effectively.
*/

#include <errno.h>
#include <sys/types.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* The nvmp subsystem provide an abstraction layer between non volatile memory
* specific drivers and higher-level applications for non volatile memory and
* its partitions. On non volatile memory and its partitions 3 routines for
* operation are provided: read, write and erase.
*
*/

/**
* @brief Retrieve a pointer to the non volatile info struct of non volatile
* memory.
*
* A non volatile memory or one of its partition with nodelabel "nodelabel" is
* retrieved as:
* const struct nbmp_info *nvmp = NVMP_GET(nodelabel)
*
* @param nodelabel of the non volatile memory or one of its partitions.
*/
#define NVMP_GET(nodelabel) &UTIL_CAT(nvmp_info_, DT_NODELABEL(nodelabel))

struct nvmp_info;
/**
* @brief nvmp_info represents a nvmp item.
*/
struct nvmp_info {
/** nvmp store */
const void *store;
/** nvmp size */
const size_t size;
/** nvmp block-size */
const size_t block_size;
/** nvmp write-block-size */
const size_t write_block_size;
/** nvmp routines */
int (*const open)(const struct nvmp_info *info);
int (*const read)(const struct nvmp_info *info, size_t start, void *data,
size_t len);
int (*const write)(const struct nvmp_info *info, size_t start,
const void *data, size_t len);
int (*const erase)(const struct nvmp_info *info, size_t start,
size_t len);
int (*const clear)(const struct nvmp_info *info, void *data, size_t len);
int (*const close)(const struct nvmp_info *info);
};

/**
* @brief Get the size in byte of a nvmp item.
*
* @param[in] info nvmp item
* @return the size.
*/
size_t nvmp_get_size(const struct nvmp_info *info);

/**
* @brief Get the block-size in byte of a nvmp item.
*
* @param[in] info nvmp item
* @return the size.
*/
size_t nvmp_get_block_size(const struct nvmp_info *info);

/**
* @brief Get the write-block-size in byte of a nvmp item.
*
* @param[in] info nvmp item
* @return the size.
*/
size_t nvmp_get_write_block_size(const struct nvmp_info *info);

/**
* @brief Open a nvmp item.
*
* @param[in] info nvmp item
*
* @return 0 on success, negative errno code on fail.
*/
int nvmp_open(const struct nvmp_info *info);

/**
* @brief Read data from nvmp item. Read boundaries are verified before read
* request is executed.
*
*
* @param[in] info nvmp item
* @param[in] start point relative from beginning of nvmp item
* @param[out] data Buffer to store read data
* @param[in] len Size to read
*
* @return 0 on success, negative errno code on fail.
*/
int nvmp_read(const struct nvmp_info *info, size_t start, void *data,
size_t len);

/**
* @brief Write data to nvmp item. Write boundaries are verified before write
* request is executed.
*
* @param[in] info nvmp item
* @param[in] start point relative from beginning of nvmp item
* @param[out] data Buffer with data to be written
* @param[in] len Size to read
*
* @return 0 on success, negative errno code on fail.
*/
int nvmp_write(const struct nvmp_info *info, size_t start, const void *data,
size_t len);

/**
* @brief Erase range on nvmp item. Erase boundaries are verified before erase
* is executed.
*
* @param[in] info nvmp item
* @param[in] start point relative from beginning of nvmp item
* @param[in] len Size to erase
*
* @return 0 on success, negative errno code on fail.
*/
int nvmp_erase(const struct nvmp_info *info, size_t start, size_t len);

/**
* @brief Clear a buffer by setting the value to the nvmp item erase value.
*
*
* @param[in] info nvmp item
* @param[in] data Buffer to clear
* @param[in] len Size to clear
*
* @return 0 on success, negative errno code on fail.
*/
int nvmp_clear(const struct nvmp_info *info, void *data, size_t len);

/**
* @brief Close a nvmp item.
*
* @param[in] info nvmp item
*
* @return 0 on success, negative errno code on fail.
*/
int nvmp_close(const struct nvmp_info *info);

/** @cond INTERNAL_HIDDEN */

#define NVMP_DECLARE_ITEM(n) extern const struct nvmp_info nvmp_info_##n;
#define NVMP_DECLARE(inst) DT_FOREACH_CHILD_STATUS_OKAY(inst, NVMP_DECLARE_ITEM)

#ifdef CONFIG_NVMP_EEPROM
DT_FOREACH_STATUS_OKAY(zephyr_eeprom_nvmp_fixed_partitions, NVMP_DECLARE)
#endif

#ifdef CONFIG_NVMP_FLASH
DT_FOREACH_STATUS_OKAY(zephyr_flash_nvmp_fixed_partitions, NVMP_DECLARE)
#endif

/** @endcond */

#ifdef __cplusplus
}
#endif

/**
* @}
*/

#endif /* ZEPHYR_INCLUDE_NVMP_H_ */
1 change: 1 addition & 0 deletions subsys/storage/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# SPDX-License-Identifier: Apache-2.0

add_subdirectory_ifdef(CONFIG_FLASH_MAP flash_map)
add_subdirectory_ifdef(CONFIG_NVMP nvmp)
add_subdirectory_ifdef(CONFIG_STREAM_FLASH stream)
1 change: 1 addition & 0 deletions subsys/storage/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
menu "Storage"

source "subsys/storage/flash_map/Kconfig"
source "subsys/storage/nvmp/Kconfig"
source "subsys/storage/stream/Kconfig"

endmenu
6 changes: 6 additions & 0 deletions subsys/storage/nvmp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: Apache-2.0

zephyr_library()
zephyr_library_sources(nvmp.c)
zephyr_library_sources_ifdef(CONFIG_NVMP_EEPROM nvmp_eeprom.c)
zephyr_library_sources_ifdef(CONFIG_NVMP_FLASH nvmp_flash.c)
42 changes: 42 additions & 0 deletions subsys/storage/nvmp/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright (c) 2024, Laczen
# SPDX-License-Identifier: Apache-2.0

menuconfig NVMP
bool "nvmp support"
help
Enables support for the nvmp system, which enables using unified
routines to read/write and erase non volatile memory.

if NVMP

config NVMP_FLASH
bool "nvmp support for flash devices"
default y if DT_HAS_ZEPHYR_FLASH_NVMP_FIXED_PARTITIONS_ENABLED
depends on FLASH
help
Enables nvmp support for flash devices.

if NVMP_FLASH

config NVMP_FLASH_RUNTIME_VERIFY
bool "runtime verification of flash properties"
default n
help
Enable runtime verification that block size is multiple of the flash
erase block size, that write block size is a multiple of the flash
write block size, and that the erase-value is correct.

endif #NVMP_FLASH

config NVMP_EEPROM
bool "nvmp support for eeprom devices"
default y if DT_HAS_ZEPHYR_EEPROM_NVMP_FIXED_PARTITIONS_ENABLED
depends on EEPROM
help
Enables nvmp support for eeprom devices.

module = NVMP
module-str = nvmp
source "subsys/logging/Kconfig.template.log_config"

endif #NVMP
Loading

0 comments on commit 9e44e50

Please sign in to comment.