samples: flash_shell: migrate example to new shell
Convert flash_shell example to use the new shell API. Signed-off-by: Jakub Rzeszutko <jakub.rzeszutko@nordicsemi.no>
This commit is contained in:
parent
4db9731451
commit
3d4c525c4c
2 changed files with 300 additions and 233 deletions
|
@ -1,11 +1,10 @@
|
|||
CONFIG_PRINTK=y
|
||||
CONFIG_CONSOLE_SHELL=y
|
||||
CONFIG_KERNEL_SHELL=y
|
||||
CONFIG_SHELL=y
|
||||
CONFIG_SERIAL=y
|
||||
CONFIG_LOG=y
|
||||
CONFIG_FLASH=y
|
||||
# Your flash driver may not enable this, even if it's supported.
|
||||
# If that's the case and you're interested in the flash layout, enable
|
||||
# it here.
|
||||
# CONFIG_FLASH_PAGE_LAYOUT=y
|
||||
CONFIG_MPU_ALLOW_FLASH_WRITE=y
|
||||
|
||||
CONFIG_LOG=y
|
||||
|
|
|
@ -9,13 +9,27 @@
|
|||
|
||||
#include <zephyr.h>
|
||||
#include <misc/printk.h>
|
||||
#include <shell/legacy_shell.h>
|
||||
#include <logging/log.h>
|
||||
#include <shell/shell.h>
|
||||
#include <shell/shell_uart.h>
|
||||
#include <flash.h>
|
||||
#include <device.h>
|
||||
#include <soc.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define THIS_MODULE_NAME "flash"
|
||||
LOG_MODULE_REGISTER(app);
|
||||
|
||||
SHELL_UART_DEFINE(shell_transport_uart);
|
||||
SHELL_DEFINE(uart_shell, "uart:~$ ", &shell_transport_uart, 10);
|
||||
|
||||
#define PR_SHELL(shell, fmt, ...) \
|
||||
shell_fprintf(shell, SHELL_NORMAL, fmt, ##__VA_ARGS__)
|
||||
#define PR_ERROR(shell, fmt, ...) \
|
||||
shell_fprintf(shell, SHELL_ERROR, fmt, ##__VA_ARGS__)
|
||||
#define PR_INFO(fshell, fmt, ...) \
|
||||
shell_fprintf(shell, SHELL_INFO, fmt, ##__VA_ARGS__)
|
||||
#define PR_WARNING(shell, fmt, ...) \
|
||||
shell_fprintf(shell, SHELL_WARNING, fmt, ##__VA_ARGS__)
|
||||
/*
|
||||
* When FLASH_DEV_NAME is available, we use it here. Otherwise,
|
||||
* the device can be set at runtime with the set_device command.
|
||||
|
@ -26,10 +40,10 @@
|
|||
|
||||
/* Command usage info. */
|
||||
#define WRITE_BLOCK_SIZE_HELP \
|
||||
("Print the device's write block size. This is the smallest amount\n" \
|
||||
"of data which may be written to the device, in bytes.")
|
||||
("Print the device's write block size. This is the smallest amount" \
|
||||
" of data which may be written to the device, in bytes.")
|
||||
#define READ_HELP \
|
||||
("<off> <len>\n\n" \
|
||||
("<off> <len>\n" \
|
||||
"Read <len> bytes from device offset <off>.")
|
||||
#define ERASE_HELP \
|
||||
("<off> <len>\n\n" \
|
||||
|
@ -44,82 +58,69 @@
|
|||
"\n\nPrint the number of pages on the flash device."
|
||||
#define PAGE_LAYOUT_HELP \
|
||||
("[start_page] [end_page]\n\n" \
|
||||
"Print layout of flash pages in the range [start_page, end_page],\n" \
|
||||
"which is inclusive. By default, all pages are printed.")
|
||||
#define READ_PAGE_HELP \
|
||||
"Print layout of flash pages in the range [start_page, end_page]," \
|
||||
" which is inclusive. By default, all pages are printed.")
|
||||
#define PAGE_READ_HELP \
|
||||
("<page> <len> OR <page> <off> <len>\n\n" \
|
||||
"Read <len> bytes from given page, starting at page offset <off>,\n" \
|
||||
"or offset 0 if not given. No checks are made that bytes read are\n" \
|
||||
"all within the page.")
|
||||
#define ERASE_PAGE_HELP \
|
||||
"Read <len> bytes from given page, starting at page offset <off>," \
|
||||
"or offset 0 if not given. No checks are made that bytes read are" \
|
||||
" all within the page.")
|
||||
#define PAGE_ERASE_HELP \
|
||||
("<page> [num]\n\n" \
|
||||
"Erase [num] pages (default 1), starting at page <page>.")
|
||||
#define WRITE_PAGE_HELP \
|
||||
#define PAGE_WRITE_HELP \
|
||||
("<page> <off> <byte1> [... byteN]\n\n" \
|
||||
"Write given bytes to given page, starting at page offset <off>.\n" \
|
||||
"No checks are made that the bytes all fall within the page.\n" \
|
||||
"Pages must be erased before they can be written.")
|
||||
"Write given bytes to given page, starting at page offset <off>." \
|
||||
" No checks are made that the bytes all fall within the page." \
|
||||
" Pages must be erased before they can be written.")
|
||||
#endif
|
||||
#define SET_DEVICE_HELP \
|
||||
#define SET_DEV_HELP \
|
||||
("<device_name>\n\n" \
|
||||
"Set flash device by name. If a flash device was not found,\n" \
|
||||
"this command must be run first to bind a device to this module.")
|
||||
"Set flash device by name. If a flash device was not found," \
|
||||
" this command must be run first to bind a device to this module.")
|
||||
|
||||
/*
|
||||
* Canonicalize argc/argv.
|
||||
*
|
||||
* When run as "<command> <arguments>", i.e. after running "select
|
||||
* flash", the module name is not part of argv. When run as "flash
|
||||
* <command> <arguments>", it is. Normalize argc and argv to skip
|
||||
* "flash" regardless of the case.
|
||||
*/
|
||||
#define CANONICALIZE_ARGS(argc, argv) do { \
|
||||
if (!strcmp(argv[0], THIS_MODULE_NAME)) { \
|
||||
argc--; \
|
||||
argv++; \
|
||||
} \
|
||||
/* Skip the command name as well. */ \
|
||||
argc--; \
|
||||
argv++; \
|
||||
} while (0)
|
||||
|
||||
#define ARGC_MAX 10 /* from shell.c */
|
||||
#if (CONFIG_SHELL_ARGC_MAX > 4)
|
||||
#define ARGC_MAX (CONFIG_SHELL_ARGC_MAX - 4)
|
||||
#else
|
||||
#error Please increase CONFIG_SHELL_ARGC_MAX parameter.
|
||||
#endif
|
||||
|
||||
static struct device *flash_device;
|
||||
|
||||
static int check_flash_device(void)
|
||||
static int check_flash_device(const struct shell *shell)
|
||||
{
|
||||
if (flash_device == NULL) {
|
||||
printk("Flash device is unknown. Run set_device first.\n");
|
||||
PR_ERROR(shell, "Flash device is unknown."
|
||||
" Run set_device first.\r\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dump_buffer(u8_t *buf, size_t size)
|
||||
static void dump_buffer(const struct shell *shell, u8_t *buf, size_t size)
|
||||
{
|
||||
bool newline = false;
|
||||
u8_t *p = buf;
|
||||
|
||||
while (size >= 8) {
|
||||
printk("%02x %02x %02x %02x | %02x %02x %02x %02x\n",
|
||||
PR_SHELL(shell, "%02x %02x %02x %02x | %02x %02x %02x %02x\r\n",
|
||||
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
|
||||
p += 8;
|
||||
size -= 8;
|
||||
}
|
||||
if (size > 4) {
|
||||
printk("%02x %02x %02x %02x | ",
|
||||
PR_SHELL(shell, "%02x %02x %02x %02x | ",
|
||||
p[0], p[1], p[2], p[3]);
|
||||
p += 4;
|
||||
size -= 4;
|
||||
newline = true;
|
||||
}
|
||||
while (size--) {
|
||||
printk("%02x ", *p++);
|
||||
PR_SHELL(shell, "%02x ", *p++);
|
||||
newline = true;
|
||||
}
|
||||
if (newline) {
|
||||
printk("\n");
|
||||
PR_SHELL(shell, "\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,6 +142,7 @@ static int parse_ul(const char *str, unsigned long *result)
|
|||
static int parse_u8(const char *str, u8_t *result)
|
||||
{
|
||||
unsigned long val;
|
||||
|
||||
if (parse_ul(str, &val) || val > 0xff) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -149,7 +151,7 @@ static int parse_u8(const char *str, u8_t *result)
|
|||
}
|
||||
|
||||
/* Read bytes, dumping contents to console and printing on error. */
|
||||
static int do_read(off_t offset, size_t len)
|
||||
static int do_read(const struct shell *shell, off_t offset, size_t len)
|
||||
{
|
||||
u8_t buf[64];
|
||||
int ret;
|
||||
|
@ -159,7 +161,7 @@ static int do_read(off_t offset, size_t len)
|
|||
if (ret) {
|
||||
goto err_read;
|
||||
}
|
||||
dump_buffer(buf, sizeof(buf));
|
||||
dump_buffer(shell, buf, sizeof(buf));
|
||||
len -= sizeof(buf);
|
||||
offset += sizeof(buf);
|
||||
}
|
||||
|
@ -167,192 +169,228 @@ static int do_read(off_t offset, size_t len)
|
|||
if (ret) {
|
||||
goto err_read;
|
||||
}
|
||||
dump_buffer(buf, len);
|
||||
dump_buffer(shell, buf, len);
|
||||
return 0;
|
||||
|
||||
err_read:
|
||||
printk("flash_read: %d\n", ret);
|
||||
return 0;
|
||||
PR_ERROR(shell, "flash_read error: %d\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Erase area, handling write protection and printing on error. */
|
||||
static int do_erase(off_t offset, size_t size)
|
||||
static int do_erase(const struct shell *shell, off_t offset, size_t size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = flash_write_protection_set(flash_device, false);
|
||||
if (ret) {
|
||||
printk("flash_write_protection_set: %d (can't disable)\n", ret);
|
||||
PR_ERROR(shell, "Failed to disable flash protection (err: %d)."
|
||||
"\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = flash_erase(flash_device, offset, size);
|
||||
if (ret) {
|
||||
printk("flash_erase: %d\n", ret);
|
||||
PR_ERROR(shell, "flash_erase failed (err:%d).\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = flash_write_protection_set(flash_device, true);
|
||||
if (ret) {
|
||||
printk("flash_write_protection_set: %d (can't enable)\n", ret);
|
||||
PR_ERROR(shell, "Failed to enable flash protection (err: %d)."
|
||||
"\r\n", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Write bytes, handling write protection and printing on error. */
|
||||
static int do_write(off_t offset, u8_t *buf, size_t len, bool read_back)
|
||||
static int do_write(const struct shell *shell, off_t offset, u8_t *buf,
|
||||
size_t len, bool read_back)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = flash_write_protection_set(flash_device, false);
|
||||
if (ret) {
|
||||
printk("flash_write_protection_set: %d (can't disable)\n", ret);
|
||||
PR_ERROR(shell, "Failed to disable flash protection (err: %d)."
|
||||
"\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = flash_write(flash_device, offset, buf, len);
|
||||
if (ret) {
|
||||
printk("flash_write: %d\n", ret);
|
||||
PR_ERROR(shell, "flash_write failed (err:%d).\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = flash_write_protection_set(flash_device, true);
|
||||
if (ret) {
|
||||
printk("flash_write_protection_set: %d (can't enable)\n", ret);
|
||||
PR_ERROR(shell, "Failed to enable flash protection (err: %d)."
|
||||
"\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
if (read_back) {
|
||||
printk("Reading back written bytes:\n");
|
||||
ret = do_read(offset, len);
|
||||
PR_SHELL(shell, "Reading back written bytes:\r\n");
|
||||
ret = do_read(shell, offset, len);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int flash_shell_write_block_size(int argc, char *argv[])
|
||||
static int cmd_flash(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
if (check_flash_device()) {
|
||||
return 0;
|
||||
}
|
||||
ARG_UNUSED(argc);
|
||||
ARG_UNUSED(argv);
|
||||
|
||||
CANONICALIZE_ARGS(argc, argv);
|
||||
if (argc) {
|
||||
printk("No arguments expected.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printk("%d\n", flash_get_write_block_size(flash_device));
|
||||
shell_help_print(shell, NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int flash_shell_read(int argc, char *argv[])
|
||||
{
|
||||
long unsigned int offset, len;
|
||||
|
||||
if (check_flash_device()) {
|
||||
static int cmd_write_block_size(const struct shell *shell, size_t argc,
|
||||
char **argv)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!shell_cmd_precheck(shell, argc == 1, NULL, 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CANONICALIZE_ARGS(argc, argv);
|
||||
if (argc != 2 || parse_ul(argv[0], &offset) ||
|
||||
parse_ul(argv[1], &len)) {
|
||||
goto bail;
|
||||
err = check_flash_device(shell);
|
||||
if (!err) {
|
||||
PR_SHELL(shell, "%d\r\n",
|
||||
flash_get_write_block_size(flash_device));
|
||||
}
|
||||
|
||||
do_read(offset, len);
|
||||
return 0;
|
||||
|
||||
bail:
|
||||
printk("Invalid arguments.\n");
|
||||
return -EINVAL;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int flash_shell_erase(int argc, char *argv[])
|
||||
static int cmd_read(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
long unsigned int offset, size;
|
||||
unsigned long int offset, len;
|
||||
int err;
|
||||
|
||||
if (check_flash_device()) {
|
||||
if (!shell_cmd_precheck(shell, argc == 3, NULL, 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CANONICALIZE_ARGS(argc, argv);
|
||||
if (argc != 2 || parse_ul(argv[0], &offset) ||
|
||||
parse_ul(argv[1], &size)) {
|
||||
goto bail;
|
||||
err = check_flash_device(shell);
|
||||
if (err) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
do_erase((off_t)offset, (size_t)size);
|
||||
return 0;
|
||||
if (parse_ul(argv[1], &offset) || parse_ul(argv[2], &len)) {
|
||||
PR_ERROR(shell, "Invalid arguments.\r\n");
|
||||
err = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
bail:
|
||||
printk("Invalid arguments.\n");
|
||||
return -EINVAL;
|
||||
err = do_read(shell, offset, len);
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int flash_shell_write(int argc, char *argv[])
|
||||
static int cmd_erase(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
unsigned long int offset, size;
|
||||
int err;
|
||||
|
||||
if (!shell_cmd_precheck(shell, argc == 3, NULL, 0)) {
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
err = check_flash_device(shell);
|
||||
if (err) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (parse_ul(argv[1], &offset) || parse_ul(argv[2], &size)) {
|
||||
PR_ERROR(shell, "Invalid arguments.\r\n");
|
||||
err = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
err = do_erase(shell, (off_t)offset, (size_t)size);
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int cmd_write(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
unsigned long int i, offset;
|
||||
u8_t buf[ARGC_MAX];
|
||||
long unsigned int i, offset;
|
||||
int err = 0;
|
||||
|
||||
if (check_flash_device()) {
|
||||
if (!shell_cmd_precheck(shell, argc > 2, NULL, 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CANONICALIZE_ARGS(argc, argv);
|
||||
if (argc < 2 || parse_ul(argv[0], &offset)) {
|
||||
goto bail;
|
||||
} else if (argc - 1 > sizeof(buf)) {
|
||||
/* Can only happen if Zephyr limit is increased. */
|
||||
printk("At most %lu bytes can be written.\n",
|
||||
(unsigned long)sizeof(buf));
|
||||
return -EINVAL;
|
||||
err = check_flash_device(shell);
|
||||
if (err) {
|
||||
goto exit;
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
err = parse_ul(argv[1], &offset);
|
||||
if (err) {
|
||||
PR_ERROR(shell, "Invalid argument.\r\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((argc - 2) > ARGC_MAX) {
|
||||
/* Can only happen if Zephyr limit is increased. */
|
||||
PR_ERROR(shell, "At most %lu bytes can be written.\r\n"
|
||||
"In order to write more bytes please increase"
|
||||
" parameter: CONFIG_SHELL_ARGC_MAX.\r\n",
|
||||
(unsigned long)ARGC_MAX);
|
||||
err = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* skip cmd name and offset */
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (parse_u8(argv[i], &buf[i])) {
|
||||
printk("Argument %lu (%s) is not a byte.\n",
|
||||
i + 1, argv[i]);
|
||||
goto bail;
|
||||
PR_ERROR(shell, "Argument %lu (%s) is not a byte.\r\n"
|
||||
"Bytes shall be passed in decimal"
|
||||
" notation.\r\n",
|
||||
i + 1, argv[i]);
|
||||
err = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
do_write(offset, buf, i, true);
|
||||
return 0;
|
||||
err = do_write(shell, offset, buf, i, true);
|
||||
|
||||
bail:
|
||||
printk("Invalid arguments.\n");
|
||||
return -EINVAL;
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FLASH_PAGE_LAYOUT
|
||||
static int flash_shell_page_count(int argc, char *argv[])
|
||||
static int cmd_page_count(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
size_t page_count;
|
||||
int err;
|
||||
|
||||
if (check_flash_device()) {
|
||||
if (!shell_cmd_precheck(shell, argc == 1, NULL, 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CANONICALIZE_ARGS(argc, argv);
|
||||
if (argc) {
|
||||
goto bail;
|
||||
err = check_flash_device(shell);
|
||||
if (!err) {
|
||||
page_count = flash_get_page_count(flash_device);
|
||||
PR_SHELL(shell, "Flash device contains %lu pages.\r\n",
|
||||
(unsigned long int)page_count);
|
||||
}
|
||||
|
||||
page_count = flash_get_page_count(flash_device);
|
||||
printk("Flash device contains %lu pages.\n",
|
||||
(long unsigned int)page_count);
|
||||
return 0;
|
||||
|
||||
bail:
|
||||
printk("Invalid arguments.\n");
|
||||
return -EINVAL;
|
||||
return err;
|
||||
}
|
||||
|
||||
struct page_layout_data {
|
||||
long unsigned int start_page;
|
||||
long unsigned int end_page;
|
||||
unsigned long int start_page;
|
||||
unsigned long int end_page;
|
||||
const struct shell *shell;
|
||||
};
|
||||
|
||||
static bool page_layout_cb(const struct flash_pages_info *info, void *datav)
|
||||
{
|
||||
struct page_layout_data *data = datav;
|
||||
long unsigned int sz;
|
||||
unsigned long int sz;
|
||||
|
||||
if (info->index < data->start_page) {
|
||||
return true;
|
||||
|
@ -361,217 +399,224 @@ static bool page_layout_cb(const struct flash_pages_info *info, void *datav)
|
|||
}
|
||||
|
||||
sz = info->size;
|
||||
printk("\tPage %u: start 0x%08x, length 0x%lx (%lu, %lu KB)\n",
|
||||
info->index, info->start_offset, sz, sz, sz / KB(1));
|
||||
PR_SHELL(data->shell,
|
||||
"\tPage %u: start 0x%08x, length 0x%lx (%lu, %lu KB)\r\n",
|
||||
info->index, info->start_offset, sz, sz, sz / KB(1));
|
||||
return true;
|
||||
}
|
||||
|
||||
static int flash_shell_page_layout(int argc, char *argv[])
|
||||
static int cmd_page_layout(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
long unsigned int start_page, end_page;
|
||||
unsigned long int start_page, end_page;
|
||||
struct page_layout_data data;
|
||||
int err = 0;
|
||||
|
||||
if (check_flash_device()) {
|
||||
return 0;
|
||||
if (!shell_cmd_precheck(shell, argc <= 3, NULL, 0)) {
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
err = check_flash_device(shell);
|
||||
if (err) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
CANONICALIZE_ARGS(argc, argv);
|
||||
switch (argc) {
|
||||
case 0:
|
||||
case 1:
|
||||
start_page = 0;
|
||||
end_page = flash_get_page_count(flash_device) - 1;
|
||||
break;
|
||||
case 1:
|
||||
if (parse_ul(argv[0], &start_page)) {
|
||||
case 2:
|
||||
if (parse_ul(argv[1], &start_page)) {
|
||||
err = -EINVAL;
|
||||
goto bail;
|
||||
}
|
||||
end_page = flash_get_page_count(flash_device) - 1;
|
||||
break;
|
||||
case 2:
|
||||
if (parse_ul(argv[0], &start_page) ||
|
||||
parse_ul(argv[1], &end_page)) {
|
||||
case 3:
|
||||
if (parse_ul(argv[1], &start_page) ||
|
||||
parse_ul(argv[2], &end_page)) {
|
||||
err = -EINVAL;
|
||||
goto bail;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto bail;
|
||||
PR_ERROR(shell, "Invalid argument count.\r\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data.start_page = start_page;
|
||||
data.end_page = end_page;
|
||||
data.shell = shell;
|
||||
flash_page_foreach(flash_device, page_layout_cb, &data);
|
||||
return 0;
|
||||
|
||||
bail:
|
||||
printk("Invalid arguments.\n");
|
||||
return -EINVAL;
|
||||
bail:
|
||||
PR_ERROR(shell, "Invalid arguments.\r\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
static int flash_shell_read_page(int argc, char *argv[])
|
||||
static int cmd_page_read(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
long unsigned int page, offset, len;
|
||||
unsigned long int page, offset, len;
|
||||
struct flash_pages_info info;
|
||||
int ret;
|
||||
|
||||
if (check_flash_device()) {
|
||||
ret = check_flash_device(shell);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!shell_cmd_precheck(shell, (argc == 3) || (argc == 4), NULL, 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CANONICALIZE_ARGS(argc, argv);
|
||||
if (argc != 2 && argc != 3) {
|
||||
goto bail;
|
||||
}
|
||||
if (argc == 2) {
|
||||
if (parse_ul(argv[0], &page) || parse_ul(argv[1], &len)) {
|
||||
if (argc == 3) {
|
||||
if (parse_ul(argv[1], &page) || parse_ul(argv[2], &len)) {
|
||||
ret = -EINVAL;
|
||||
goto bail;
|
||||
}
|
||||
offset = 0;
|
||||
} else if (parse_ul(argv[0], &page) || parse_ul(argv[1], &offset) ||
|
||||
parse_ul(argv[2], &len)) {
|
||||
} else if (parse_ul(argv[1], &page) || parse_ul(argv[2], &offset) ||
|
||||
parse_ul(argv[3], &len)) {
|
||||
ret = -EINVAL;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
ret = flash_get_page_info_by_idx(flash_device, page, &info);
|
||||
if (ret) {
|
||||
printk("flash_page_info_by_idx: %d\n", ret);
|
||||
return 0;
|
||||
PR_ERROR(shell, "Function flash_page_info_by_idx returned an"
|
||||
" error: %d\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
offset += info.start_offset;
|
||||
do_read(offset, len);
|
||||
return 0;
|
||||
ret = do_read(shell, offset, len);
|
||||
return ret;
|
||||
|
||||
bail:
|
||||
printk("Invalid arguments.\n");
|
||||
return -EINVAL;
|
||||
PR_ERROR(shell, "Invalid arguments.\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int flash_shell_erase_page(int argc, char *argv[])
|
||||
static int cmd_page_erase(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
struct flash_pages_info info;
|
||||
long unsigned int i, page, num;
|
||||
unsigned long int i, page, num;
|
||||
int ret;
|
||||
|
||||
if (check_flash_device()) {
|
||||
ret = check_flash_device(shell);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!shell_cmd_precheck(shell, (argc == 2) || (argc == 3), NULL, 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CANONICALIZE_ARGS(argc, argv);
|
||||
if (argc < 1 || parse_ul(argv[0], &page)) {
|
||||
if (parse_ul(argv[1], &page)) {
|
||||
ret = -EINVAL;
|
||||
goto bail;
|
||||
}
|
||||
if (argc == 1) {
|
||||
if (argc == 2) {
|
||||
num = 1;
|
||||
} else if (parse_ul(argv[1], &num)) {
|
||||
} else if (parse_ul(argv[2], &num)) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
ret = flash_get_page_info_by_idx(flash_device, page + i, &info);
|
||||
if (ret) {
|
||||
printk("flash_get_page_info_by_idx: %d\n", ret);
|
||||
return 0;
|
||||
PR_ERROR(shell, "flash_get_page_info_by_idx error:"
|
||||
" %d\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
printk("Erasing page %u (start offset 0x%x, size 0x%x)\n",
|
||||
PR_SHELL(shell, "Erasing page %u (start offset 0x%x,"
|
||||
" size 0x%x)\r\n",
|
||||
info.index, info.start_offset, info.size);
|
||||
ret = do_erase(info.start_offset, info.size);
|
||||
ret = do_erase(shell, info.start_offset, info.size);
|
||||
if (ret) {
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
|
||||
bail:
|
||||
printk("Invalid arguments.\n");
|
||||
return -EINVAL;
|
||||
PR_ERROR(shell, "Invalid arguments.\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int flash_shell_write_page(int argc, char *argv[])
|
||||
static int cmd_page_write(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
struct flash_pages_info info;
|
||||
long unsigned int page, off;
|
||||
unsigned long int page, off;
|
||||
u8_t buf[ARGC_MAX];
|
||||
size_t i;
|
||||
int ret;
|
||||
|
||||
if (check_flash_device()) {
|
||||
ret = check_flash_device(shell);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!shell_cmd_precheck(shell, (argc > 2), NULL, 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CANONICALIZE_ARGS(argc, argv);
|
||||
if (argc < 2 || parse_ul(argv[0], &page) || parse_ul(argv[1], &off)) {
|
||||
if (argc < 2 || parse_ul(argv[1], &page) || parse_ul(argv[2], &off)) {
|
||||
ret = -EINVAL;
|
||||
goto bail;
|
||||
}
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
argc -= 3;
|
||||
argv += 3;
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (parse_u8(argv[i], &buf[i])) {
|
||||
printk("Argument %d (%s) is not a byte.\n",
|
||||
i + 2, argv[i]);
|
||||
PR_ERROR(shell, "Argument %d (%s) is not a byte.\r\n",
|
||||
i + 2, argv[i]);
|
||||
ret = -EINVAL;
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
|
||||
ret = flash_get_page_info_by_idx(flash_device, page, &info);
|
||||
if (ret) {
|
||||
printk("flash_get_page_info_by_idx: %d\n", ret);
|
||||
return 0;
|
||||
PR_ERROR(shell, "flash_get_page_info_by_idx: %d\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
do_write(info.start_offset + off, buf, i, true);
|
||||
return 0;
|
||||
ret = do_write(shell, info.start_offset + off, buf, i, true);
|
||||
return ret;
|
||||
|
||||
bail:
|
||||
printk("Invalid arguments.\n");
|
||||
return -EINVAL;
|
||||
PR_ERROR(shell, "Invalid arguments.\r\n");
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
|
||||
|
||||
static int flash_shell_set_device(int argc, char *argv[])
|
||||
static int cmd_set_dev(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
struct device *dev;
|
||||
const char *name;
|
||||
|
||||
/* Parse arguments. */
|
||||
CANONICALIZE_ARGS(argc, argv);
|
||||
if (argc != 1) {
|
||||
goto bail;
|
||||
if (!shell_cmd_precheck(shell, (argc == 2), NULL, 0)) {
|
||||
return 0;
|
||||
}
|
||||
name = argv[0];
|
||||
|
||||
name = argv[1];
|
||||
|
||||
/* Run command. */
|
||||
dev = device_get_binding(name);
|
||||
if (!dev) {
|
||||
printk("No device named %s.\n", name);
|
||||
return -EINVAL;
|
||||
PR_ERROR(shell, "No device named %s.\r\n", name);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
if (flash_device) {
|
||||
printk("Leaving behind device %s", flash_device->config->name);
|
||||
PR_SHELL(shell, "Leaving behind device %s\r\n",
|
||||
flash_device->config->name);
|
||||
}
|
||||
flash_device = dev;
|
||||
|
||||
return 0;
|
||||
|
||||
bail:
|
||||
printk("Invalid arguments.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct shell_cmd commands[] = {
|
||||
{ "write_block_size", flash_shell_write_block_size,
|
||||
WRITE_BLOCK_SIZE_HELP },
|
||||
{ "read", flash_shell_read, READ_HELP },
|
||||
{ "erase", flash_shell_erase, ERASE_HELP },
|
||||
{ "write", flash_shell_write, WRITE_HELP },
|
||||
#ifdef CONFIG_FLASH_PAGE_LAYOUT
|
||||
{ "page_count", flash_shell_page_count, PAGE_COUNT_HELP },
|
||||
{ "page_layout", flash_shell_page_layout, PAGE_LAYOUT_HELP },
|
||||
{ "read_page", flash_shell_read_page, READ_PAGE_HELP },
|
||||
{ "erase_page", flash_shell_erase_page, ERASE_PAGE_HELP },
|
||||
{ "write_page", flash_shell_write_page, WRITE_PAGE_HELP },
|
||||
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
|
||||
{ "set_device", flash_shell_set_device, SET_DEVICE_HELP },
|
||||
{ NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
void main(void)
|
||||
{
|
||||
flash_device = device_get_binding(FLASH_DEV_NAME);
|
||||
|
@ -584,5 +629,28 @@ void main(void)
|
|||
"before using other commands.\n");
|
||||
}
|
||||
|
||||
SHELL_REGISTER(THIS_MODULE_NAME, commands);
|
||||
(void)shell_init(&uart_shell, NULL, true, true, LOG_LEVEL_INF);
|
||||
}
|
||||
|
||||
|
||||
SHELL_CREATE_STATIC_SUBCMD_SET(sub_flash)
|
||||
{
|
||||
/* Alphabetically sorted to ensure correct Tab autocompletion. */
|
||||
SHELL_CMD(erase, NULL, ERASE_HELP, cmd_erase),
|
||||
#ifdef CONFIG_FLASH_PAGE_LAYOUT
|
||||
SHELL_CMD(page_count, NULL, PAGE_COUNT_HELP, cmd_page_count),
|
||||
SHELL_CMD(page_errase, NULL, PAGE_ERASE_HELP, cmd_page_erase),
|
||||
SHELL_CMD(page_layout, NULL, PAGE_LAYOUT_HELP, cmd_page_layout),
|
||||
SHELL_CMD(page_read, NULL, PAGE_READ_HELP, cmd_page_read),
|
||||
SHELL_CMD(page_write, NULL, PAGE_WRITE_HELP, cmd_page_write),
|
||||
#endif
|
||||
SHELL_CMD(read, NULL, READ_HELP, cmd_read),
|
||||
SHELL_CMD(set_device, NULL, SET_DEV_HELP, cmd_set_dev),
|
||||
SHELL_CMD(write, NULL, WRITE_HELP, cmd_write),
|
||||
SHELL_CMD(write_block_size, NULL, WRITE_BLOCK_SIZE_HELP,
|
||||
cmd_write_block_size),
|
||||
SHELL_SUBCMD_SET_END /* Array terminated. */
|
||||
};
|
||||
|
||||
SHELL_CMD_REGISTER(flash, &sub_flash, "Flash realated commands.", cmd_flash);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue