Skip to content

Commit

Permalink
mtd: api for mtd devices
Browse files Browse the repository at this point in the history
Enable support of mtd devices and partitions on flash. Provide support
for mtd on eeprom and retained_ram.

Modified flash_map_default.c to avoid generating non flash partitions in
the default_flash_map structure.

Performed some optimisation in finding the mtd_dev_cfg and offset on the
device.

Reworked to make the read, write and erase functions on the device part
of the mtd_dev_cfg struct.

Made the library more modular to allow easier addition of new backends

Signed-off-by: Laczen JMS <laczenjms@gmail.com>
  • Loading branch information
Laczen committed Sep 5, 2023
1 parent 0df085b commit 02b86e7
Show file tree
Hide file tree
Showing 22 changed files with 881 additions and 1 deletion.
6 changes: 6 additions & 0 deletions dts/bindings/mtd/zephyr,mtd-eeprom.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright (c) 2023 Laczen
# SPDX-License-Identifier: Apache-2.0

# Compatible used to describe mtd on eeprom

include: base.yaml
6 changes: 6 additions & 0 deletions dts/bindings/mtd/zephyr,mtd-flash.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright (c) 2023 Laczen
# SPDX-License-Identifier: Apache-2.0

# Compatible used to describe mtd on flash

include: base.yaml
6 changes: 6 additions & 0 deletions dts/bindings/mtd/zephyr,mtd-retained-mem.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright (c) 2023 Laczen
# SPDX-License-Identifier: Apache-2.0

# Compatible used to describe mtd on retained_mem

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

/**
* @file
* @brief Public API for memory technology devices (mtd) partitions
*/

#ifndef ZEPHYR_INCLUDE_MTD_H_
#define ZEPHYR_INCLUDE_MTD_H_

/**
* @brief Abstraction over mtd devices and partitions on mtd devices and their
* drivers
*
* @defgroup mtd_part_api mtd interface
* @{
*/

/*
* This API makes it possible to operate on mtd devices and partitions on mtd
* devices easily and effectively.
*/

#include <sys/types.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/drivers/eeprom.h>
#include <zephyr/drivers/retained_mem.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* The MTD subsystem provide an abstraction layer between hardware-specific
* device drivers and higher-level applications for mtd devices. On mtd devices
* 3 routines for operation are used: read, write and erase. Before data can be
* written the write location needs to be erased. The MTD subsystem also
* provides an adaptation layer for devices that are generally not considered
* mtd devices (e.g. eeprom and retained_mem).
*
* Both the MTD device as partitions on a MTD device are created by the
* subsystem.
*
*/

/**
* @brief Retrieve a pointer to the MTD info struct of a MTD.
*
* A mtd with nodelabel "flash0" is retrieved as:
* const struct mtd_info *mtd = MTD_GET(flash0)
* A mtd partition nodelabel "storage_partition" is retrieved as:
* const struct mtd_info *mtd = MTD_GET(storage_partition)
*
* @param nodelabel of the mtd device.
*/
#define MTD_GET(nodelabel) &UTIL_CAT(mtd_info_, DT_NODELABEL(nodelabel))

enum mtd_type {UNKNOWN, FLASH, EEPROM, RETAINED_MEM};

struct mtd_dev_cfg;

/** @brief mtd_dev_cfg represents the configuration of a mtd device */
struct mtd_dev_cfg {
/** device used as mtd backend */
const struct device *dev;
/** type of device used as mtd backend */
const enum mtd_type type;
/** backend routines */
int (* const read)(const struct mtd_dev_cfg *dev_cfg, off_t off,
void *dst, size_t len);
int (* const write)(const struct mtd_dev_cfg *dev_cfg, off_t off,
const void *src, size_t len);
int (* const erase)(const struct mtd_dev_cfg *dev_cfg, off_t off,
size_t len);
};

struct mtd_info;

/**
* @brief mtd_info represents a mtd item.
*/
struct mtd_info {
/** mtd device configuration (is NULL for a mtd partition) */
const struct mtd_dev_cfg *dev_cfg;
/** mtd parent (is NULL for a mtd device) */
const struct mtd_info *parent;
/** mtd offset on parent */
const off_t off;
const size_t size;
const bool read_only;
};

/**
* @brief Get the size of a mtd item.
*
* @param[in] info MTD item
* @return the size.
*/
size_t mtd_get_size(const struct mtd_info *info);

/**
* @brief Get the device that is used by a mtd item.
*
* @param[in] info MTD item
* @return the device.
*/
const struct device *mtd_get_device(const struct mtd_info *info);

/**
* @brief Get the offset of the mtd item on the device.
*
* @param[in] info MTD item
* @return the offsetdevice.
*/
off_t mtd_get_device_offset(const struct mtd_info *info);

/**
* @brief Get the device type of a mtd item.
*
* @param[in] info MTD item
* @return the device type.
*/
enum mtd_type mtd_get_device_type(const struct mtd_info *info);

/**
* @brief Read data from mtd item. Read boundaries are verified before read
* request is executed.
*
* @param[in] info MTD item
* @param[in] off Offset relative from beginning of mtd item to read
* @param[out] dst Buffer to store read data
* @param[in] len Number of bytes to read
*
* @return 0 on success, negative errno code on fail.
*/
int mtd_read(const struct mtd_info *info, off_t off, void *dst, size_t len);

/**
* @brief Write data to mtd item. Write boundaries are verified before write
* request is executed.
*
* @param[in] info MTD item
* @param[in] off Offset relative from beginning of mtd item to write
* @param[out] src Buffer with data to be written
* @param[in] len Number of bytes to write
*
* @return 0 on success, negative errno code on fail.
*/
int mtd_write(const struct mtd_info *info, off_t off, const void *src,
size_t len);

/**
* @brief Erase range on mtd item. Erase boundaries are verified before erase
* is executed.
*
* @param[in] info MTD item
* @param[in] off Offset relative from beginning of mtd item.
* @param[in] len Number of bytes to be erase
*
* @return 0 on success, negative errno code on fail.
*/
int mtd_erase(const struct mtd_info *info, off_t off, size_t len);

/** @cond INTERNAL_HIDDEN */

#define MTD_DECLARE(n) extern const struct mtd_info mtd_info_##n;

#define MTD_FIXED_PARTITIONS_DECLARE(n, _compat) \
COND_CODE_0(DT_NODE_HAS_COMPAT(DT_PARENT(n), _compat), (), \
(DT_FOREACH_CHILD(n, MTD_DECLARE)))

#define MTD_COMPATIBLE_PARTITIONS_DECLARE(_compatible) \
DT_FOREACH_STATUS_OKAY_VARGS(fixed_partitions, \
MTD_FIXED_PARTITIONS_DECLARE, _compatible)

#ifdef CONFIG_MTD_FLASH
DT_FOREACH_STATUS_OKAY(zephyr_mtd_flash, MTD_DECLARE)
MTD_COMPATIBLE_PARTITIONS_DECLARE(zephyr_mtd_flash)
#endif

#ifdef CONFIG_MTD_EEPROM
DT_FOREACH_STATUS_OKAY(zephyr_mtd_eeprom, MTD_DECLARE)
MTD_COMPATIBLE_PARTITIONS_DECLARE(zephyr_mtd_eeprom)
#endif

#ifdef CONFIG_MTD_RETAINED_MEM
DT_FOREACH_STATUS_OKAY(zephyr_mtd_retained_mem, MTD_DECLARE)
MTD_COMPATIBLE_PARTITIONS_DECLARE(zephyr_mtd_retained_mem)
#endif

/** @endcond */

#ifdef __cplusplus
}
#endif

/**
* @}
*/

#endif /* ZEPHYR_INCLUDE_MTD_H_ */
2 changes: 2 additions & 0 deletions subsys/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ add_subdirectory_ifdef(CONFIG_IMG_MANAGER dfu)
add_subdirectory_ifdef(CONFIG_INPUT input)
add_subdirectory_ifdef(CONFIG_JWT jwt)
add_subdirectory_ifdef(CONFIG_MODEM_MODULES modem)
add_subdirectory_ifdef(CONFIG_LORAWAN lorawan)
add_subdirectory_ifdef(CONFIG_MTD mtd)
add_subdirectory_ifdef(CONFIG_NET_BUF net)
add_subdirectory_ifdef(CONFIG_RETENTION retention)
add_subdirectory_ifdef(CONFIG_SENSING sensing)
Expand Down
1 change: 1 addition & 0 deletions subsys/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ source "subsys/lorawan/Kconfig"
source "subsys/mgmt/Kconfig"
source "subsys/modbus/Kconfig"
source "subsys/modem/Kconfig"
source "subsys/mtd/Kconfig"
source "subsys/net/Kconfig"
source "subsys/pm/Kconfig"
source "subsys/portability/Kconfig"
Expand Down
7 changes: 7 additions & 0 deletions subsys/mtd/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: Apache-2.0

zephyr_library()
zephyr_library_sources(mtd.c)
zephyr_library_sources_ifdef(CONFIG_MTD_FLASH mtd_flash.c)
zephyr_library_sources_ifdef(CONFIG_MTD_EEPROM mtd_eeprom.c)
zephyr_library_sources_ifdef(CONFIG_MTD_RETAINED_MEM mtd_retained_mem.c)
53 changes: 53 additions & 0 deletions subsys/mtd/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Copyright (c) 2023, Laczen
# SPDX-License-Identifier: Apache-2.0

menuconfig MTD
bool "mtd support"
help
Enables support for the mtd system, which enables using generic mtd
routines to read/write and erase mtd devices. Supported mtd devices
are flash, but also eeprom, bbram and retained_mem over an adaptation
layer.

if MTD

config MTD_FLASH
bool "mtd support for flash devices"
default y
depends on FLASH
help
Enables mtd support for flash devices.

config MTD_EEPROM
bool "mtd support for eeprom devices"
default y
depends on EEPROM
help
Enables mtd support for eeprom devices.

config MTD_RETAINED_MEM
bool "mtd support for retained_mem devices"
default y
depends on RETAINED_MEM
help
Enables mtd support for retained_mem devices.

config MTD_ERASE_BUFSIZE
int "mtd erase bufsize"
default 64
range 16 256
help
Size of the buffer used to erase when mtd is used on non-flash
devices.

config MTD_ERASE_VALUE
hex "mtd erase value"
default 0xff
help
Value used to erase when mtd is used on non-flash devices.

module = MTD
module-str = mtd
source "subsys/logging/Kconfig.template.log_config"

endif # MTD
Loading

0 comments on commit 02b86e7

Please sign in to comment.