chprintf() implemented, improved the shell.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3093 35acf78f-673a-0410-8e92-d51de3d6d3f4master
parent
e10edf1683
commit
ddc9ded3f0
|
@ -108,7 +108,7 @@ static void cmd_mem(BaseChannel *chp, int argc, char *argv[]) {
|
||||||
|
|
||||||
(void)argv;
|
(void)argv;
|
||||||
if (argc > 0) {
|
if (argc > 0) {
|
||||||
shellPrintLine(chp, "Usage: mem");
|
chprintf(chp, "Usage: mem\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
n = chHeapStatus(NULL, &size);
|
n = chHeapStatus(NULL, &size);
|
||||||
|
@ -138,10 +138,10 @@ static void cmd_threads(BaseChannel *chp, int argc, char *argv[]) {
|
||||||
|
|
||||||
(void)argv;
|
(void)argv;
|
||||||
if (argc > 0) {
|
if (argc > 0) {
|
||||||
shellPrintLine(chp, "Usage: threads");
|
chprintf(chp, "Usage: threads\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
shellPrintLine(chp, " addr stack prio refs state time");
|
chprintf(chp, " addr stack prio refs state time\r\n");
|
||||||
tp = chRegFirstThread();
|
tp = chRegFirstThread();
|
||||||
do {
|
do {
|
||||||
chprintf(chp, "%.8lx %.8lx %4lu %4lu %9s %lu\r\n",
|
chprintf(chp, "%.8lx %.8lx %4lu %4lu %9s %lu\r\n",
|
||||||
|
@ -157,13 +157,13 @@ static void cmd_test(BaseChannel *chp, int argc, char *argv[]) {
|
||||||
|
|
||||||
(void)argv;
|
(void)argv;
|
||||||
if (argc > 0) {
|
if (argc > 0) {
|
||||||
shellPrintLine(chp, "Usage: test");
|
chprintf(chp, "Usage: test\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tp = chThdCreateFromHeap(NULL, TEST_WA_SIZE, chThdGetPriority(),
|
tp = chThdCreateFromHeap(NULL, TEST_WA_SIZE, chThdGetPriority(),
|
||||||
TestThread, chp);
|
TestThread, chp);
|
||||||
if (tp == NULL) {
|
if (tp == NULL) {
|
||||||
shellPrintLine(chp, "out of memory");
|
chprintf(chp, "out of memory\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
chThdWait(tp);
|
chThdWait(tp);
|
||||||
|
@ -176,16 +176,16 @@ static void cmd_tree(BaseChannel *chp, int argc, char *argv[]) {
|
||||||
|
|
||||||
(void)argv;
|
(void)argv;
|
||||||
if (argc > 0) {
|
if (argc > 0) {
|
||||||
shellPrintLine(chp, "Usage: tree");
|
chprintf(chp, "Usage: tree\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!fs_ready) {
|
if (!fs_ready) {
|
||||||
shellPrintLine(chp, "File System not mounted");
|
chprintf(chp, "File System not mounted\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
err = f_getfree("/", &clusters, &fsp);
|
err = f_getfree("/", &clusters, &fsp);
|
||||||
if (err != FR_OK) {
|
if (err != FR_OK) {
|
||||||
shellPrintLine(chp, "FS: f_getfree() failed");
|
chprintf(chp, "FS: f_getfree() failed\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
chprintf(chp,
|
chprintf(chp,
|
||||||
|
|
|
@ -45,6 +45,29 @@ static char *ltoa(char *p, long num, unsigned radix) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief System formatted output function.
|
||||||
|
* @details This function implements a minimal @p printf() like functionality
|
||||||
|
* with output on a @p BaseChannel.
|
||||||
|
* The general parameters format is: %[.][width|*][l|L]p.
|
||||||
|
* The following parameter types (p) are supported:
|
||||||
|
* - <b>x</b> hexadecimal integer.
|
||||||
|
* - <b>X</b> hexadecimal long.
|
||||||
|
* - <b>o</b> octal integer.
|
||||||
|
* - <b>O</b> octal long.
|
||||||
|
* - <b>d</b> decimal signed integer.
|
||||||
|
* - <b>D</b> decimal signed long.
|
||||||
|
* - <b>u</b> decimal unsigned integer.
|
||||||
|
* - <b>U</b> decimal unsigned long.
|
||||||
|
* - <b>c</b> character.
|
||||||
|
* - <b>s</b> string.
|
||||||
|
* .
|
||||||
|
* @note Floating point types are not implemented, this function is meant
|
||||||
|
* as a system utility and not a full implementation.
|
||||||
|
*
|
||||||
|
* @param[in] chp pointer to a @p BaseChannel implementing object
|
||||||
|
* @param[in] fmt formatting string
|
||||||
|
*/
|
||||||
void chprintf(BaseChannel *chp, const char *fmt, ...) {
|
void chprintf(BaseChannel *chp, const char *fmt, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char buf[MAX_FILLER + 1];
|
char buf[MAX_FILLER + 1];
|
||||||
|
@ -84,8 +107,7 @@ void chprintf(BaseChannel *chp, const char *fmt, ...) {
|
||||||
c = va_arg(ap, int);
|
c = va_arg(ap, int);
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
width *= 10;
|
width = width * 10 + c;
|
||||||
width += c;
|
|
||||||
}
|
}
|
||||||
n = 0;
|
n = 0;
|
||||||
if (c == '.') {
|
if (c == '.') {
|
||||||
|
@ -122,7 +144,8 @@ void chprintf(BaseChannel *chp, const char *fmt, ...) {
|
||||||
lflag = TRUE;
|
lflag = TRUE;
|
||||||
case 'o':
|
case 'o':
|
||||||
c = 8;
|
c = 8;
|
||||||
oxu: if (lflag)
|
oxu:
|
||||||
|
if (lflag)
|
||||||
l = va_arg(ap, long);
|
l = va_arg(ap, long);
|
||||||
else
|
else
|
||||||
l = va_arg(ap, int);
|
l = va_arg(ap, int);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
/**
|
/**
|
||||||
* @file shell.c
|
* @file shell.c
|
||||||
* @brief Simple CLI shell code.
|
* @brief Simple CLI shell code.
|
||||||
|
*
|
||||||
* @addtogroup SHELL
|
* @addtogroup SHELL
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
@ -31,6 +32,7 @@
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
#include "shell.h"
|
#include "shell.h"
|
||||||
|
#include "chprintf.h"
|
||||||
|
|
||||||
#if SHELL_USE_IPRINTF
|
#if SHELL_USE_IPRINTF
|
||||||
#define sprintf siprintf
|
#define sprintf siprintf
|
||||||
|
@ -65,15 +67,13 @@ static char *strtok_r(char *str, const char *delim, char **saveptr) {
|
||||||
|
|
||||||
static void usage(BaseChannel *chp, char *p) {
|
static void usage(BaseChannel *chp, char *p) {
|
||||||
|
|
||||||
shellPrint(chp, "Usage: ");
|
chprintf(chp, "Usage: %s\r\n", p);
|
||||||
shellPrintLine(chp, p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void list_commands(BaseChannel *chp, const ShellCommand *scp) {
|
static void list_commands(BaseChannel *chp, const ShellCommand *scp) {
|
||||||
|
|
||||||
while (scp->sc_name != NULL) {
|
while (scp->sc_name != NULL) {
|
||||||
shellPrint(chp, scp->sc_name);
|
chprintf(chp, "%s ", scp->sc_name);
|
||||||
shellPrint(chp, " ");
|
|
||||||
scp++;
|
scp++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,38 +86,33 @@ static void cmd_info(BaseChannel *chp, int argc, char *argv[]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
shellPrint(chp, "Kernel version: ");
|
chprintf(chp, "Kernel: %s\r\n", CH_KERNEL_VERSION);
|
||||||
shellPrintLine(chp, CH_KERNEL_VERSION);
|
#ifdef CH_COMPILER_NAME
|
||||||
#ifdef __GNUC__
|
chprintf(chp, "Compiler: %s\r\n", CH_COMPILER_NAME);
|
||||||
shellPrint(chp, "GCC Version: ");
|
|
||||||
shellPrintLine(chp, __VERSION__);
|
|
||||||
#endif
|
#endif
|
||||||
shellPrint(chp, "Architecture: ");
|
chprintf(chp, "Architecture: %s\r\n", CH_ARCHITECTURE_NAME);
|
||||||
shellPrintLine(chp, CH_ARCHITECTURE_NAME);
|
|
||||||
#ifdef CH_CORE_VARIANT_NAME
|
#ifdef CH_CORE_VARIANT_NAME
|
||||||
shellPrint(chp, "Core Variant: ");
|
chprintf(chp, "Core Variant: %s\r\n", CH_CORE_VARIANT_NAME);
|
||||||
shellPrintLine(chp, CH_CORE_VARIANT_NAME);
|
#endif
|
||||||
|
#ifdef CH_PORT_INFO
|
||||||
|
chprintf(chp, "Port Info: %s\r\n", CH_PORT_INFO);
|
||||||
#endif
|
#endif
|
||||||
#ifdef PLATFORM_NAME
|
#ifdef PLATFORM_NAME
|
||||||
shellPrint(chp, "Platform: ");
|
chprintf(chp, "Platform: %s\r\n", PLATFORM_NAME);
|
||||||
shellPrintLine(chp, PLATFORM_NAME);
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef BOARD_NAME
|
#ifdef BOARD_NAME
|
||||||
shellPrint(chp, "Board: ");
|
chprintf(chp, "Board: %s\r\n", BOARD_NAME);
|
||||||
shellPrintLine(chp, BOARD_NAME);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cmd_systime(BaseChannel *chp, int argc, char *argv[]) {
|
static void cmd_systime(BaseChannel *chp, int argc, char *argv[]) {
|
||||||
char buf[12];
|
|
||||||
|
|
||||||
(void)argv;
|
(void)argv;
|
||||||
if (argc > 0) {
|
if (argc > 0) {
|
||||||
usage(chp, "systime");
|
usage(chp, "systime");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sprintf(buf, "%lu", (unsigned long)chTimeNow());
|
chprintf(chp, "%lu\r\n", (unsigned long)chTimeNow());
|
||||||
shellPrintLine(chp, buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -158,12 +153,11 @@ static msg_t shell_thread(void *p) {
|
||||||
char *lp, *cmd, *tokp, line[SHELL_MAX_LINE_LENGTH];
|
char *lp, *cmd, *tokp, line[SHELL_MAX_LINE_LENGTH];
|
||||||
char *args[SHELL_MAX_ARGUMENTS + 1];
|
char *args[SHELL_MAX_ARGUMENTS + 1];
|
||||||
|
|
||||||
shellPrintLine(chp, "");
|
chprintf(chp, "\r\nChibiOS/RT Shell\r\n");
|
||||||
shellPrintLine(chp, "ChibiOS/RT Shell");
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
shellPrint(chp, "ch> ");
|
chprintf(chp, "ch> ");
|
||||||
if (shellGetLine(chp, line, sizeof(line))) {
|
if (shellGetLine(chp, line, sizeof(line))) {
|
||||||
shellPrint(chp, "\nlogout");
|
chprintf(chp, "\r\nlogout");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lp = strtok_r(line, " \009", &tokp);
|
lp = strtok_r(line, " \009", &tokp);
|
||||||
|
@ -171,7 +165,7 @@ static msg_t shell_thread(void *p) {
|
||||||
n = 0;
|
n = 0;
|
||||||
while ((lp = strtok_r(NULL, " \009", &tokp)) != NULL) {
|
while ((lp = strtok_r(NULL, " \009", &tokp)) != NULL) {
|
||||||
if (n >= SHELL_MAX_ARGUMENTS) {
|
if (n >= SHELL_MAX_ARGUMENTS) {
|
||||||
shellPrintLine(chp, "too many arguments");
|
chprintf(chp, "too many arguments\r\n");
|
||||||
cmd = NULL;
|
cmd = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -180,23 +174,27 @@ static msg_t shell_thread(void *p) {
|
||||||
args[n] = NULL;
|
args[n] = NULL;
|
||||||
if (cmd != NULL) {
|
if (cmd != NULL) {
|
||||||
if (strcasecmp(cmd, "exit") == 0) {
|
if (strcasecmp(cmd, "exit") == 0) {
|
||||||
if (n > 0)
|
if (n > 0) {
|
||||||
usage(chp, "exit");
|
usage(chp, "exit");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (strcasecmp(cmd, "help") == 0) {
|
else if (strcasecmp(cmd, "help") == 0) {
|
||||||
if (n > 0)
|
if (n > 0) {
|
||||||
usage(chp, "help");
|
usage(chp, "help");
|
||||||
shellPrint(chp, "Commands: help exit ");
|
continue;
|
||||||
|
}
|
||||||
|
chprintf(chp, "Commands: help exit ");
|
||||||
list_commands(chp, local_commands);
|
list_commands(chp, local_commands);
|
||||||
if (scp != NULL)
|
if (scp != NULL)
|
||||||
list_commands(chp, scp);
|
list_commands(chp, scp);
|
||||||
shellPrintLine(chp, "");
|
chprintf(chp, "\r\n");
|
||||||
}
|
}
|
||||||
else if (cmdexec(local_commands, chp, cmd, n, args) &&
|
else if (cmdexec(local_commands, chp, cmd, n, args) &&
|
||||||
((scp == NULL) || cmdexec(scp, chp, cmd, n, args))) {
|
((scp == NULL) || cmdexec(scp, chp, cmd, n, args))) {
|
||||||
shellPrint(chp, cmd);
|
chprintf(chp, "%s", cmd);
|
||||||
shellPrintLine(chp, " ?");
|
chprintf(chp, " ?\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,30 +226,6 @@ Thread *shellCreate(const ShellConfig *scp, size_t size, tprio_t prio) {
|
||||||
return chThdCreateFromHeap(NULL, size, prio, shell_thread, (void *)scp);
|
return chThdCreateFromHeap(NULL, size, prio, shell_thread, (void *)scp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Prints a string.
|
|
||||||
*
|
|
||||||
* @param[in] chp pointer to a @p BaseChannel object
|
|
||||||
* @param[in] msg pointer to the string
|
|
||||||
*/
|
|
||||||
void shellPrint(BaseChannel *chp, const char *msg) {
|
|
||||||
|
|
||||||
while (*msg)
|
|
||||||
chIOPut(chp, *msg++);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Prints a string with a final newline.
|
|
||||||
*
|
|
||||||
* @param[in] chp pointer to a @p BaseChannel object
|
|
||||||
* @param[in] msg pointer to the string
|
|
||||||
*/
|
|
||||||
void shellPrintLine(BaseChannel *chp, const char *msg) {
|
|
||||||
|
|
||||||
shellPrint(chp, msg);
|
|
||||||
shellPrint(chp, "\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads a whole line from the input channel.
|
* @brief Reads a whole line from the input channel.
|
||||||
*
|
*
|
||||||
|
@ -271,7 +245,7 @@ bool_t shellGetLine(BaseChannel *chp, char *line, unsigned size) {
|
||||||
if (c < 0)
|
if (c < 0)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (c == 4) {
|
if (c == 4) {
|
||||||
shellPrintLine(chp, "^D");
|
chprintf(chp, "^D");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
if (c == 8) {
|
if (c == 8) {
|
||||||
|
@ -284,7 +258,7 @@ bool_t shellGetLine(BaseChannel *chp, char *line, unsigned size) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c == '\r') {
|
if (c == '\r') {
|
||||||
shellPrintLine(chp, "");
|
chprintf(chp, "\r\n");
|
||||||
*p = 0;
|
*p = 0;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
/**
|
/**
|
||||||
* @file shell.h
|
* @file shell.h
|
||||||
* @brief Simple CLI shell header.
|
* @brief Simple CLI shell header.
|
||||||
|
*
|
||||||
* @addtogroup SHELL
|
* @addtogroup SHELL
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
@ -79,8 +80,6 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void shellInit(void);
|
void shellInit(void);
|
||||||
Thread *shellCreate(const ShellConfig *scp, size_t size, tprio_t prio);
|
Thread *shellCreate(const ShellConfig *scp, size_t size, tprio_t prio);
|
||||||
void shellPrint(BaseChannel *chp, const char *msg);
|
|
||||||
void shellPrintLine(BaseChannel *chp, const char *msg);
|
|
||||||
bool_t shellGetLine(BaseChannel *chp, char *line, unsigned size);
|
bool_t shellGetLine(BaseChannel *chp, char *line, unsigned size);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,11 @@
|
||||||
(backported to 2.2.4).
|
(backported to 2.2.4).
|
||||||
- FIX: Fixed timeout problem in the lwIP interface layer (bug 3302420)
|
- FIX: Fixed timeout problem in the lwIP interface layer (bug 3302420)
|
||||||
(backported to 2.2.4).
|
(backported to 2.2.4).
|
||||||
|
- NEW: Added a chprintf() function to ./os/various, it can print on any
|
||||||
|
BaseChannel.
|
||||||
|
- NEW: Improved the mini shell, enhanced info command, optimizations and
|
||||||
|
removed the shellPrint() and shellPrintLine() functions, now it uses
|
||||||
|
chprintf() for output.
|
||||||
- NEW: lwIP 1.4.0 has been integrated, this new version does not require
|
- NEW: lwIP 1.4.0 has been integrated, this new version does not require
|
||||||
custom hooks into the Thread structure and is thus much lighter.
|
custom hooks into the Thread structure and is thus much lighter.
|
||||||
- NEW: FatFs demo for the STM32F103ZG using the SDC driver.
|
- NEW: FatFs demo for the STM32F103ZG using the SDC driver.
|
||||||
|
|
Loading…
Reference in New Issue