From 41e4b5323ac3888c45763ed7574c892cf3907fb5 Mon Sep 17 00:00:00 2001 From: Chris Friedt Date: Sat, 13 Jul 2024 11:38:58 -0400 Subject: [PATCH] drivers: flash: shell: add "flash copy" command Add a flash copy command, capable of copying a region in one flash device to a region on the same or another flash device. The destination is erased prior to copying. This is useful for evaluating mcuboot on devices with little on-chip resources, or devices that are incapable of running more elaborate image management services (e.g. via bluetooth or networking). Additionally, it's useful for evaluating mcuboot on devices with one or more images stored on external spi flash. The command syntax is flash copy E.g. flash copy flash@0 flash-controller@abcd1234 0x1234 0x5678 21012 Copied 21012 bytes from flash@0:1234 to \ flash-controller@abcd1234:5678 Signed-off-by: Chris Friedt --- drivers/flash/flash_shell.c | 73 ++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 17 deletions(-) diff --git a/drivers/flash/flash_shell.c b/drivers/flash/flash_shell.c index a0d6a19a2332a9..74b490266e747e 100644 --- a/drivers/flash/flash_shell.c +++ b/drivers/flash/flash_shell.c @@ -5,19 +5,33 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include +#include +#include +#include +#include + #include #include - +#include #include #include -#include -#include -#include - /* Buffer is only needed for bytes that follow command and offset */ #define BUF_ARRAY_CNT (CONFIG_SHELL_ARGC_MAX - 2) +#define FLASH_LOAD_BUF_MAX 256 + +static const struct device *flash_load_dev; +static uint32_t flash_load_buf_size; +static uint32_t flash_load_addr; +static uint32_t flash_load_total; +static uint32_t flash_load_written; +static uint32_t flash_load_chunk; + +static uint32_t flash_load_boff; +static uint8_t flash_load_buf[FLASH_LOAD_BUF_MAX]; + /* This only issues compilation error when it would not be possible * to extract at least one byte from command line arguments, yet * it does not warrant successful writes if BUF_ARRAY_CNT @@ -165,6 +179,40 @@ static int cmd_write(const struct shell *sh, size_t argc, char *argv[]) return 0; } +static int cmd_copy(const struct shell *sh, size_t argc, char *argv[]) +{ + int ret; + uint32_t size = 0; + uint32_t src_offset = 0; + uint32_t dst_offset = 0; + const struct device *src_dev = NULL; + const struct device *dst_dev = NULL; + + if (argc < 5) { + shell_error(sh, "missing parameters"); + return -EINVAL; + } + + src_dev = device_get_binding(argv[1]); + dst_dev = device_get_binding(argv[2]); + src_offset = strtoul(argv[3], NULL, 0); + dst_offset = strtoul(argv[4], NULL, 0); + /* size will be padded to write_size bytes */ + size = strtoul(argv[5], NULL, 0); + + ret = flash_copy(src_dev, src_offset, dst_dev, dst_offset, size, flash_load_buf, + sizeof(flash_load_buf)); + if (ret < 0) { + shell_error(sh, "%s failed: %d", "flash_copy()", ret); + return -EIO; + } + + shell_print(sh, "Copied %u bytes from %s:%x to %s:%x", size, argv[1], src_offset, argv[2], + dst_offset); + + return 0; +} + static int cmd_read(const struct shell *sh, size_t argc, char *argv[]) { const struct device *flash_dev; @@ -544,18 +592,6 @@ static int set_bypass(const struct shell *sh, shell_bypass_cb_t bypass) return 0; } -#define FLASH_LOAD_BUF_MAX 256 - -static const struct device *flash_load_dev; -static uint32_t flash_load_buf_size; -static uint32_t flash_load_addr; -static uint32_t flash_load_total; -static uint32_t flash_load_written; -static uint32_t flash_load_chunk; - -static uint32_t flash_load_boff; -static uint8_t flash_load_buf[FLASH_LOAD_BUF_MAX]; - static void bypass_cb(const struct shell *sh, uint8_t *recv, size_t len) { uint32_t left_to_read = flash_load_total - flash_load_written - flash_load_boff; @@ -711,6 +747,9 @@ static void device_name_get(size_t idx, struct shell_static_entry *entry) } SHELL_STATIC_SUBCMD_SET_CREATE(flash_cmds, + SHELL_CMD_ARG(copy, &dsub_device_name, + " ", + cmd_copy, 5, 5), SHELL_CMD_ARG(erase, &dsub_device_name, "[] []", cmd_erase, 2, 2),