summaryrefslogtreecommitdiffstats
path: root/cpukit/libmisc/shell
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cpukit/libmisc/shell/login_check.c2
-rw-r--r--cpukit/libmisc/shell/login_prompt.c2
-rw-r--r--cpukit/libmisc/shell/main_blkstats.c2
-rw-r--r--cpukit/libmisc/shell/main_chmod.c2
-rw-r--r--cpukit/libmisc/shell/main_cmdchmod.c2
-rw-r--r--cpukit/libmisc/shell/main_cmdchown.c2
-rw-r--r--cpukit/libmisc/shell/main_cmdls.c2
-rw-r--r--cpukit/libmisc/shell/main_cpuinfo.c2
-rw-r--r--cpukit/libmisc/shell/main_edit.c21
-rw-r--r--cpukit/libmisc/shell/main_flashdev.c584
-rw-r--r--cpukit/libmisc/shell/main_i2cdetect.c2
-rw-r--r--cpukit/libmisc/shell/main_i2cget.c2
-rw-r--r--cpukit/libmisc/shell/main_i2cset.c2
-rw-r--r--cpukit/libmisc/shell/main_lsof.c2
-rw-r--r--cpukit/libmisc/shell/main_mmove.c2
-rw-r--r--cpukit/libmisc/shell/main_pci.c2
-rw-r--r--cpukit/libmisc/shell/main_profreport.c2
-rw-r--r--cpukit/libmisc/shell/main_rtc.c2
-rw-r--r--cpukit/libmisc/shell/main_spi.c2
-rw-r--r--cpukit/libmisc/shell/shell-wait-for-input.c2
-rw-r--r--cpukit/libmisc/shell/shell.c150
21 files changed, 735 insertions, 56 deletions
diff --git a/cpukit/libmisc/shell/login_check.c b/cpukit/libmisc/shell/login_check.c
index 5ba2332070..d9bce28a7d 100644
--- a/cpukit/libmisc/shell/login_check.c
+++ b/cpukit/libmisc/shell/login_check.c
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2009-2014 embedded brains GmbH and others.
+ * Copyright (C) 2009, 2014 embedded brains GmbH & Co. KG
*
* Based on work from Chris Johns and Fernando Ruiz.
*
diff --git a/cpukit/libmisc/shell/login_prompt.c b/cpukit/libmisc/shell/login_prompt.c
index 6eda753607..149966be63 100644
--- a/cpukit/libmisc/shell/login_prompt.c
+++ b/cpukit/libmisc/shell/login_prompt.c
@@ -48,7 +48,7 @@
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*
- * Copyright (c) 2009 embedded brains GmbH and others.
+ * Copyright (c) 2009 embedded brains GmbH & Co. KG
*
* Based on work from Chris Johns, Fernando Ruiz and Till Straumann.
*
diff --git a/cpukit/libmisc/shell/main_blkstats.c b/cpukit/libmisc/shell/main_blkstats.c
index 294dd1b7d9..3acc652d87 100644
--- a/cpukit/libmisc/shell/main_blkstats.c
+++ b/cpukit/libmisc/shell/main_blkstats.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2012 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
diff --git a/cpukit/libmisc/shell/main_chmod.c b/cpukit/libmisc/shell/main_chmod.c
index 1f646d92d4..9a42cbd940 100644
--- a/cpukit/libmisc/shell/main_chmod.c
+++ b/cpukit/libmisc/shell/main_chmod.c
@@ -56,7 +56,7 @@ static int rtems_shell_main_chmod(
* Now change the files modes
*/
for (n=2 ; n < argc ; n++) {
- sc = chmod(argv[n++], mode);
+ sc = chmod(argv[n], mode);
_Assert_Unused_variable_unequal(sc, -1);
}
diff --git a/cpukit/libmisc/shell/main_cmdchmod.c b/cpukit/libmisc/shell/main_cmdchmod.c
index dee4d899a8..b6ec03bd5d 100644
--- a/cpukit/libmisc/shell/main_cmdchmod.c
+++ b/cpukit/libmisc/shell/main_cmdchmod.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2014 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
diff --git a/cpukit/libmisc/shell/main_cmdchown.c b/cpukit/libmisc/shell/main_cmdchown.c
index 6ceab0f5b1..ba44d70ebb 100644
--- a/cpukit/libmisc/shell/main_cmdchown.c
+++ b/cpukit/libmisc/shell/main_cmdchown.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2014 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
diff --git a/cpukit/libmisc/shell/main_cmdls.c b/cpukit/libmisc/shell/main_cmdls.c
index ab11c83892..529e070e8b 100644
--- a/cpukit/libmisc/shell/main_cmdls.c
+++ b/cpukit/libmisc/shell/main_cmdls.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2014 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
diff --git a/cpukit/libmisc/shell/main_cpuinfo.c b/cpukit/libmisc/shell/main_cpuinfo.c
index 846f5efd4a..70179dcee8 100644
--- a/cpukit/libmisc/shell/main_cpuinfo.c
+++ b/cpukit/libmisc/shell/main_cpuinfo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2016 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
diff --git a/cpukit/libmisc/shell/main_edit.c b/cpukit/libmisc/shell/main_edit.c
index 191eefa19d..8317452b7b 100644
--- a/cpukit/libmisc/shell/main_edit.c
+++ b/cpukit/libmisc/shell/main_edit.c
@@ -412,6 +412,9 @@ static void move_gap(struct editor *ed, int pos, int minsize) {
if (gapsize + MINEXTEND > minsize) minsize = gapsize + MINEXTEND;
newsize = (ed->end - ed->start) - gapsize + minsize;
start = (unsigned char *) malloc(newsize); // TODO check for out of memory
+ if (start == NULL) {
+ return;
+ }
gap = start + pos;
rest = gap + minsize;
end = start + newsize;
@@ -1710,7 +1713,6 @@ static void copy_selection(struct editor *ed) {
ed->env->clipboard = (unsigned char *) realloc(ed->env->clipboard, ed->env->clipsize);
if (!ed->env->clipboard) return;
copy(ed, ed->env->clipboard, selstart, ed->env->clipsize);
- select_toggle(ed);
}
static void cut_selection(struct editor *ed) {
@@ -1809,14 +1811,14 @@ static void save_editor(struct editor *ed) {
ed->refresh = 1;
}
-static void close_editor(struct editor *ed) {
+static struct editor* close_editor(struct editor *ed) {
struct env *env = ed->env;
if (ed->dirty) {
display_message(ed, "Close %s without saving changes (y/n)? ", ed->filename);
if (!ask()) {
ed->refresh = 1;
- return;
+ return ed;
}
}
@@ -1828,6 +1830,7 @@ static void close_editor(struct editor *ed) {
new_file(ed, "");
}
ed->refresh = 1;
+ return ed;
}
static void pipe_command(struct editor *ed) {
@@ -2128,7 +2131,7 @@ static void edit(struct editor *ed) {
case ctrl('e'): select_toggle(ed); break;
case ctrl('a'): select_all(ed); break;
- case ctrl('c'): copy_selection(ed); break;
+ case ctrl('c'): copy_selection(ed);select_toggle(ed); break;
case ctrl('f'): find_text(ed, 0); break;
case ctrl('l'): goto_line(ed); break;
case ctrl('g'): find_text(ed, 1); break;
@@ -2151,15 +2154,7 @@ static void edit(struct editor *ed) {
case ctrl('s'): save_editor(ed); break;
case ctrl('p'): pipe_command(ed); break;
#endif
-#if defined(__rtems__)
- /*
- * Coverity spotted this as using ed after free() so changing
- * the order of the statements.
- */
- case ctrl('w'): ed = ed->env->current; close_editor(ed); break;
-#else
- case ctrl('w'): close_editor(ed); ed = ed->env->current; break;
-#endif
+ case ctrl('w'): ed = close_editor(ed); break;
}
}
}
diff --git a/cpukit/libmisc/shell/main_flashdev.c b/cpukit/libmisc/shell/main_flashdev.c
new file mode 100644
index 0000000000..ca2454b33c
--- /dev/null
+++ b/cpukit/libmisc/shell/main_flashdev.c
@@ -0,0 +1,584 @@
+/*
+ * Copyright (C) 2023 Aaron Nyholm
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <errno.h>
+#include <rtems/shell.h>
+
+#include <dev/flash/flashdev.h>
+
+static int flashdev_shell_read(char *dev_path, int argc, char *argv[]);
+static int flashdev_shell_write(char *dev_path, int argc, char *argv[]);
+static int flashdev_shell_erase(char *dev_path, int argc, char *argv[]);
+static int flashdev_shell_type(char *dev_path);
+static int flashdev_shell_jedecid(char *dev_path);
+static int flashdev_shell_page_off(char *dev_path, int argc, char *argv[]);
+static int flashdev_shell_page_idx(char *dev_path, int argc, char *argv[]);
+static int flashdev_shell_pg_count(char *dev_path);
+static int flashdev_shell_wb_size(char *dev_path);
+
+static int flashdev_shell_ioctl_value(
+ char *dev_path,
+ int ioctl_call,
+ void *ret
+);
+
+static int flashdev_shell_page(
+ char *dev_path,
+ int argc,
+ char *argv[],
+ int ioctl_call
+);
+
+static const char rtems_flashdev_shell_usage [] =
+ "simple flash read / write / erase\n"
+ "\n"
+ "flashdev <FLASH_DEV_PATH> [OPTION]\n"
+ " -r <address> <bytes> Read at address for bytes\n"
+ " -w <address> <file> Write file to address\n"
+ " -e <address> <bytes> Erase at address for bytes\n"
+ " -t Print the flash type\n"
+ " -d Print the JEDEC ID of flash device\n"
+ " -o <address> Print the page information of page at address\n"
+ " -i <index> Print the page information of page at index\n"
+ " -p Print the number of pages\n"
+ " -b Print the write block size\n"
+ " -h Print this help\n";
+
+
+static int rtems_flashdev_shell_main( int argc, char *argv[] ) {
+
+ char *dev_path = NULL;
+ int i;
+
+ for (i = 1; i < argc; ++i) {
+ if (argv[i][0] == '-') {
+ /*
+ * Check that a path to flashdev has been provided before running
+ * command.
+ */
+ if (dev_path == NULL) {
+ printf("Please input FLASH_DEV_PATH before instruction\n");
+ return 1;
+ }
+ /* Run command */
+ switch (argv[i][1]) {
+ case ('r'):
+ /* Read */
+ return flashdev_shell_read(dev_path, argc, &argv[i]);
+ case ('w'):
+ /* Write */
+ return flashdev_shell_write(dev_path, argc, &argv[i]);
+ case ('e'):
+ /* Erase */
+ return flashdev_shell_erase(dev_path, argc, &argv[i]);
+ case ('t'):
+ /* Flash Type */
+ return flashdev_shell_type(dev_path);
+ case ('d'):
+ /* JEDEC Id */
+ return flashdev_shell_jedecid(dev_path);
+ case ('o'):
+ /* Page info by offset */
+ return flashdev_shell_page_off(dev_path, argc, &argv[i]);
+ case ('i'):
+ /* Page info by index */
+ return flashdev_shell_page_idx(dev_path, argc, &argv[i]);
+ case ('p'):
+ /* Page count */
+ return flashdev_shell_pg_count(dev_path);
+ case ('b'):
+ /* Write block size */
+ return flashdev_shell_wb_size(dev_path);
+ case ('h'):
+ default:
+ /* Help */
+ printf(rtems_flashdev_shell_usage);
+ break;
+ }
+ } else if (dev_path == NULL) {
+ dev_path = argv[i];
+ } else {
+ printf("Invalid argument: %s\n", argv[i]);
+ return 1;
+ }
+ }
+
+ if (argc == 1) {
+ printf(rtems_flashdev_shell_usage);
+ }
+
+ return 0;
+}
+
+int flashdev_shell_read(
+ char *dev_path,
+ int argc,
+ char *argv[]
+)
+{
+ uint32_t address;
+ uint32_t bytes;
+ int fd;
+ int status;
+ void *buffer;
+
+ /* Check arguments */
+ if (argc < 5) {
+ printf("Missing argument\n");
+ return -1;
+ }
+
+ /* Get arguments */
+ errno = 0;
+ address = (uint32_t) strtoul(argv[1], NULL, 0);
+ if (errno != 0) {
+ printf("Could not read address\n");
+ }
+ errno = 0;
+ bytes = (uint32_t) strtoul(argv[2], NULL, 0);
+ if (errno != 0) {
+ printf("Could not read address\n");
+ }
+
+ /* Open flash device */
+ fd = open(dev_path, O_RDONLY);
+ if (fd == -1) {
+ printf("Couldn't open %s\n", dev_path);
+ return -1;
+ }
+
+ /* Move to address */
+ status = lseek(fd, address, SEEK_SET);
+ if (status == -1) {
+ printf("Reading failed\n");
+ close(fd);
+ return -1;
+ }
+
+ /* Create a buffer to read into */
+ buffer = calloc((bytes + bytes%4), 1);
+ if (buffer == NULL) {
+ printf("Failed to allocate read buffer\n");
+ close(fd);
+ return -1;
+ }
+
+ /* Read into buffer */
+ status = read(fd, buffer, bytes);
+ if (status == -1) {
+ printf("Reading failed\n");
+ free(buffer);
+ close(fd);
+ return -1;
+ }
+
+ /* Print buffer out in 32bit blocks */
+ printf("Reading %s at 0x%08x for %d bytes\n", dev_path, address, bytes);
+ for (int i = 0; i < (bytes/4); i++) {
+ printf("%08x ", ((uint32_t*)buffer)[i]);
+ if ((i+1)%4 == 0) {
+ printf("\n");
+ }
+ }
+ printf("\n");
+
+ /* Clean up */
+ free(buffer);
+ close(fd);
+ return 0;
+}
+
+int flashdev_shell_write(
+ char *dev_path,
+ int argc,
+ char *argv[]
+)
+{
+ uint32_t address;
+ int flash;
+ int file;
+ int status;
+ int read_len;
+ off_t length;
+ void *buffer;
+ uint32_t offset;
+ char *file_path;
+
+ /* Check arguments */
+ if (argc < 5) {
+ printf("Missing argument\n");
+ return -1;
+ }
+
+ /* Get arguments */
+ errno = 0;
+ address = (uint32_t) strtoul(argv[1], NULL, 0);
+ if (errno != 0) {
+ printf("Could not read address\n");
+ }
+ errno = 0;
+ file_path = argv[2];
+
+ /* Open flash device and move to write offset */
+ flash = open(dev_path, O_WRONLY);
+ if (flash == -1) {
+ printf("Couldn't open %s\n", dev_path);
+ return -1;
+ }
+ status = lseek(flash, address, SEEK_SET);
+ if (status == -1) {
+ printf("Reading failed\n");
+ close(flash);
+ return -1;
+ }
+
+ /* Open file and get file length */
+ file = open(file_path, O_RDONLY);
+ if (file == -1) {
+ printf("Couldn't open %s\n", file_path);
+ close(flash);
+ return -1;
+ }
+
+ length = lseek(file, 0, SEEK_END);
+ if (length == -1) {
+ close(flash);
+ close(file);
+ printf("Couldn't find length of file\n");
+ return -1;
+ }
+
+ if (lseek(file, 0, SEEK_SET) == -1) {
+ close(flash);
+ close(file);
+ printf("Couldn't find length of file\n");
+ return -1;
+ }
+
+ /* Create buffer */
+ buffer = calloc(1, 0x1000);
+
+ /* Write file to flash device in 0x1000 byte chunks */
+ offset = 0;
+ while (offset != length) {
+
+ read_len = length - offset;
+ if (read_len > 0x1000) {
+ read_len = 0x1000;
+ }
+
+ status = read(file, buffer, read_len);
+ if (status == -1) {
+ free(buffer);
+ close(flash);
+ close(file);
+ printf("Can't read %s\n", file_path);
+ return -1;
+ }
+
+ status = write(flash, buffer, read_len);
+ if (status == -1) {
+ free(buffer);
+ close(flash);
+ close(file);
+ printf("Can't write %s\n", dev_path);
+ return -1;
+ }
+
+ offset = offset + read_len;
+ }
+
+ /* Clean up */
+ close(flash);
+ close(file);
+ free(buffer);
+ return 0;
+}
+
+int flashdev_shell_erase(
+ char *dev_path,
+ int argc,
+ char *argv[]
+)
+{
+ uint32_t address;
+ uint32_t bytes;
+ int fd;
+ int status;
+ rtems_flashdev_region args;
+
+ /* Check arguments */
+ if (argc < 5) {
+ printf("Missing argument\n");
+ return -1;
+ }
+
+ /* Get arguments */
+ errno = 0;
+ address = (uint32_t) strtoul(argv[1], NULL, 0);
+ if (errno != 0) {
+ printf("Could not read address\n");
+ }
+ errno = 0;
+ bytes = (uint32_t) strtoul(argv[2], NULL, 0);
+ if (errno != 0) {
+ printf("Could not read address\n");
+ }
+
+ /* Open flash device */
+ fd = open(dev_path, O_RDWR);
+ if (fd == -1) {
+ printf("Couldn't open %s\n", dev_path);
+ return -1;
+ }
+
+ printf("Erasing at %08x for %x bytes\n", address, bytes);
+
+ /* Erase flash */
+ args.offset = address;
+ args.size = bytes;
+
+ status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_ERASE, &args);
+ if (status == -1) {
+ printf("Erase failed\n");
+ close(fd);
+ return -1;
+ }
+
+ /* Clean up */
+ close(fd);
+
+ return 0;
+}
+
+int flashdev_shell_type( char *dev_path )
+{
+ int type;
+ int status;
+
+ /* Get type */
+ status = flashdev_shell_ioctl_value(
+ dev_path,
+ RTEMS_FLASHDEV_IOCTL_TYPE,
+ &type
+ );
+
+ if (status) {
+ printf("Failed to get flash type\n");
+ return status;
+ }
+
+ /* Print type */
+ switch(type) {
+ case RTEMS_FLASHDEV_NOR:
+ printf("NOR flash\n");
+ break;
+ case RTEMS_FLASHDEV_NAND:
+ printf("NAND flash\n");
+ break;
+ default:
+ printf("Unknown type\n");
+ }
+
+ return 0;
+}
+
+int flashdev_shell_jedecid( char *dev_path ) {
+ uint32_t ret;
+ int status;
+
+ /* Get JEDEC Id */
+ status = flashdev_shell_ioctl_value(
+ dev_path,
+ RTEMS_FLASHDEV_IOCTL_JEDEC_ID,
+ &ret
+ );
+
+ /* Print JEDEC Id */
+ if (status) {
+ printf("Failed to get JEDEC Id\n");
+ return status;
+ } else {
+ printf("JEDEC Id: 0x%x\n", ret);
+ }
+ return 0;
+}
+
+static int flashdev_shell_page_off(
+ char *dev_path,
+ int argc,
+ char *argv[]
+)
+{
+ return flashdev_shell_page(
+ dev_path,
+ argc,
+ argv,
+ RTEMS_FLASHDEV_IOCTL_PAGEINFO_BY_OFFSET
+ );
+}
+
+static int flashdev_shell_page_idx(
+ char *dev_path,
+ int argc,
+ char *argv[]
+)
+{
+ return flashdev_shell_page(
+ dev_path,
+ argc,
+ argv,
+ RTEMS_FLASHDEV_IOCTL_PAGEINFO_BY_INDEX
+ );
+}
+
+static int flashdev_shell_pg_count( char *dev_path )
+{
+ uint32_t ret;
+ int status;
+
+ /* Get Page Count */
+ status = flashdev_shell_ioctl_value(
+ dev_path,
+ RTEMS_FLASHDEV_IOCTL_PAGE_COUNT,
+ &ret
+ );
+
+ /* Print Page Count */
+ if (status) {
+ printf("Failed to get page count\n");
+ return status;
+ } else {
+ printf("Page count: 0x%x\n", ret);
+ }
+ return 0;
+}
+
+static int flashdev_shell_wb_size( char *dev_path )
+{
+ size_t ret;
+ int status;
+
+ /* Get Write Block Size */
+ status = flashdev_shell_ioctl_value(
+ dev_path,
+ RTEMS_FLASHDEV_IOCTL_WRITE_BLOCK_SIZE,
+ &ret
+ );
+
+ /* Print Write Block Size */
+ if (status) {
+ printf("Failed to get write block size\n");
+ return status;
+ } else {
+ printf("Write block size: 0x%zx\n", ret);
+ }
+ return 0;
+}
+
+static int flashdev_shell_ioctl_value(
+ char *dev_path,
+ int ioctl_call,
+ void *ret
+)
+{
+ int fd;
+ int status;
+
+ fd = open(dev_path, O_RDONLY);
+ if (fd == -1) {
+ printf("Couldn't open %s\n", dev_path);
+ return -1;
+ }
+
+ status = ioctl(fd, ioctl_call, ret);
+ if (status == -1) {
+ close(fd);
+ return -1;
+ }
+
+ close(fd);
+ return 0;
+}
+
+static int flashdev_shell_page(
+ char *dev_path,
+ int argc,
+ char *argv[],
+ int ioctl_call
+)
+{
+ rtems_flashdev_ioctl_page_info pg_info;
+ int fd;
+ int status;
+
+ /* Check arguments */
+ if (argc < 4) {
+ printf("Missing argument\n");
+ return -1;
+ }
+
+ /* Get arguments */
+ errno = 0;
+ pg_info.location = (off_t) strtoul(argv[1], NULL, 0);
+ if (errno != 0) {
+ printf("Could not read address\n");
+ }
+
+ /* Open flash device */
+ fd = open(dev_path, O_RDWR);
+ if (fd == -1) {
+ printf("Couldn't open %s\n", dev_path);
+ return -1;
+ }
+
+ status = ioctl(fd, ioctl_call, &pg_info);
+ if (status == -1) {
+ printf("Failed to get page info\n");
+ close(fd);
+ return -1;
+ }
+
+ printf(
+ "Page offset: 0x%jx\nPage length: 0x%zx\n",
+ pg_info.page_info.offset,
+ pg_info.page_info.size
+ );
+
+ /* Clean up */
+ close(fd);
+ return 0;
+}
+
+rtems_shell_cmd_t rtems_shell_FLASHDEV_Command = {
+ .name = "flashdev",
+ .usage = rtems_flashdev_shell_usage,
+ .topic = "misc",
+ .command = rtems_flashdev_shell_main,
+};
diff --git a/cpukit/libmisc/shell/main_i2cdetect.c b/cpukit/libmisc/shell/main_i2cdetect.c
index e953b4eaef..1a863434b7 100644
--- a/cpukit/libmisc/shell/main_i2cdetect.c
+++ b/cpukit/libmisc/shell/main_i2cdetect.c
@@ -1,7 +1,7 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (C) 2020 embedded brains GmbH.
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/cpukit/libmisc/shell/main_i2cget.c b/cpukit/libmisc/shell/main_i2cget.c
index ffa551308b..5726c6ea14 100644
--- a/cpukit/libmisc/shell/main_i2cget.c
+++ b/cpukit/libmisc/shell/main_i2cget.c
@@ -1,7 +1,7 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (C) 2020 embedded brains GmbH.
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/cpukit/libmisc/shell/main_i2cset.c b/cpukit/libmisc/shell/main_i2cset.c
index d9025b3b28..cdc42a57f9 100644
--- a/cpukit/libmisc/shell/main_i2cset.c
+++ b/cpukit/libmisc/shell/main_i2cset.c
@@ -1,7 +1,7 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (C) 2020 embedded brains GmbH.
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/cpukit/libmisc/shell/main_lsof.c b/cpukit/libmisc/shell/main_lsof.c
index efe886e6de..2cc35f96fe 100644
--- a/cpukit/libmisc/shell/main_lsof.c
+++ b/cpukit/libmisc/shell/main_lsof.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014 embedded brains GmbH. All rights reserved.
+ * Copyright (C) 2012, 2014 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
diff --git a/cpukit/libmisc/shell/main_mmove.c b/cpukit/libmisc/shell/main_mmove.c
index 38731b10a2..0029882d62 100644
--- a/cpukit/libmisc/shell/main_mmove.c
+++ b/cpukit/libmisc/shell/main_mmove.c
@@ -62,7 +62,7 @@ static int rtems_shell_main_mmove(
/*
* Now copy the memory.
*/
- memcpy(dst, src, length);
+ memmove(dst, src, length);
return 0;
}
diff --git a/cpukit/libmisc/shell/main_pci.c b/cpukit/libmisc/shell/main_pci.c
index 5946aceb33..4902ed07b9 100644
--- a/cpukit/libmisc/shell/main_pci.c
+++ b/cpukit/libmisc/shell/main_pci.c
@@ -375,7 +375,7 @@ static int shell_pci_infodev(
printf(" PCIID: 0x%04x\n", dev->busdevfun);
bus = dev->bus;
if (!bus) {
- printf(" AT BUS: 0x%x via Host Bridge\n", bus->num);
+ printf(" AT BUS: via Host Bridge\n");
} else {
printf(" AT BUS: 0x%x via Bridge at [%x:%x:%x]\n", bus->num,
PCI_DEV_EXPAND(bus->dev.busdevfun));
diff --git a/cpukit/libmisc/shell/main_profreport.c b/cpukit/libmisc/shell/main_profreport.c
index a3c64a5e5d..ab14cc1e49 100644
--- a/cpukit/libmisc/shell/main_profreport.c
+++ b/cpukit/libmisc/shell/main_profreport.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2015 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
diff --git a/cpukit/libmisc/shell/main_rtc.c b/cpukit/libmisc/shell/main_rtc.c
index 21ca8bb9d1..940c7c9b52 100644
--- a/cpukit/libmisc/shell/main_rtc.c
+++ b/cpukit/libmisc/shell/main_rtc.c
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2009 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2009 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
diff --git a/cpukit/libmisc/shell/main_spi.c b/cpukit/libmisc/shell/main_spi.c
index 487a22fc6c..9c47ba0054 100644
--- a/cpukit/libmisc/shell/main_spi.c
+++ b/cpukit/libmisc/shell/main_spi.c
@@ -1,7 +1,7 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
- * Copyright (C) 2020 embedded brains GmbH.
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/cpukit/libmisc/shell/shell-wait-for-input.c b/cpukit/libmisc/shell/shell-wait-for-input.c
index db1387baf3..60d6ea4225 100644
--- a/cpukit/libmisc/shell/shell-wait-for-input.c
+++ b/cpukit/libmisc/shell/shell-wait-for-input.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2011 embedded brains GmbH & Co. KG
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
diff --git a/cpukit/libmisc/shell/shell.c b/cpukit/libmisc/shell/shell.c
index cd83aa56d1..9cefc80255 100644
--- a/cpukit/libmisc/shell/shell.c
+++ b/cpukit/libmisc/shell/shell.c
@@ -806,6 +806,109 @@ void rtems_shell_print_env(
#endif
/*
+ * Wait for the string to return or timeout.
+ */
+static bool rtems_shell_term_wait_for(const int fd, const char* str, const int timeout)
+{
+ int msec = timeout;
+ int i = 0;
+ while (msec-- > 0 && str[i] != '\0') {
+ char ch[2];
+ if (read(fd, &ch[0], 1) == 1) {
+ fflush(stdout);
+ if (ch[0] != str[i++]) {
+ return false;
+ }
+ msec = timeout;
+ } else {
+ usleep(1000);
+ }
+ }
+ if (msec == 0) {
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Buffer a string up to the end string
+ */
+static int rtems_shell_term_buffer_until(const int fd,
+ char* buf,
+ const int size,
+ const char* end,
+ const int timeout)
+{
+ int msec = timeout;
+ int i = 0;
+ int e = 0;
+ memset(&buf[0], 0, size);
+ while (msec-- > 0 && i < size && end[e] != '\0') {
+ char ch[2];
+ if (read(fd, &ch[0], 1) == 1) {
+ fflush(stdout);
+ buf[i++] = ch[0];
+ if (ch[0] == end[e]) {
+ e++;
+ } else {
+ e = 0;
+ }
+ msec = timeout;
+ } else {
+ usleep(1000);
+ }
+ }
+ if (msec == 0 || end[e] != '\0') {
+ return -1;
+ }
+ i -= e;
+ if (i < size) {
+ buf[i] = '\0';
+ }
+ return i;
+}
+
+/*
+ * Determine if the terminal has the row and column values
+ * swapped
+ *
+ * https://github.com/tmux/tmux/issues/3457
+ *
+ * Tmux has a bug where the lines and cols are swapped. There is a lag
+ * in the time it takes to get the fix into code so see if tmux is
+ * running and which version and work around the bug.
+ *
+ * The terminal device needs to have VMIN=0, and VTIME=0
+ */
+static bool rtems_shell_term_row_column_swapped(const int fd, const int timeout) {
+ char buf[64];
+ memset(&buf[0], 0, sizeof(buf));
+ /*
+ * CSI > Ps q
+ * Ps = 0 => DCS > | text ST
+ */
+ fputs("\033[>0q", stdout);
+ fflush(stdout);
+ if (rtems_shell_term_wait_for(fd, "\033P>|", timeout)) {
+ int len = rtems_shell_term_buffer_until(fd, buf, sizeof(buf), "\033\\", timeout);
+ if (len > 0) {
+ if (memcmp(buf, "tmux ", 5) == 0) {
+ static const char* bad_versions[] = {
+ "3.2", "3.2a", "3.3", "3.3a"
+ };
+ size_t i;
+ for (i = 0; i < RTEMS_ARRAY_SIZE(bad_versions); ++i) {
+ if (strcmp(bad_versions[i], buf + 5) == 0) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
+/*
* Direct method to get the size of an XTERM window.
*
* If you do not use an XTERM the env variables are not define.
@@ -814,6 +917,7 @@ static void rtems_shell_winsize( void )
{
const int fd = fileno(stdin);
struct winsize ws;
+ const int timeout = 150;
char buf[64];
bool ok = false;
int lines = 0;
@@ -831,9 +935,6 @@ static void rtems_shell_winsize( void )
term.c_cc[VMIN] = 0;
term.c_cc[VTIME] = 0;
if (tcsetattr (fd, TCSADRAIN, &term) >= 0) {
- int msec = 50;
- int len = 0;
- int i = 0;
memset(&buf[0], 0, sizeof(buf));
/*
* https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Miscellaneous
@@ -842,35 +943,34 @@ static void rtems_shell_winsize( void )
*/
fputs("\033[18t", stdout);
fflush(stdout);
- while (msec-- > 0 && len < sizeof(buf)) {
- char ch[2];
- if (read(fd, &ch[0], 1) == 1) {
- buf[len++] = ch[0];
- msec = 50;
- } else {
- usleep(1000);
- }
- }
- while (i < len) {
- static const char resp[] = "\033[8;";
- if (memcmp(resp, &buf[i], sizeof(resp) - 1) == 0) {
- i += sizeof(resp) - 1;
- while (i < len && buf[i] != ';') {
+ if (rtems_shell_term_wait_for(fd, "\033[8;", timeout)) {
+ int len = rtems_shell_term_buffer_until(fd, buf, sizeof(buf), ";", timeout);
+ if (len > 0) {
+ int i;
+ lines = 0;
+ i = 0;
+ while (i < len) {
lines *= 10;
lines += buf[i++] - '0';
}
- cols = 0;
- ++i;
- while (i < len && buf[i] != 't') {
- cols *= 10;
- cols += buf[i++] - '0';
+ len = rtems_shell_term_buffer_until(fd, buf, sizeof(buf), "t", timeout);
+ if (len > 0) {
+ cols = 0;
+ i = 0;
+ while (i < len) {
+ cols *= 10;
+ cols += buf[i++] - '0';
+ }
+ ok = true;
}
- } else {
- i++;
}
- ok = true;
}
}
+ if (rtems_shell_term_row_column_swapped(fd, timeout)) {
+ int tmp = lines;
+ lines = cols;
+ cols = tmp;
+ }
tcsetattr (fd, TCSADRAIN, &cterm);
}
}