-
Notifications
You must be signed in to change notification settings - Fork 6.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
flash_partitions: a flash_map alternative
Working with partitions on a flash device has been done using the flash_map subsystem. The flash_map subsystem has been limiting (e.g. #52395) and does not support support for flash devices that do not need an erase (non flash devices that are supported as if they are flash). The PR proposes an alternative for flash_map that supports classic flash devices, "no-erase" flash devices. Partitions can be read-only, and it is possible to provide an "override" erase-block-size. The support for "no-erase" flash devices is achieved by the definition of a "zephyr,flash-no-erase" compatible that is added to the flash device. Signed-off-by: Laczen JMS <laczenjms@gmail.com>
- Loading branch information
Showing
8 changed files
with
517 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Copyright (c) 2024 Laczen | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
description: Compatible describing that a flash device has no erase. | ||
|
||
compatible: "zephyr,flash-no-erase" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
description: | | ||
This binding is used to describe fixed partitions of a flash memory. | ||
Here is an example: | ||
&flash0 { | ||
partitions { | ||
compatible = "zephyr,flash-partitions"; | ||
#address-cells = <1>; | ||
#size-cells = <1>; | ||
boot_partition: partition@0 { | ||
label = "mcuboot"; | ||
reg = <0x00000000 0x0000C000>; | ||
}; | ||
slot0_partition: partition@c000 { | ||
label = "image-0"; | ||
reg = <0x0000C000 0x00076000>; | ||
}; | ||
slot1_partition: partition@82000 { | ||
label = "image-1"; | ||
reg = <0x00082000 0x00076000>; | ||
}; | ||
/* | ||
* The flash starting at 0x000f8000 and ending at | ||
* 0x000fffff is reserved for use by the application. | ||
*/ | ||
/* | ||
* Storage partition will be used by FCB/LittleFS/NVS | ||
* if enabled. | ||
*/ | ||
storage_partition: partition@f8000 { | ||
label = "storage"; | ||
reg = <0x000f8000 0x00008000>; | ||
}; | ||
}; | ||
}; | ||
Note that the usual name for this node is 'partitions'. | ||
The zephyr,flash-partitions node should be a child of the flash | ||
memory node. Note also that the flash memory node is usually | ||
different from the node representing the flash controller | ||
IP block. | ||
Above, slot0_partition's register address 0xc000 means that | ||
the partition begins at that offset from the parent flash | ||
memory flash0's base address. That is, partition addresses | ||
are relative; physical addresses must be calculated by adding | ||
the start address of flash0 in memory to each partition's | ||
reg address. | ||
compatible: "zephyr,flash-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 zephyr,flash-partitions node represents | ||
an individual flash 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 flash partition. | ||
read-only: | ||
type: boolean | ||
description: set this property if the partition is read-only | ||
erase-block-size: | ||
type: int | ||
description: override value for the flash node erase-block-size. | ||
reg: | ||
type: array | ||
description: | | ||
This should be in the format <OFFSET SIZE>, where OFFSET | ||
is the offset of the flash partition relative to the base | ||
address of the parent memory, and SIZE is the size of | ||
the partition in bytes. | ||
required: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
/* | ||
* Copyright (c) 2024 Laczen | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
/** | ||
* @file | ||
* @brief Public API for flash partitions | ||
*/ | ||
|
||
#ifndef ZEPHYR_INCLUDE_FLASH_PARTITIONS_H_ | ||
#define ZEPHYR_INCLUDE_FLASH_PARTITIONS_H_ | ||
|
||
/** | ||
* @brief Abstraction over flash memory and its partitions | ||
* | ||
* @defgroup flash_partitions_api flash_partitions interface | ||
* @{ | ||
*/ | ||
|
||
/* | ||
* This API makes it possible to operate on flash partitions easily and | ||
* effectively. | ||
*/ | ||
|
||
#include <errno.h> | ||
#include <sys/types.h> | ||
#include <zephyr/device.h> | ||
#include <zephyr/devicetree.h> | ||
#include <zephyr/drivers/flash.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* The flash_partitions subsystem provide an abstraction layer between flash | ||
* memory specific drivers and higher-level applications for flash memory | ||
* partitions. On flash partitions the following routines for operation are | ||
* provided: open, read, write, erase, clear and close. | ||
* | ||
*/ | ||
|
||
/** | ||
* @brief Retrieve a pointer to the flash partition info struct. | ||
* | ||
* A flash partition with nodelabel "nodelabel" is retrieved as: | ||
* const struct flash_partition *fp = FLASH_PARTITION_GET(nodelabel) | ||
* | ||
* @param nodelabel of the flash partition. | ||
*/ | ||
#define FLASH_PARTITION_GET(nodelabel) \ | ||
&UTIL_CAT(flash_partition_, DT_NODELABEL(nodelabel)) | ||
|
||
/** | ||
* @brief flash_partition represents a flash partition. | ||
*/ | ||
struct flash_partition { | ||
/** flash device */ | ||
const struct device *fldev; | ||
/** flash partition size */ | ||
const size_t size; | ||
/** flash partition offset on flash device */ | ||
const size_t offset; | ||
/** flash partition erase-block-size */ | ||
const size_t erase_block_size; | ||
/** flash partition routines */ | ||
int (*const open)(const struct flash_partition *partition); | ||
int (*const read)(const struct flash_partition *partition, size_t start, | ||
void *data, size_t len); | ||
int (*const write)(const struct flash_partition *partition, size_t start, | ||
const void *data, size_t len); | ||
int (*const erase)(const struct flash_partition *partition, size_t start, | ||
size_t len); | ||
int (*const close)(const struct flash_partition *partition); | ||
}; | ||
|
||
/** | ||
* @brief Get the size in byte of a flash partition. | ||
* | ||
* @param[in] partition flash partition | ||
* @return the size. | ||
*/ | ||
size_t flash_partition_get_size(const struct flash_partition *partition); | ||
|
||
/** | ||
* @brief Get the erase-block-size in byte of a flash partition. | ||
* | ||
* @param[in] partition flash partition | ||
* @return the size. | ||
*/ | ||
size_t flash_partition_get_ebs(const struct flash_partition *partition); | ||
|
||
/** | ||
* @brief Open a flash partition. | ||
* | ||
* @param[in] partition flash partition | ||
* | ||
* @return 0 on success, negative errno code on fail. | ||
*/ | ||
int flash_partition_open(const struct flash_partition *partition); | ||
|
||
/** | ||
* @brief Read data from flash partition. Read boundaries are verified before | ||
* read request is executed. | ||
* | ||
* | ||
* @param[in] partition flash partition | ||
* @param[in] start point relative from beginning of flash partition | ||
* @param[out] data Buffer to store read data | ||
* @param[in] len Size to read | ||
* | ||
* @return 0 on success, negative errno code on fail. | ||
*/ | ||
int flash_partition_read(const struct flash_partition *partition, size_t start, | ||
void *data, size_t len); | ||
|
||
/** | ||
* @brief Write data to flash partition. Write boundaries are verified before | ||
* write request is executed. | ||
* | ||
* @param[in] partition flash partition | ||
* @param[in] start point relative from beginning of flash partition | ||
* @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 flash_partition_write(const struct flash_partition *partition, size_t start, | ||
const void *data, size_t len); | ||
|
||
/** | ||
* @brief Erase range on flash partition. Erase boundaries are verified before | ||
* erase is executed. | ||
* | ||
* @param[in] partition flash partition | ||
* @param[in] start point relative from beginning of flash partition | ||
* @param[in] len Size to erase | ||
* | ||
* @return 0 on success, negative errno code on fail. | ||
*/ | ||
int flash_partition_erase(const struct flash_partition *partition, size_t start, | ||
size_t len); | ||
|
||
/** | ||
* @brief Close a flash partition. | ||
* | ||
* @param[in] partition flash partition | ||
* | ||
* @return 0 on success, negative errno code on fail. | ||
*/ | ||
int flash_partition_close(const struct flash_partition *partition); | ||
|
||
/** @cond INTERNAL_HIDDEN */ | ||
|
||
#define FLASH_PARTITION_DECLARE(n) \ | ||
extern const struct flash_partition flash_partition_##n; | ||
|
||
#define FLASH_PARTITIONS_DECLARE(inst) \ | ||
DT_FOREACH_CHILD_STATUS_OKAY(inst, FLASH_PARTITION_DECLARE) | ||
|
||
DT_FOREACH_STATUS_OKAY(zephyr_flash_partitions, FLASH_PARTITIONS_DECLARE) | ||
/** @endcond */ | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
/** | ||
* @} | ||
*/ | ||
|
||
#endif /* ZEPHYR_INCLUDE_FLASH_PARTITIONS_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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_FLASH_PARTITIONS flash_partitions) | ||
add_subdirectory_ifdef(CONFIG_STREAM_FLASH stream) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
zephyr_library() | ||
zephyr_library_sources(flash_partitions.c) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Copyright (c) 2024, Laczen | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
menuconfig FLASH_PARTITIONS | ||
bool "flash partitions support" | ||
default y if DT_HAS_ZEPHYR_FLASH_PARTITIONS_ENABLED | ||
select FLASH | ||
help | ||
Enables support for the flash partitions system, which enables using | ||
unified routines to work with partitions defined on flash devices. | ||
|
||
if FLASH_PARTITIONS | ||
|
||
config FLASH_PARTITIONS_RUNTIME_VERIFY | ||
bool "runtime verification of erase-block-size" | ||
default n | ||
select FLASH_PAGE_LAYOUT | ||
help | ||
Enable runtime verification that erase-block-size is a multiple of the | ||
flash erase block size. | ||
|
||
module = FLASH_PARTITIONS | ||
module-str = flash_partitions | ||
source "subsys/logging/Kconfig.template.log_config" | ||
|
||
endif #FLASH_PARTITIONS |
Oops, something went wrong.