diff options
Diffstat (limited to 'demos/GNU-Linux-GCC/main.c')
-rw-r--r-- | demos/GNU-Linux-GCC/main.c | 191 |
1 files changed, 180 insertions, 11 deletions
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 <stdio.h>
#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;
}
|