dts: flash_map: Automatically generate of the list of flash area
This Patch add functionality for automatic generation of the flash map using DTS description. Automatic generation allows to replace C-hardcoded flash_map. We generate a set of defines based on the index of a partiion: #define DT_FLASH_AREA_<IDX>_OFFSET 0 #define DT_FLASH_AREA_<IDX>_SIZE 131072 #define DT_FLASH_AREA_<IDX>_DEV "FLASH_CTRL" #define DT_FLASH_AREA_<IDX>_LABEL MCUBOOT Additionally we also define: #define DT_FLASH_AREA_NUM 4 and: #define DT_FLASH_AREA_<PARTNAME>_ID 0 Signed-off-by: Findlay Feng <i@fengch.me> Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
This commit is contained in:
parent
85c8c0fe3c
commit
69c15f0ed1
4 changed files with 81 additions and 94 deletions
|
@ -42,6 +42,7 @@ struct flash_area {
|
|||
u16_t pad16;
|
||||
off_t fa_off;
|
||||
size_t fa_size;
|
||||
const char *fa_dev_name;
|
||||
};
|
||||
|
||||
struct flash_sector {
|
||||
|
|
|
@ -18,12 +18,80 @@ class DTFlash(DTDirective):
|
|||
def __init__(self):
|
||||
# Node of the flash
|
||||
self._flash_node = None
|
||||
self._flash_area = {}
|
||||
|
||||
def _extract_partition(self, node_address):
|
||||
prop_def = {}
|
||||
prop_alias = {}
|
||||
node = reduced[node_address]
|
||||
|
||||
partition_name = node['props']['label']
|
||||
partition_sectors = node['props']['reg']
|
||||
|
||||
# Build Index based partition IDs
|
||||
if node_address in self._flash_area:
|
||||
area_id = self._flash_area[node_address]["id"]
|
||||
else:
|
||||
area_id = len(self._flash_area)
|
||||
self._flash_area[node_address] = {'id': area_id }
|
||||
partition_idx = str(area_id)
|
||||
|
||||
# Extract a per partition dev name, something like:
|
||||
# #define DT_FLASH_AREA_1_DEV "FLASH_CTRL"
|
||||
|
||||
# For now assume node_address is something like:
|
||||
# /flash-controller@4001E000/flash@0/partitions/partition@fc000
|
||||
# and we go up 3 levels to get the controller
|
||||
ctrl_addr = '/' + '/'.join(node_address.split('/')[1:-3])
|
||||
|
||||
node = reduced[ctrl_addr]
|
||||
name = "\"{}\"".format(node['props']['label'])
|
||||
|
||||
for area in self._flash_area.keys():
|
||||
if ctrl_addr in area:
|
||||
label = self.get_label_string(["DT_FLASH_AREA", partition_idx, "DEV"])
|
||||
prop_def[label] = name
|
||||
|
||||
label = self.get_label_string(["DT_FLASH_AREA"] + [partition_name] + ["ID",])
|
||||
prop_def[label] = area_id
|
||||
|
||||
label_prefix = ["DT_FLASH_AREA", partition_idx]
|
||||
|
||||
index = 0
|
||||
while index < len(partition_sectors):
|
||||
sector_index = int(index/2)
|
||||
sector_start_offset = partition_sectors[index]
|
||||
sector_size = partition_sectors[index + 1]
|
||||
label = self.get_label_string(
|
||||
label_prefix + ["OFFSET", str(sector_index)])
|
||||
prop_def[label] = "{}".format(sector_start_offset)
|
||||
label = self.get_label_string(
|
||||
label_prefix + ["SIZE", str(sector_index)])
|
||||
prop_def[label] = "{}".format(sector_size)
|
||||
index += 2
|
||||
|
||||
# alias sector 0
|
||||
label = self.get_label_string(label_prefix + ["OFFSET",])
|
||||
prop_alias[label] = self.get_label_string(
|
||||
label_prefix + ["OFFSET", '0'])
|
||||
label = self.get_label_string(label_prefix + ["SIZE",])
|
||||
prop_alias[label] = self.get_label_string(
|
||||
label_prefix + ["SIZE", '0'])
|
||||
|
||||
label = self.get_label_string(["DT_FLASH_AREA", partition_idx, "LABEL"])
|
||||
prop_def[label] = self.get_label_string([partition_name,])
|
||||
|
||||
prop_def["DT_FLASH_AREA_NUM"] = len(self._flash_area)
|
||||
|
||||
insert_defs("DT_FLASH_AREA", prop_def, prop_alias)
|
||||
|
||||
def extract_partition(self, node_address):
|
||||
prop_def = {}
|
||||
prop_alias = {}
|
||||
node = reduced[node_address]
|
||||
|
||||
self._extract_partition(node_address)
|
||||
|
||||
partition_name = node['props']['label']
|
||||
partition_sectors = node['props']['reg']
|
||||
|
||||
|
|
|
@ -26,26 +26,8 @@ struct layout_data {
|
|||
};
|
||||
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
|
||||
|
||||
struct driver_map_entry {
|
||||
u8_t id;
|
||||
const char * const name;
|
||||
};
|
||||
|
||||
static const struct driver_map_entry flash_drivers_map[] = {
|
||||
#ifdef DT_FLASH_DEV_NAME /* SoC embedded flash driver */
|
||||
{SOC_FLASH_0_ID, DT_FLASH_DEV_NAME},
|
||||
#endif
|
||||
#ifdef CONFIG_SPI_FLASH_W25QXXDV
|
||||
{SPI_FLASH_0_ID, CONFIG_SPI_FLASH_W25QXXDV_DRV_NAME},
|
||||
#endif
|
||||
#ifdef DT_SPI_NOR_DRV_NAME
|
||||
{SPI_FLASH_0_ID, DT_SPI_NOR_DRV_NAME},
|
||||
#endif
|
||||
};
|
||||
|
||||
extern const struct flash_area *flash_map;
|
||||
extern const int flash_map_entries;
|
||||
static struct device *flash_dev[ARRAY_SIZE(flash_drivers_map)];
|
||||
|
||||
static struct flash_area const *get_flash_area_from_id(int idx)
|
||||
{
|
||||
|
@ -80,17 +62,6 @@ void flash_area_close(const struct flash_area *fa)
|
|||
/* nothing to do for now */
|
||||
}
|
||||
|
||||
static struct device *get_flash_dev_from_id(u8_t id)
|
||||
{
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(flash_drivers_map); i++) {
|
||||
if (flash_drivers_map[i].id == id) {
|
||||
return flash_dev[i];
|
||||
}
|
||||
}
|
||||
|
||||
k_panic();
|
||||
}
|
||||
|
||||
static inline bool is_in_flash_area_bounds(const struct flash_area *fa,
|
||||
off_t off, size_t len)
|
||||
{
|
||||
|
@ -159,7 +130,7 @@ flash_page_cb cb, struct layout_data *cb_data)
|
|||
cb_data->ret_len = *cnt;
|
||||
cb_data->status = 0;
|
||||
|
||||
flash_dev = get_flash_dev_from_id(fa->fa_device_id);
|
||||
flash_dev = device_get_binding(fa->fa_dev_name);
|
||||
|
||||
flash_page_foreach(flash_dev, cb, cb_data);
|
||||
|
||||
|
@ -204,7 +175,7 @@ int flash_area_read(const struct flash_area *fa, off_t off, void *dst,
|
|||
return -1;
|
||||
}
|
||||
|
||||
dev = get_flash_dev_from_id(fa->fa_device_id);
|
||||
dev = device_get_binding(fa->fa_dev_name);
|
||||
|
||||
return flash_read(dev, fa->fa_off + off, dst, len);
|
||||
}
|
||||
|
@ -219,7 +190,7 @@ int flash_area_write(const struct flash_area *fa, off_t off, const void *src,
|
|||
return -1;
|
||||
}
|
||||
|
||||
flash_dev = get_flash_dev_from_id(fa->fa_device_id);
|
||||
flash_dev = device_get_binding(fa->fa_dev_name);
|
||||
|
||||
rc = flash_write_protection_set(flash_dev, false);
|
||||
if (rc) {
|
||||
|
@ -243,7 +214,7 @@ int flash_area_erase(const struct flash_area *fa, off_t off, size_t len)
|
|||
return -1;
|
||||
}
|
||||
|
||||
flash_dev = get_flash_dev_from_id(fa->fa_device_id);
|
||||
flash_dev = device_get_binding(fa->fa_dev_name);
|
||||
|
||||
rc = flash_write_protection_set(flash_dev, false);
|
||||
if (rc) {
|
||||
|
@ -262,29 +233,16 @@ u8_t flash_area_align(const struct flash_area *fa)
|
|||
{
|
||||
struct device *dev;
|
||||
|
||||
dev = get_flash_dev_from_id(fa->fa_device_id);
|
||||
dev = device_get_binding(fa->fa_dev_name);
|
||||
|
||||
return flash_get_write_block_size(dev);
|
||||
}
|
||||
|
||||
int flash_area_has_driver(const struct flash_area *fa)
|
||||
{
|
||||
if (get_flash_dev_from_id(fa->fa_device_id) == NULL) {
|
||||
if (device_get_binding(fa->fa_dev_name) == NULL) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int flash_map_init(struct device *dev)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0U; i < ARRAY_SIZE(flash_dev); i++) {
|
||||
flash_dev[i] = device_get_binding(flash_drivers_map[i].name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(flash_map_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
|
||||
|
|
|
@ -8,54 +8,14 @@
|
|||
#include <zephyr.h>
|
||||
#include <flash_map.h>
|
||||
|
||||
#if defined(DT_FLASH_DEV_NAME)
|
||||
#define FA_DEV_ID SOC_FLASH_0_ID
|
||||
#elif defined(CONFIG_SPI_FLASH_W25QXXDV) || defined(DT_JEDEC_SPI_NOR_0_LABEL)
|
||||
#define FA_DEV_ID SPI_FLASH_0_ID
|
||||
#endif
|
||||
#define FLASH_AREA_FOO(i, _) \
|
||||
{.fa_id = i, \
|
||||
.fa_off = DT_FLASH_AREA_##i##_OFFSET, \
|
||||
.fa_dev_name = DT_FLASH_AREA_##i##_DEV, \
|
||||
.fa_size = DT_FLASH_AREA_##i##_SIZE,},
|
||||
|
||||
const struct flash_area default_flash_map[] = {
|
||||
/* FLASH_AREA_BOOTLOADER */
|
||||
{
|
||||
.fa_id = 0,
|
||||
.fa_device_id = FA_DEV_ID,
|
||||
.fa_off = FLASH_AREA_MCUBOOT_OFFSET,
|
||||
.fa_size = FLASH_AREA_MCUBOOT_SIZE,
|
||||
},
|
||||
|
||||
/* FLASH_AREA_IMAGE_0 */
|
||||
{
|
||||
.fa_id = 1,
|
||||
.fa_device_id = FA_DEV_ID,
|
||||
.fa_off = FLASH_AREA_IMAGE_0_OFFSET,
|
||||
.fa_size = FLASH_AREA_IMAGE_0_SIZE,
|
||||
},
|
||||
|
||||
/* FLASH_AREA_IMAGE_1 */
|
||||
{
|
||||
.fa_id = 2,
|
||||
.fa_device_id = FA_DEV_ID,
|
||||
.fa_off = FLASH_AREA_IMAGE_1_OFFSET,
|
||||
.fa_size = FLASH_AREA_IMAGE_1_SIZE,
|
||||
},
|
||||
|
||||
/* FLASH_AREA_IMAGE_SCRATCH */
|
||||
{
|
||||
.fa_id = 3,
|
||||
.fa_device_id = FA_DEV_ID,
|
||||
.fa_off = FLASH_AREA_IMAGE_SCRATCH_OFFSET,
|
||||
.fa_size = FLASH_AREA_IMAGE_SCRATCH_SIZE,
|
||||
},
|
||||
|
||||
#ifdef CONFIG_FS_FLASH_STORAGE_PARTITION
|
||||
/* FLASH_AREA_STORAGE */
|
||||
{
|
||||
.fa_id = 4,
|
||||
.fa_device_id = FA_DEV_ID,
|
||||
.fa_off = FLASH_AREA_STORAGE_OFFSET,
|
||||
.fa_size = FLASH_AREA_STORAGE_SIZE,
|
||||
},
|
||||
#endif
|
||||
UTIL_LISTIFY(DT_FLASH_AREA_NUM, FLASH_AREA_FOO, ~)
|
||||
};
|
||||
|
||||
const int flash_map_entries = ARRAY_SIZE(default_flash_map);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue