aboutsummaryrefslogtreecommitdiffstats
path: root/demos
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2009-12-10 15:44:55 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2009-12-10 15:44:55 +0000
commitdea70dbc797e0936c2532ae55881437e06e169fa (patch)
tree8b2e54295e4f0d670c0c9625ae1d4c475c6c7176 /demos
parent97b35245d19b59ff87d69fa9f7df701eea8f18c9 (diff)
downloadChibiOS-dea70dbc797e0936c2532ae55881437e06e169fa.tar.gz
ChibiOS-dea70dbc797e0936c2532ae55881437e06e169fa.tar.bz2
ChibiOS-dea70dbc797e0936c2532ae55881437e06e169fa.zip
Added a small generic command line shell.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1411 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'demos')
-rw-r--r--demos/Win32-MinGW/Makefile3
-rw-r--r--demos/Win32-MinGW/main.c316
2 files changed, 96 insertions, 223 deletions
diff --git a/demos/Win32-MinGW/Makefile b/demos/Win32-MinGW/Makefile
index e690b7804..76362dec1 100644
--- a/demos/Win32-MinGW/Makefile
+++ b/demos/Win32-MinGW/Makefile
@@ -21,7 +21,7 @@ CC = $(TRGT)gcc
AS = $(TRGT)gcc -x assembler-with-cpp
# List all default C defines here, like -D_DEBUG=1
-DDEFS =
+DDEFS = -DSHELL_USE_IPRINTF=FALSE
# List all default ASM defines here, like -D_DEBUG=1
DADEFS =
@@ -69,6 +69,7 @@ SRC = ${PORTSRC} \
${TESTSRC} \
${HALSRC} \
${PLATFORMSRC} \
+ ${CHIBIOS}/os/various/shell.c \
main.c
# List ASM source files here
diff --git a/demos/Win32-MinGW/main.c b/demos/Win32-MinGW/main.c
index 2b0c5ea15..c2ead083e 100644
--- a/demos/Win32-MinGW/main.c
+++ b/demos/Win32-MinGW/main.c
@@ -17,53 +17,36 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <string.h>
-#include <stdio.h>
-
#include "ch.h"
#include "hal.h"
+#include "test.h"
+#include "shell.h"
-static uint32_t wdguard;
-static WORKING_AREA(wdarea, 2048);
-
-static uint32_t cdguard;
-static WORKING_AREA(cdarea, 2048);
-static Thread *cdtp;
-
-static msg_t WatchdogThread(void *arg);
-static msg_t ConsoleThread(void *arg);
-
-msg_t TestThread(void *p);
+#define SHELL_WA_SIZE THD_WA_SIZE(4096)
+#define CONSOLE_WA_SIZE THD_WA_SIZE(4096)
#define cprint(msg) chMsgSend(cdtp, (msg_t)msg)
-/*
- * Watchdog thread, it checks magic values located under the various stack
- * areas. The system is halted if something is wrong.
- */
-static msg_t WatchdogThread(void *arg) {
+static Thread *cdtp;
+static Thread *shelltp1;
+static Thread *shelltp2;
- (void)arg;
- wdguard = 0xA51F2E3D;
- cdguard = 0xA51F2E3D;
- while (TRUE) {
- if ((wdguard != 0xA51F2E3D) ||
- (cdguard != 0xA51F2E3D)) {
- printf("Halted by watchdog");
- fflush(stdout);
- chSysHalt();
- }
- chThdSleep(50);
- }
- return 0;
-}
+static const ShellConfig shell_cfg1 = {
+ (BaseChannel *)&SD1,
+ NULL
+};
+
+static const ShellConfig shell_cfg2 = {
+ (BaseChannel *)&SD2,
+ NULL
+};
/*
* Console print server done using synchronous messages. This makes the access
* to the C printf() thread safe and the print operation atomic among threads.
* In this example the message is the zero termitated string itself.
*/
-static msg_t ConsoleThread(void *arg) {
+static msg_t console_thread(void *arg) {
(void)arg;
while (!chThdShouldTerminate()) {
@@ -74,221 +57,87 @@ static msg_t ConsoleThread(void *arg) {
return 0;
}
-static void PrintLineSD(SerialDriver *sd, char *msg) {
-
- while (*msg)
- sdPut(sd, *msg++);
-}
-
-static bool_t GetLineFDD(SerialDriver *sd, char *line, int size) {
- char *p = line;
-
- while (TRUE) {
- short c = chIQGet(&sd->d2.iqueue);
- if (c < 0)
- return TRUE;
- if (c == 4) {
- PrintLineSD(sd, "^D\r\n");
- return TRUE;
- }
- if (c == 8) {
- if (p != line) {
- sdPut(sd, (uint8_t)c);
- sdPut(sd, 0x20);
- sdPut(sd, (uint8_t)c);
- p--;
- }
- continue;
- }
- if (c == '\r') {
- PrintLineSD(sd, "\r\n");
- *p = 0;
- return FALSE;
- }
- if (c < 0x20)
- continue;
- if (p < line + size - 1) {
- sdPut(sd, (uint8_t)c);
- *p++ = (uint8_t)c;
- }
- }
-}
-
-/*
- * Example thread, not much to see here. It simulates the CTRL-C but there
- * are no real signals involved.
+/**
+ * @brief Shell termination handler.
+ *
+ * @param[in] id event id.
*/
-static msg_t HelloWorldThread(void *arg) {
- int i;
- short c;
- SerialDriver *sd = (SerialDriver *)arg;
-
- for (i = 0; i < 10; i++) {
+static void termination_handler(eventid_t id) {
- PrintLineSD(sd, "Hello World\r\n");
- c = sdGetTimeout(sd, 333);
- switch (c) {
- case Q_TIMEOUT:
- continue;
- case Q_RESET:
- return 1;
- case 3:
- PrintLineSD(sd, "^C\r\n");
- return 0;
- default:
- chThdSleep(333);
- }
+ (void)id;
+ if (shelltp1 && chThdTerminated(shelltp1)) {
+ chThdWait(shelltp1);
+ shelltp1 = NULL;
+ cprint("Init: shell on SD1 terminated\n");
+ chSysLock();
+ chOQResetI(&SD1.d2.oqueue);
+ chSysUnlock();
}
- return 0;
-}
-
-static bool_t checkend(SerialDriver *sd) {
-
- char * lp = strtok(NULL, " \009"); /* It is not thread safe but this is a demo.*/
- if (lp) {
- PrintLineSD(sd, lp);
- PrintLineSD(sd, " ?\r\n");
- return TRUE;
+ if (shelltp2 && chThdTerminated(shelltp2)) {
+ chThdWait(shelltp2);
+ shelltp2 = NULL;
+ cprint("Init: shell on SD2 terminated\n");
+ chSysLock();
+ chOQResetI(&SD2.d2.oqueue);
+ chSysUnlock();
}
- return FALSE;
}
-/*
- * Simple command shell thread, the argument is the serial line for the
- * standard input and output. It recognizes few simple commands.
+/**
+ * @brief SD1 status change handler.
+ *
+ * @param[in] id event id.
*/
-static msg_t ShellThread(void *arg) {
- SerialDriver *sd = (SerialDriver *)arg;
- char *lp, line[64];
- Thread *tp;
- WORKING_AREA(tarea, 2048);
-
- chSysLock();
- chIQResetI(&sd->d2.iqueue);
- chOQResetI(&sd->d2.oqueue);
- chSysUnlock();
- PrintLineSD(sd, "ChibiOS/RT Command Shell\r\n\n");
- while (TRUE) {
- PrintLineSD(sd, "ch> ");
- if (GetLineFDD(sd, line, sizeof(line))) {
- PrintLineSD(sd, "\nlogout");
- break;
- }
- lp = strtok(line, " \009"); // Note: not thread safe but it is just a demo.
- if (lp) {
- if ((stricmp(lp, "help") == 0) ||
- (stricmp(lp, "h") == 0) ||
- (stricmp(lp, "?") == 0)) {
- if (checkend(sd))
- continue;
- PrintLineSD(sd, "Commands:\r\n");
- PrintLineSD(sd, " help,h,? - This help\r\n");
- PrintLineSD(sd, " exit - Logout from ChibiOS/RT\r\n");
- PrintLineSD(sd, " time - Prints the system timer value\r\n");
- PrintLineSD(sd, " hello - Runs the Hello World demo thread\r\n");
- PrintLineSD(sd, " test - Runs the System Test thread\r\n");
- }
- else if (stricmp(lp, "exit") == 0) {
- if (checkend(sd))
- continue;
- PrintLineSD(sd, "\nlogout");
- break;
- }
- else if (stricmp(lp, "time") == 0) {
- if (checkend(sd))
- continue;
- sprintf(line, "Time: %d\r\n", chTimeNow());
- PrintLineSD(sd, line);
- }
- else if (stricmp(lp, "hello") == 0) {
- if (checkend(sd))
- continue;
- tp = chThdCreateStatic(tarea, sizeof(tarea),
- NORMALPRIO, HelloWorldThread, sd);
- if (chThdWait(tp))
- break; // Lost connection while executing the hello thread.
- }
- else if (stricmp(lp, "test") == 0) {
- if (checkend(sd))
- continue;
- tp = chThdCreateStatic(tarea, sizeof(tarea),
- NORMALPRIO, TestThread, arg);
- if (chThdWait(tp))
- break; // Lost connection while executing the hello thread.
- }
- else {
- PrintLineSD(sd, lp);
- PrintLineSD(sd, " ?\r\n");
- }
- }
- }
- return 0;
-}
-
-static WORKING_AREA(s1area, 4096);
-static Thread *s1;
-EventListener s1tel;
-
-static void COM1Handler(eventid_t id) {
+static void sd1_handler(eventid_t id) {
sdflags_t flags;
(void)id;
- if (s1 && chThdTerminated(s1)) {
- s1 = NULL;
- cprint("Init: disconnection on SD1\n");
- }
flags = sdGetAndClearFlags(&SD1);
- if ((flags & SD_CONNECTED) && (s1 == NULL)) {
+ if ((flags & SD_CONNECTED) && (shelltp1 == NULL)) {
cprint("Init: connection on SD1\n");
- s1 = chThdInit(s1area, sizeof(s1area),
- NORMALPRIO, ShellThread, &SD1);
- chEvtRegister(chThdGetExitEventSource(s1), &s1tel, 0);
- chThdResume(s1);
+ shelltp1 = shellCreate(&shell_cfg1, SHELL_WA_SIZE, NORMALPRIO + 1);
}
- if ((flags & SD_DISCONNECTED) && (s1 != NULL)) {
+ if (flags & SD_DISCONNECTED) {
+ cprint("Init: disconnection on SD1\n");
chSysLock();
chIQResetI(&SD1.d2.iqueue);
chSysUnlock();
}
}
-static WORKING_AREA(s2area, 4096);
-static Thread *s2;
-EventListener s2tel;
-
-static void COM2Handler(eventid_t id) {
+/**
+ * @brief SD2 status change handler.
+ *
+ * @param[in] id event id.
+ */
+static void sd2_handler(eventid_t id) {
sdflags_t flags;
(void)id;
- if (s2 && chThdTerminated(s2)) {
- s2 = NULL;
- cprint("Init: disconnection on SD2\n");
- }
flags = sdGetAndClearFlags(&SD2);
- if ((flags & SD_CONNECTED) && (s2 == NULL)) {
+ if ((flags & SD_CONNECTED) && (shelltp2 == NULL)) {
cprint("Init: connection on SD2\n");
- s2 = chThdInit(s2area, sizeof(s1area),
- NORMALPRIO, ShellThread, &SD2);
- chEvtRegister(chThdGetExitEventSource(s2), &s2tel, 1);
- chThdResume(s2);
+ shelltp2 = shellCreate(&shell_cfg2, SHELL_WA_SIZE, NORMALPRIO + 10);
}
- if ((flags & SD_DISCONNECTED) && (s2 != NULL)) {
+ if (flags & SD_DISCONNECTED) {
+ cprint("Init: disconnection on SD2\n");
chSysLock();
chIQResetI(&SD2.d2.iqueue);
chSysUnlock();
}
}
-static evhandler_t fhandlers[2] = {
- COM1Handler,
- COM2Handler
+static evhandler_t fhandlers[] = {
+ termination_handler,
+ sd1_handler,
+ sd2_handler
};
/*------------------------------------------------------------------------*
- * Simulator main, start here your threads, examples inside. *
+ * Simulator main. *
*------------------------------------------------------------------------*/
int main(void) {
- EventListener c1fel, c2fel;
+ EventListener sd1fel, sd2fel, tel;
/*
* HAL initialization.
@@ -300,22 +149,45 @@ int main(void) {
*/
chSysInit();
+ /*
+ * Serial ports (simulated) initialization.
+ */
sdStart(&SD1, NULL);
sdStart(&SD2, NULL);
- chThdCreateStatic(wdarea, sizeof(wdarea), NORMALPRIO + 2, WatchdogThread, NULL);
- cdtp = chThdCreateStatic(cdarea, sizeof(cdarea), NORMALPRIO + 1, ConsoleThread, NULL);
+ /*
+ * Shell manager initialization.
+ */
+ shellInit();
+ chEvtRegister(&shell_terminated, &tel, 0);
+
+ /*
+ * Console thread started.
+ */
+ cdtp = chThdCreateFromHeap(NULL, CONSOLE_WA_SIZE, NORMALPRIO + 1,
+ console_thread, NULL);
- cprint("Console service started on SD1, SD2\n");
+ /*
+ * Initializing connection/disconnection events.
+ */
+ cprint("Shell service started on SD1, SD2\n");
cprint(" - Listening for connections on SD1\n");
- sdGetAndClearFlags(&SD1);
- chEvtRegister(&SD1.d2.sevent, &c1fel, 0);
+ (void) sdGetAndClearFlags(&SD1);
+ chEvtRegister(&SD1.d2.sevent, &sd1fel, 1);
cprint(" - Listening for connections on SD2\n");
- sdGetAndClearFlags(&SD2);
- chEvtRegister(&SD2.d2.sevent, &c2fel, 1);
+ (void) sdGetAndClearFlags(&SD2);
+ chEvtRegister(&SD2.d2.sevent, &sd2fel, 2);
+
+ /*
+ * Events servicing loop.
+ */
while (!chThdShouldTerminate())
chEvtDispatch(fhandlers, chEvtWaitOne(ALL_EVENTS));
- chEvtUnregister(&SD1.d2.sevent, &c2fel); // Never invoked but this is an example...
- chEvtUnregister(&SD2.d2.sevent, &c1fel); // Never invoked but this is an example...
+
+ /*
+ * Clean simulator exit.
+ */
+ chEvtUnregister(&SD1.d2.sevent, &sd1fel);
+ chEvtUnregister(&SD2.d2.sevent, &sd2fel);
return 0;
}