chprintf() implemented, improved the shell.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3093 35acf78f-673a-0410-8e92-d51de3d6d3f4
master
gdisirio 2011-06-28 06:29:04 +00:00
parent e10edf1683
commit ddc9ded3f0
5 changed files with 75 additions and 74 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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;
} }

View File

@ -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
} }

View File

@ -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.