diff --git a/demos/ARMCM3-STM32F103-FATFS/main.c b/demos/ARMCM3-STM32F103-FATFS/main.c index 98eb19962..e3a5fc6ad 100644 --- a/demos/ARMCM3-STM32F103-FATFS/main.c +++ b/demos/ARMCM3-STM32F103-FATFS/main.c @@ -108,7 +108,7 @@ static void cmd_mem(BaseChannel *chp, int argc, char *argv[]) { (void)argv; if (argc > 0) { - shellPrintLine(chp, "Usage: mem"); + chprintf(chp, "Usage: mem\r\n"); return; } n = chHeapStatus(NULL, &size); @@ -138,10 +138,10 @@ static void cmd_threads(BaseChannel *chp, int argc, char *argv[]) { (void)argv; if (argc > 0) { - shellPrintLine(chp, "Usage: threads"); + chprintf(chp, "Usage: threads\r\n"); return; } - shellPrintLine(chp, " addr stack prio refs state time"); + chprintf(chp, " addr stack prio refs state time\r\n"); tp = chRegFirstThread(); do { 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; if (argc > 0) { - shellPrintLine(chp, "Usage: test"); + chprintf(chp, "Usage: test\r\n"); return; } tp = chThdCreateFromHeap(NULL, TEST_WA_SIZE, chThdGetPriority(), TestThread, chp); if (tp == NULL) { - shellPrintLine(chp, "out of memory"); + chprintf(chp, "out of memory\r\n"); return; } chThdWait(tp); @@ -176,16 +176,16 @@ static void cmd_tree(BaseChannel *chp, int argc, char *argv[]) { (void)argv; if (argc > 0) { - shellPrintLine(chp, "Usage: tree"); + chprintf(chp, "Usage: tree\r\n"); return; } if (!fs_ready) { - shellPrintLine(chp, "File System not mounted"); + chprintf(chp, "File System not mounted\r\n"); return; } err = f_getfree("/", &clusters, &fsp); if (err != FR_OK) { - shellPrintLine(chp, "FS: f_getfree() failed"); + chprintf(chp, "FS: f_getfree() failed\r\n"); return; } chprintf(chp, diff --git a/os/various/chprintf.c b/os/various/chprintf.c index 383a2121a..1645cd678 100644 --- a/os/various/chprintf.c +++ b/os/various/chprintf.c @@ -45,6 +45,29 @@ static char *ltoa(char *p, long num, unsigned radix) { 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: + * - x hexadecimal integer. + * - X hexadecimal long. + * - o octal integer. + * - O octal long. + * - d decimal signed integer. + * - D decimal signed long. + * - u decimal unsigned integer. + * - U decimal unsigned long. + * - c character. + * - s 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, ...) { va_list ap; char buf[MAX_FILLER + 1]; @@ -84,8 +107,7 @@ void chprintf(BaseChannel *chp, const char *fmt, ...) { c = va_arg(ap, int); else break; - width *= 10; - width += c; + width = width * 10 + c; } n = 0; if (c == '.') { @@ -122,7 +144,8 @@ void chprintf(BaseChannel *chp, const char *fmt, ...) { lflag = TRUE; case 'o': c = 8; - oxu: if (lflag) +oxu: + if (lflag) l = va_arg(ap, long); else l = va_arg(ap, int); diff --git a/os/various/shell.c b/os/various/shell.c index e3686c6cb..b62297fc8 100644 --- a/os/various/shell.c +++ b/os/various/shell.c @@ -19,8 +19,9 @@ */ /** - * @file shell.c - * @brief Simple CLI shell code. + * @file shell.c + * @brief Simple CLI shell code. + * * @addtogroup SHELL * @{ */ @@ -31,6 +32,7 @@ #include "ch.h" #include "hal.h" #include "shell.h" +#include "chprintf.h" #if SHELL_USE_IPRINTF #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) { - shellPrint(chp, "Usage: "); - shellPrintLine(chp, p); + chprintf(chp, "Usage: %s\r\n", p); } static void list_commands(BaseChannel *chp, const ShellCommand *scp) { while (scp->sc_name != NULL) { - shellPrint(chp, scp->sc_name); - shellPrint(chp, " "); + chprintf(chp, "%s ", scp->sc_name); scp++; } } @@ -86,38 +86,33 @@ static void cmd_info(BaseChannel *chp, int argc, char *argv[]) { return; } - shellPrint(chp, "Kernel version: "); - shellPrintLine(chp, CH_KERNEL_VERSION); -#ifdef __GNUC__ - shellPrint(chp, "GCC Version: "); - shellPrintLine(chp, __VERSION__); + chprintf(chp, "Kernel: %s\r\n", CH_KERNEL_VERSION); +#ifdef CH_COMPILER_NAME + chprintf(chp, "Compiler: %s\r\n", CH_COMPILER_NAME); #endif - shellPrint(chp, "Architecture: "); - shellPrintLine(chp, CH_ARCHITECTURE_NAME); + chprintf(chp, "Architecture: %s\r\n", CH_ARCHITECTURE_NAME); #ifdef CH_CORE_VARIANT_NAME - shellPrint(chp, "Core Variant: "); - shellPrintLine(chp, CH_CORE_VARIANT_NAME); + chprintf(chp, "Core Variant: %s\r\n", CH_CORE_VARIANT_NAME); +#endif +#ifdef CH_PORT_INFO + chprintf(chp, "Port Info: %s\r\n", CH_PORT_INFO); #endif #ifdef PLATFORM_NAME - shellPrint(chp, "Platform: "); - shellPrintLine(chp, PLATFORM_NAME); + chprintf(chp, "Platform: %s\r\n", PLATFORM_NAME); #endif #ifdef BOARD_NAME - shellPrint(chp, "Board: "); - shellPrintLine(chp, BOARD_NAME); + chprintf(chp, "Board: %s\r\n", BOARD_NAME); #endif } static void cmd_systime(BaseChannel *chp, int argc, char *argv[]) { - char buf[12]; (void)argv; if (argc > 0) { usage(chp, "systime"); return; } - sprintf(buf, "%lu", (unsigned long)chTimeNow()); - shellPrintLine(chp, buf); + chprintf(chp, "%lu\r\n", (unsigned long)chTimeNow()); } /** @@ -158,12 +153,11 @@ static msg_t shell_thread(void *p) { char *lp, *cmd, *tokp, line[SHELL_MAX_LINE_LENGTH]; char *args[SHELL_MAX_ARGUMENTS + 1]; - shellPrintLine(chp, ""); - shellPrintLine(chp, "ChibiOS/RT Shell"); + chprintf(chp, "\r\nChibiOS/RT Shell\r\n"); while (TRUE) { - shellPrint(chp, "ch> "); + chprintf(chp, "ch> "); if (shellGetLine(chp, line, sizeof(line))) { - shellPrint(chp, "\nlogout"); + chprintf(chp, "\r\nlogout"); break; } lp = strtok_r(line, " \009", &tokp); @@ -171,7 +165,7 @@ static msg_t shell_thread(void *p) { n = 0; while ((lp = strtok_r(NULL, " \009", &tokp)) != NULL) { if (n >= SHELL_MAX_ARGUMENTS) { - shellPrintLine(chp, "too many arguments"); + chprintf(chp, "too many arguments\r\n"); cmd = NULL; break; } @@ -180,23 +174,27 @@ static msg_t shell_thread(void *p) { args[n] = NULL; if (cmd != NULL) { if (strcasecmp(cmd, "exit") == 0) { - if (n > 0) + if (n > 0) { usage(chp, "exit"); + continue; + } break; } else if (strcasecmp(cmd, "help") == 0) { - if (n > 0) + if (n > 0) { usage(chp, "help"); - shellPrint(chp, "Commands: help exit "); + continue; + } + chprintf(chp, "Commands: help exit "); list_commands(chp, local_commands); if (scp != NULL) list_commands(chp, scp); - shellPrintLine(chp, ""); + chprintf(chp, "\r\n"); } else if (cmdexec(local_commands, chp, cmd, n, args) && ((scp == NULL) || cmdexec(scp, chp, cmd, n, args))) { - shellPrint(chp, cmd); - shellPrintLine(chp, " ?"); + chprintf(chp, "%s", cmd); + 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); } -/** - * @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. * @@ -271,7 +245,7 @@ bool_t shellGetLine(BaseChannel *chp, char *line, unsigned size) { if (c < 0) return TRUE; if (c == 4) { - shellPrintLine(chp, "^D"); + chprintf(chp, "^D"); return TRUE; } if (c == 8) { @@ -284,7 +258,7 @@ bool_t shellGetLine(BaseChannel *chp, char *line, unsigned size) { continue; } if (c == '\r') { - shellPrintLine(chp, ""); + chprintf(chp, "\r\n"); *p = 0; return FALSE; } diff --git a/os/various/shell.h b/os/various/shell.h index 9b3b70513..075d4e264 100644 --- a/os/various/shell.h +++ b/os/various/shell.h @@ -19,8 +19,9 @@ */ /** - * @file shell.h - * @brief Simple CLI shell header. + * @file shell.h + * @brief Simple CLI shell header. + * * @addtogroup SHELL * @{ */ @@ -79,8 +80,6 @@ extern "C" { #endif void shellInit(void); 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); #ifdef __cplusplus } diff --git a/readme.txt b/readme.txt index a187c458a..31dbcfd6a 100644 --- a/readme.txt +++ b/readme.txt @@ -83,6 +83,11 @@ (backported to 2.2.4). - FIX: Fixed timeout problem in the lwIP interface layer (bug 3302420) (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 custom hooks into the Thread structure and is thus much lighter. - NEW: FatFs demo for the STM32F103ZG using the SDC driver.