Skip to content

Commit

Permalink
drivers: flash: shell: add "flash copy" command
Browse files Browse the repository at this point in the history
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 <src_dev> <dst_dev> <src_offs> <dest_offs> <size>

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 <cfriedt@tenstorrent.com>
  • Loading branch information
Chris Friedt authored and nashif committed Oct 8, 2024
1 parent ccc7891 commit 41e4b53
Showing 1 changed file with 56 additions and 17 deletions.
73 changes: 56 additions & 17 deletions drivers/flash/flash_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,33 @@
* SPDX-License-Identifier: Apache-2.0
*/

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <zephyr/kernel.h>
#include <zephyr/devicetree.h>

#include <zephyr/drivers/flash.h>
#include <zephyr/shell/shell.h>
#include <zephyr/sys/util.h>

#include <stdlib.h>
#include <string.h>
#include <zephyr/drivers/flash.h>

/* 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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
"<src_device> <dst_device> <src_offset> <dst_offset> <size>",
cmd_copy, 5, 5),
SHELL_CMD_ARG(erase, &dsub_device_name,
"[<device>] <page address> [<size>]",
cmd_erase, 2, 2),
Expand Down

0 comments on commit 41e4b53

Please sign in to comment.