mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-24 22:13:52 +01:00
sys/shell/cmds: move mtd command from test to reusable shell commands
This commit is contained in:
parent
8f961476b7
commit
4f8ea2c77e
@ -435,6 +435,7 @@ PSEUDOMODULES += shell_cmd_iw
|
||||
PSEUDOMODULES += shell_cmd_lwip_netif
|
||||
PSEUDOMODULES += shell_cmd_mci
|
||||
PSEUDOMODULES += shell_cmd_md5sum
|
||||
PSEUDOMODULES += shell_cmd_mtd
|
||||
PSEUDOMODULES += shell_cmd_nanocoap_vfs
|
||||
PSEUDOMODULES += shell_cmd_netstats_neighbor
|
||||
PSEUDOMODULES += shell_cmd_nice
|
||||
|
||||
@ -212,6 +212,11 @@ endif
|
||||
ifneq (,$(filter shell_cmd_md5sum,$(USEMODULE)))
|
||||
USEMODULE += shell_cmd_vfs
|
||||
endif
|
||||
ifneq (,$(filter shell_cmd_mtd,$(USEMODULE)))
|
||||
USEMODULE += fmt
|
||||
USEMODULE += mtd
|
||||
USEMODULE += od
|
||||
endif
|
||||
ifneq (,$(filter shell_cmd_nanocoap_vfs,$(USEMODULE)))
|
||||
USEMODULE += nanocoap_vfs
|
||||
USEMODULE += vfs_util
|
||||
|
||||
430
sys/shell/cmds/mtd.c
Normal file
430
sys/shell/cmds/mtd.c
Normal file
@ -0,0 +1,430 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 ML!PA Consulting GmbH
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_shell_commands
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Command to low-level access Memory Technology Devices (MTD)
|
||||
*
|
||||
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
||||
* @author Fabian Hüßler <fabian.huessler@ml-pa.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "errno.h"
|
||||
#include "fmt.h"
|
||||
#include "macros/units.h"
|
||||
#include "mtd.h"
|
||||
#include "od.h"
|
||||
#include "shell.h"
|
||||
|
||||
static uint64_t _get_size(mtd_dev_t *dev)
|
||||
{
|
||||
return (uint64_t)dev->sector_count
|
||||
* dev->pages_per_sector
|
||||
* dev->page_size;
|
||||
}
|
||||
|
||||
static int _print_read_usage(const char *progname)
|
||||
{
|
||||
printf("usage: %s <addr> <len>\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cmd_read(mtd_dev_t *dev, int argc, char **argv)
|
||||
{
|
||||
uint32_t addr, len;
|
||||
|
||||
assert(strcmp(*argv, "read") == 0);
|
||||
if (argc < 3) {
|
||||
return _print_read_usage(argv[0]);
|
||||
}
|
||||
|
||||
addr = atoi(argv[1]);
|
||||
len = atoi(argv[2]);
|
||||
|
||||
void *buffer = malloc(len);
|
||||
if (buffer == NULL) {
|
||||
puts("out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* don't print random data if read fails */
|
||||
memset(buffer, 0x3F, len);
|
||||
|
||||
int res = mtd_read(dev, buffer, addr, len);
|
||||
|
||||
if (res) {
|
||||
printf("error: %i\n", res);
|
||||
}
|
||||
else {
|
||||
od_hex_dump_ext(buffer, len, 0, addr);
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _print_read_page_usage(const char *progname)
|
||||
{
|
||||
printf("usage: %s <page> <offset> <len>\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cmd_read_page(mtd_dev_t *dev, int argc, char **argv)
|
||||
{
|
||||
uint32_t page, offset, len;
|
||||
|
||||
assert(strcmp(*argv, "read_page") == 0);
|
||||
if (argc < 4) {
|
||||
return _print_read_page_usage(argv[0]);
|
||||
}
|
||||
|
||||
page = atoi(argv[1]);
|
||||
offset = atoi(argv[2]);
|
||||
len = atoi(argv[3]);
|
||||
|
||||
void *buffer = malloc(len);
|
||||
if (buffer == NULL) {
|
||||
puts("out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int res = mtd_read_page(dev, buffer, page, offset, len);
|
||||
|
||||
if (res) {
|
||||
printf("error: %i\n", res);
|
||||
}
|
||||
else {
|
||||
od_hex_dump_ext(buffer, len, 0, page * dev->page_size + offset);
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _print_write_usage(const char *progname)
|
||||
{
|
||||
printf("usage: %s <addr> <data>\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cmd_write(mtd_dev_t *dev, int argc, char **argv)
|
||||
{
|
||||
uint32_t addr, len;
|
||||
|
||||
assert(strcmp(*argv, "write") == 0);
|
||||
if (argc < 3) {
|
||||
return _print_write_usage(argv[0]);
|
||||
}
|
||||
|
||||
addr = atoi(argv[1]);
|
||||
len = strlen(argv[2]);
|
||||
|
||||
int res = mtd_write(dev, argv[2], addr, len);
|
||||
|
||||
if (res) {
|
||||
printf("error: %i\n", res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _print_write_page_raw_usage(const char *progname)
|
||||
{
|
||||
printf("usage: %s <page> <offset> <data>\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cmd_write_page_raw(mtd_dev_t *dev, int argc, char **argv)
|
||||
{
|
||||
uint32_t page, offset, len;
|
||||
|
||||
assert(strcmp(*argv, "write_page_raw") == 0);
|
||||
if (argc < 4) {
|
||||
return _print_write_page_raw_usage(argv[0]);
|
||||
}
|
||||
|
||||
page = atoi(argv[1]);
|
||||
offset = atoi(argv[2]);
|
||||
len = strlen(argv[3]);
|
||||
|
||||
int res = mtd_write_page_raw(dev, argv[3], page, offset, len);
|
||||
|
||||
if (res) {
|
||||
printf("error: %i\n", res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _print_write_page_usage(const char *progname)
|
||||
{
|
||||
printf("usage: %s <page> <offset> <data>\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cmd_write_page(mtd_dev_t *dev, int argc, char **argv)
|
||||
{
|
||||
#if IS_USED(MODULE_MTD_WRITE_PAGE)
|
||||
uint32_t page, offset, len;
|
||||
|
||||
assert(strcmp(*argv, "write_page") == 0);
|
||||
if (argc < 4) {
|
||||
return _print_write_page_usage(argv[0]);
|
||||
}
|
||||
|
||||
page = atoi(argv[1]);
|
||||
offset = atoi(argv[2]);
|
||||
len = strlen(argv[3]);
|
||||
|
||||
int res = mtd_write_page(dev, argv[3], page, offset, len);
|
||||
|
||||
if (res) {
|
||||
printf("error: %i\n", res);
|
||||
}
|
||||
|
||||
return res;
|
||||
#else
|
||||
(void)dev;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
printf("error: write_page not supported, missing module mtd_write_page\n");
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int _print_erase_usage(const char *progname)
|
||||
{
|
||||
printf("usage: %s <addr> <len>\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cmd_erase(mtd_dev_t *dev, int argc, char **argv)
|
||||
{
|
||||
uint32_t addr;
|
||||
uint32_t len;
|
||||
|
||||
assert(strcmp(*argv, "erase") == 0);
|
||||
if (argc < 3) {
|
||||
return _print_erase_usage(argv[0]);
|
||||
}
|
||||
|
||||
addr = atoi(argv[1]);
|
||||
len = atoi(argv[2]);
|
||||
|
||||
int res = mtd_erase(dev, addr, len);
|
||||
|
||||
if (res) {
|
||||
printf("error: %i\n", res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _print_erase_sector_usage(const char *progname)
|
||||
{
|
||||
printf("usage: %s <sector> [count]\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cmd_erase_sector(mtd_dev_t *dev, int argc, char **argv)
|
||||
{
|
||||
uint32_t sector, count = 1;
|
||||
|
||||
assert(strcmp(*argv, "erase_sector") == 0);
|
||||
if (argc < 2) {
|
||||
return _print_erase_sector_usage(argv[0]);
|
||||
}
|
||||
|
||||
sector = atoi(argv[1]);
|
||||
if (argc > 2) {
|
||||
count = atoi(argv[2]);
|
||||
}
|
||||
|
||||
int res = mtd_erase_sector(dev, sector, count);
|
||||
|
||||
if (res) {
|
||||
printf("error: %i\n", res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void _print_size(uint64_t size)
|
||||
{
|
||||
unsigned long len;
|
||||
const char *unit;
|
||||
|
||||
if (size == 0) {
|
||||
len = 0;
|
||||
unit = "byte";
|
||||
}
|
||||
else if ((size & (GiB(1) - 1)) == 0) {
|
||||
len = size / GiB(1);
|
||||
unit = "GiB";
|
||||
}
|
||||
else if ((size & (MiB(1) - 1)) == 0) {
|
||||
len = size / MiB(1);
|
||||
unit = "MiB";
|
||||
}
|
||||
else if ((size & (KiB(1) - 1)) == 0) {
|
||||
len = size / KiB(1);
|
||||
unit = "kiB";
|
||||
}
|
||||
else {
|
||||
len = size;
|
||||
unit = "byte";
|
||||
}
|
||||
|
||||
printf("%lu %s", len, unit);
|
||||
}
|
||||
|
||||
static void _print_info(mtd_dev_t *dev)
|
||||
{
|
||||
assert(dev);
|
||||
printf("sectors: %"PRIu32"\n", dev->sector_count);
|
||||
printf("pages per sector: %"PRIu32"\n", dev->pages_per_sector);
|
||||
printf("page size: %"PRIu32"\n", dev->page_size);
|
||||
printf("total: ");
|
||||
_print_size(_get_size(dev));
|
||||
puts("");
|
||||
}
|
||||
|
||||
static int cmd_info(mtd_dev_t *dev, int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
assert(strcmp(*argv, "info") == 0);
|
||||
|
||||
if (dev) {
|
||||
_print_info(dev);
|
||||
}
|
||||
else {
|
||||
printf("mtd devices: %u\n", (unsigned)MTD_NUMOF);
|
||||
for (unsigned i = 0; i < MTD_NUMOF; ++i) {
|
||||
printf(" -=[ MTD_%d ]=-\n", i);
|
||||
_print_info(mtd_dev_get(i));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _print_power_usage(const char *progname)
|
||||
{
|
||||
printf("usage: %s <on|off>\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cmd_power(mtd_dev_t *dev, int argc, char **argv)
|
||||
{
|
||||
enum mtd_power_state state;
|
||||
|
||||
assert(strcmp(*argv, "power") == 0);
|
||||
if (argc < 2) {
|
||||
return _print_power_usage(argv[0]);
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "off") == 0) {
|
||||
state = MTD_POWER_DOWN;
|
||||
}
|
||||
else if (strcmp(argv[1], "on") == 0) {
|
||||
state = MTD_POWER_UP;
|
||||
}
|
||||
else {
|
||||
return _print_power_usage(argv[0]);
|
||||
}
|
||||
|
||||
mtd_power(dev, state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _cmd_mtd(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
printf("usage: %s [dev] <command> [args]\n", argv[0]);
|
||||
printf("commands:\n"
|
||||
" read: Read a region of memory on the MTD\n"
|
||||
" read_page: Read a region of memory on the MTD (pagewise addressing)\n"
|
||||
" write: Write a region of memory on the MTD\n"
|
||||
" write_page_raw: Write a region of memory on the MTD (pagewise addressing)\n"
|
||||
" write_page: Write a region of memory on the MTD (pagewise addressing, read-modify-write)\n"
|
||||
" erase: Erase a region of memory on the MTD\n"
|
||||
" erase_sector: Erase a sector of memory on the MTD\n"
|
||||
" info: Print properties of the MTD device\n"
|
||||
" power: Turn the MTD device on/off\n"
|
||||
);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (argc == 2) {
|
||||
if (!strcmp(argv[1], "info")) {
|
||||
argc -= 1;
|
||||
argv += 1;
|
||||
return cmd_info(NULL, argc, argv);
|
||||
}
|
||||
printf("unknown command: %s\n", argv[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned idx = atoi(argv[1]);
|
||||
if (idx > MTD_NUMOF) {
|
||||
printf("%s: invalid device: %s\n", argv[0], argv[1]);
|
||||
return -1;
|
||||
}
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
|
||||
mtd_dev_t *dev = mtd_dev_get(idx);
|
||||
if (dev == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[0], "read")) {
|
||||
return cmd_read(dev, argc, argv);
|
||||
}
|
||||
else if (!strcmp(argv[0], "read_page")) {
|
||||
return cmd_read_page(dev, argc, argv);
|
||||
}
|
||||
else if (!strcmp(argv[0], "write")) {
|
||||
return cmd_write(dev, argc, argv);
|
||||
}
|
||||
else if (!strcmp(argv[0], "write_page_raw")) {
|
||||
return cmd_write_page_raw(dev, argc, argv);
|
||||
}
|
||||
else if (!strcmp(argv[0], "write_page")) {
|
||||
return cmd_write_page(dev, argc, argv);
|
||||
}
|
||||
else if (!strcmp(argv[0], "erase")) {
|
||||
return cmd_erase(dev, argc, argv);
|
||||
}
|
||||
else if (!strcmp(argv[0], "erase_sector")) {
|
||||
return cmd_erase_sector(dev, argc, argv);
|
||||
}
|
||||
else if (!strcmp(argv[0], "info")) {
|
||||
return cmd_info(dev, argc, argv);
|
||||
}
|
||||
else if (!strcmp(argv[0], "power")) {
|
||||
return cmd_power(dev, argc, argv);
|
||||
}
|
||||
printf("unknown command: %s\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SHELL_COMMAND(mtd, "Read and write raw data to an MTD", _cmd_mtd);
|
||||
@ -2,9 +2,8 @@ include ../Makefile.drivers_common
|
||||
|
||||
USEMODULE += shell
|
||||
USEMODULE += shell_cmds_default
|
||||
USEMODULE += shell_cmd_mtd
|
||||
|
||||
USEMODULE += od
|
||||
USEMODULE += mtd
|
||||
USEMODULE += mtd_write_page
|
||||
|
||||
# enable true erase if MTD is an SD card
|
||||
|
||||
@ -24,11 +24,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "od.h"
|
||||
#include "board.h"
|
||||
#include "mtd.h"
|
||||
#include "shell.h"
|
||||
#include "board.h"
|
||||
#include "macros/units.h"
|
||||
#include "test_utils/expect.h"
|
||||
|
||||
static mtd_dev_t *_get_dev(int argc, char **argv)
|
||||
@ -48,285 +46,6 @@ static mtd_dev_t *_get_dev(int argc, char **argv)
|
||||
return mtd_dev_get(idx);
|
||||
}
|
||||
|
||||
static uint64_t _get_size(mtd_dev_t *dev)
|
||||
{
|
||||
return (uint64_t)dev->sector_count
|
||||
* dev->pages_per_sector
|
||||
* dev->page_size;
|
||||
}
|
||||
|
||||
static int cmd_read(int argc, char **argv)
|
||||
{
|
||||
mtd_dev_t *dev = _get_dev(argc, argv);
|
||||
uint32_t addr, len;
|
||||
|
||||
if (argc < 4 || dev == NULL) {
|
||||
printf("usage: %s <dev> <addr> <len>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
addr = atoi(argv[2]);
|
||||
len = atoi(argv[3]);
|
||||
|
||||
void *buffer = malloc(len);
|
||||
if (buffer == NULL) {
|
||||
puts("out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* don't print random data if read fails */
|
||||
memset(buffer, 0x3F, len);
|
||||
|
||||
int res = mtd_read(dev, buffer, addr, len);
|
||||
|
||||
if (res) {
|
||||
printf("error: %i\n", res);
|
||||
} else {
|
||||
od_hex_dump_ext(buffer, len, 0, addr);
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int cmd_read_page(int argc, char **argv)
|
||||
{
|
||||
mtd_dev_t *dev = _get_dev(argc, argv);
|
||||
uint32_t page, offset, len;
|
||||
|
||||
if (argc < 5 || dev == NULL) {
|
||||
printf("usage: %s <dev> <page> <offset> <len>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
page = atoi(argv[2]);
|
||||
offset = atoi(argv[3]);
|
||||
len = atoi(argv[4]);
|
||||
|
||||
void *buffer = malloc(len);
|
||||
if (buffer == NULL) {
|
||||
puts("out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int res = mtd_read_page(dev, buffer, page, offset, len);
|
||||
|
||||
if (res) {
|
||||
printf("error: %i\n", res);
|
||||
} else {
|
||||
od_hex_dump_ext(buffer, len, 0, page * dev->page_size + offset);
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int cmd_write(int argc, char **argv)
|
||||
{
|
||||
mtd_dev_t *dev = _get_dev(argc, argv);
|
||||
uint32_t addr, len;
|
||||
|
||||
if (argc < 4 || dev == NULL) {
|
||||
printf("usage: %s <dev> <addr> <data>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
addr = atoi(argv[2]);
|
||||
len = strlen(argv[3]);
|
||||
|
||||
int res = mtd_write(dev, argv[3], addr, len);
|
||||
|
||||
if (res) {
|
||||
printf("error: %i\n", res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int cmd_write_page_raw(int argc, char **argv)
|
||||
{
|
||||
mtd_dev_t *dev = _get_dev(argc, argv);
|
||||
uint32_t page, offset, len;
|
||||
|
||||
if (argc < 5 || dev == NULL) {
|
||||
printf("usage: %s <dev> <page> <offset> <data>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
page = atoi(argv[2]);
|
||||
offset = atoi(argv[3]);
|
||||
len = strlen(argv[4]);
|
||||
|
||||
int res = mtd_write_page_raw(dev, argv[4], page, offset, len);
|
||||
|
||||
if (res) {
|
||||
printf("error: %i\n", res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int cmd_write_page(int argc, char **argv)
|
||||
{
|
||||
mtd_dev_t *dev = _get_dev(argc, argv);
|
||||
uint32_t page, offset, len;
|
||||
|
||||
if (argc < 5 || dev == NULL) {
|
||||
printf("usage: %s <dev> <page> <offset> <data>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
page = atoi(argv[2]);
|
||||
offset = atoi(argv[3]);
|
||||
len = strlen(argv[4]);
|
||||
|
||||
int res = mtd_write_page(dev, argv[4], page, offset, len);
|
||||
|
||||
if (res) {
|
||||
printf("error: %i\n", res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int cmd_erase(int argc, char **argv)
|
||||
{
|
||||
mtd_dev_t *dev = _get_dev(argc, argv);
|
||||
uint32_t addr;
|
||||
uint32_t len;
|
||||
|
||||
if (argc < 4 || dev == NULL) {
|
||||
printf("usage: %s <dev> <addr> <len>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
addr = atoi(argv[2]);
|
||||
len = atoi(argv[3]);
|
||||
|
||||
int res = mtd_erase(dev, addr, len);
|
||||
|
||||
if (res) {
|
||||
printf("error: %i\n", res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int cmd_erase_sector(int argc, char **argv)
|
||||
{
|
||||
mtd_dev_t *dev = _get_dev(argc, argv);
|
||||
uint32_t sector, count = 1;
|
||||
|
||||
if (argc < 3 || dev == NULL) {
|
||||
printf("usage: %s <dev> <sector> [count]\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sector = atoi(argv[2]);
|
||||
|
||||
if (argc > 3) {
|
||||
count = atoi(argv[3]);
|
||||
}
|
||||
|
||||
int res = mtd_erase_sector(dev, sector, count);
|
||||
|
||||
if (res) {
|
||||
printf("error: %i\n", res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void _print_size(uint64_t size)
|
||||
{
|
||||
unsigned long len;
|
||||
const char *unit;
|
||||
|
||||
if (size == 0) {
|
||||
len = 0;
|
||||
unit = "byte";
|
||||
} else if ((size & (GiB(1) - 1)) == 0) {
|
||||
len = size / GiB(1);
|
||||
unit = "GiB";
|
||||
}
|
||||
else if ((size & (MiB(1) - 1)) == 0) {
|
||||
len = size / MiB(1);
|
||||
unit = "MiB";
|
||||
}
|
||||
else if ((size & (KiB(1) - 1)) == 0) {
|
||||
len = size / KiB(1);
|
||||
unit = "kiB";
|
||||
} else {
|
||||
len = size;
|
||||
unit = "byte";
|
||||
}
|
||||
|
||||
printf("%lu %s", len, unit);
|
||||
}
|
||||
|
||||
static void _print_info(mtd_dev_t *dev)
|
||||
{
|
||||
printf("sectors: %"PRIu32"\n", dev->sector_count);
|
||||
printf("pages per sector: %"PRIu32"\n", dev->pages_per_sector);
|
||||
printf("page size: %"PRIu32"\n", dev->page_size);
|
||||
printf("total: ");
|
||||
_print_size(_get_size(dev));
|
||||
puts("");
|
||||
}
|
||||
|
||||
static int cmd_info(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
printf("mtd devices: %d\n", (unsigned)MTD_NUMOF);
|
||||
|
||||
for (unsigned i = 0; i < MTD_NUMOF; ++i) {
|
||||
printf(" -=[ MTD_%d ]=-\n", i);
|
||||
_print_info(mtd_dev_get(i));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
mtd_dev_t *dev = _get_dev(argc, argv);
|
||||
|
||||
if (dev == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
_print_info(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int _print_power_usage(const char *progname)
|
||||
{
|
||||
printf("usage: %s <dev> <on|off>\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cmd_power(int argc, char **argv)
|
||||
{
|
||||
mtd_dev_t *dev = _get_dev(argc, argv);
|
||||
enum mtd_power_state state;
|
||||
|
||||
if (argc < 3 || dev == NULL) {
|
||||
return _print_power_usage(argv[0]);
|
||||
}
|
||||
|
||||
if (strcmp(argv[2], "off") == 0) {
|
||||
state = MTD_POWER_DOWN;
|
||||
} else if (strcmp(argv[2], "on") == 0) {
|
||||
state = MTD_POWER_UP;
|
||||
} else {
|
||||
return _print_power_usage(argv[0]);
|
||||
}
|
||||
|
||||
mtd_power(dev, state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool mem_is_all_set(const uint8_t *buf, uint8_t c, size_t n)
|
||||
{
|
||||
for (const uint8_t *end = buf + n; buf != end; ++buf) {
|
||||
@ -424,23 +143,7 @@ static int cmd_test(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const shell_command_t shell_commands[] = {
|
||||
{ "info", "Print properties of the MTD device", cmd_info },
|
||||
{ "power", "Turn the MTD device on/off", cmd_power },
|
||||
{ "read", "Read a region of memory on the MTD device", cmd_read },
|
||||
{ "read_page", "Read a region of memory on the MTD device (pagewise addressing)", cmd_read_page },
|
||||
{ "write", "Write a region of memory on the MTD device", cmd_write },
|
||||
{ "write_page_raw",
|
||||
"Write a region of memory on the MTD device (pagewise addressing)",
|
||||
cmd_write_page_raw },
|
||||
{ "write_page",
|
||||
"Write a region of memory on the MTD device (pagewise addressing, read-modify-write)",
|
||||
cmd_write_page },
|
||||
{ "erase", "Erase a region of memory on the MTD device", cmd_erase },
|
||||
{ "erase_sector", "Erase a sector of memory on the MTD device", cmd_erase_sector },
|
||||
{ "test", "Erase & write test data to the last two sectors", cmd_test },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
SHELL_COMMAND(test, "Erase & write test data to the last two sectors", cmd_test);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
@ -460,15 +163,12 @@ int main(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("OK (");
|
||||
_print_size(_get_size(dev));
|
||||
puts(")");
|
||||
mtd_power(dev, MTD_POWER_UP);
|
||||
}
|
||||
|
||||
/* run the shell */
|
||||
char line_buf[SHELL_DEFAULT_BUFSIZE];
|
||||
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
|
||||
shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ from testrunner import run
|
||||
|
||||
|
||||
def testfunc(child):
|
||||
child.sendline("info")
|
||||
child.sendline("mtd info")
|
||||
child.expect(r'mtd devices: (\d+)')
|
||||
mtd_numof = int(child.match.group(1))
|
||||
for dev in range(mtd_numof):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user