From a2e989330ef587868921bf9ebc8079f939e57ad5 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 23 Dec 2009 20:11:44 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1460 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/GNU-Linux-GCC/main.c | 191 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 180 insertions(+), 11 deletions(-) (limited to 'demos/GNU-Linux-GCC/main.c') diff --git a/demos/GNU-Linux-GCC/main.c b/demos/GNU-Linux-GCC/main.c index 07e16625c..c969f2208 100644 --- a/demos/GNU-Linux-GCC/main.c +++ b/demos/GNU-Linux-GCC/main.c @@ -20,34 +20,203 @@ #include #include "ch.h" +#include "hal.h" +#include "test.h" +#include "shell.h" -static WORKING_AREA(waThread1, 2048); -static msg_t Thread1(void *arg) { +#define SHELL_WA_SIZE THD_WA_SIZE(4096) +#define CONSOLE_WA_SIZE THD_WA_SIZE(4096) +#define TEST_WA_SIZE THD_WA_SIZE(4096) - while (TRUE) { - chThdSleepMilliseconds(1000); - printf("-\n"); +#define cprint(msg) chMsgSend(cdtp, (msg_t)msg) + +static Thread *cdtp; +static Thread *shelltp1; +static Thread *shelltp2; + +void cmd_test(BaseChannel *chp, int argc, char *argv[]) { + Thread *tp; + + (void)argv; + if (argc > 0) { + shellPrintLine(chp, "Usage: test"); + return; + } + tp = chThdCreateFromHeap(NULL, TEST_WA_SIZE, chThdGetPriority(), + TestThread, chp); + if (tp == NULL) { + shellPrintLine(chp, "out of memory"); + return; + } + chThdWait(tp); +} + +static const ShellCommand commands[] = { + {"test", cmd_test}, + {NULL, NULL} +}; + +static const ShellConfig shell_cfg1 = { + (BaseChannel *)&SD1, + commands +}; + +static const ShellConfig shell_cfg2 = { + (BaseChannel *)&SD2, + commands +}; + +/* + * 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 console_thread(void *arg) { + + (void)arg; + while (!chThdShouldTerminate()) { + puts((char *)chMsgWait()); + fflush(stdout); + chMsgRelease(RDY_OK); } return 0; } +/** + * @brief Shell termination handler. + * + * @param[in] id event id. + */ +static void termination_handler(eventid_t id) { + + (void)id; + if (shelltp1 && chThdTerminated(shelltp1)) { + chThdWait(shelltp1); + shelltp1 = NULL; + chThdSleepMilliseconds(10); + cprint("Init: shell on SD1 terminated\n"); + chSysLock(); + chOQResetI(&SD1.d2.oqueue); + chSysUnlock(); + } + if (shelltp2 && chThdTerminated(shelltp2)) { + chThdWait(shelltp2); + shelltp2 = NULL; + chThdSleepMilliseconds(10); + cprint("Init: shell on SD2 terminated\n"); + chSysLock(); + chOQResetI(&SD2.d2.oqueue); + chSysUnlock(); + } +} + +/** + * @brief SD1 status change handler. + * + * @param[in] id event id. + */ +static void sd1_handler(eventid_t id) { + + sdflags_t flags; + + (void)id; + flags = sdGetAndClearFlags(&SD1); + if ((flags & SD_CONNECTED) && (shelltp1 == NULL)) { + cprint("Init: connection on SD1\n"); + shelltp1 = shellCreate(&shell_cfg1, SHELL_WA_SIZE, NORMALPRIO + 1); + } + if (flags & SD_DISCONNECTED) { + cprint("Init: disconnection on SD1\n"); + chSysLock(); + chIQResetI(&SD1.d2.iqueue); + chSysUnlock(); + } +} + +/** + * @brief SD2 status change handler. + * + * @param[in] id event id. + */ +static void sd2_handler(eventid_t id) { + + sdflags_t flags; + + (void)id; + flags = sdGetAndClearFlags(&SD2); + if ((flags & SD_CONNECTED) && (shelltp2 == NULL)) { + cprint("Init: connection on SD2\n"); + shelltp2 = shellCreate(&shell_cfg2, SHELL_WA_SIZE, NORMALPRIO + 10); + } + if (flags & SD_DISCONNECTED) { + cprint("Init: disconnection on SD2\n"); + chSysLock(); + chIQResetI(&SD2.d2.iqueue); + chSysUnlock(); + } +} + +static evhandler_t fhandlers[] = { + termination_handler, + sd1_handler, + sd2_handler +}; + /*------------------------------------------------------------------------* - * Simulator main, start here your threads, examples inside. * + * Simulator main. * *------------------------------------------------------------------------*/ int main(void) { + EventListener sd1fel, sd2fel, tel; + + /* + * HAL initialization. + */ + halInit(); /* - * ChibiOS/RT initialization. + * ChibiOS/RT initialization. */ chSysInit(); /* - * Starting threads. + * Serial ports (simulated) initialization. */ - chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); + sdStart(&SD1, NULL); + sdStart(&SD2, NULL); - while (TRUE) - chThdSleepSeconds(1); + /* + * Shell manager initialization. + */ + shellInit(); + chEvtRegister(&shell_terminated, &tel, 0); + /* + * Console thread started. + */ + cdtp = chThdCreateFromHeap(NULL, CONSOLE_WA_SIZE, NORMALPRIO + 1, + console_thread, NULL); + + /* + * Initializing connection/disconnection events. + */ + cprint("Shell service started on SD1, SD2\n"); + cprint(" - Listening for connections on SD1\n"); + (void) sdGetAndClearFlags(&SD1); + chEvtRegister(&SD1.d2.sevent, &sd1fel, 1); + cprint(" - Listening for connections on SD2\n"); + (void) sdGetAndClearFlags(&SD2); + chEvtRegister(&SD2.d2.sevent, &sd2fel, 2); + + /* + * Events servicing loop. + */ + while (!chThdShouldTerminate()) + chEvtDispatch(fhandlers, chEvtWaitOne(ALL_EVENTS)); + + /* + * Clean simulator exit. + */ + chEvtUnregister(&SD1.d2.sevent, &sd1fel); + chEvtUnregister(&SD2.d2.sevent, &sd2fel); return 0; } -- cgit v1.2.3