beep when GPS ready
[protos/xbee-avr.git] / cmdline.c
index 736fa52..568dcad 100644 (file)
--- a/cmdline.c
+++ b/cmdline.c
 #include "main.h"
 #include "cmdline.h"
 
+#define FLUSH_LOGS_MS 1000 /* every second */
+#define LOG_PER_SEC_MAX 10
 
 extern const parse_ctx_t PROGMEM main_ctx[];
 
+static struct callout flush_log_timer;
+static uint8_t log_count;
 
 int cmdline_dev_send(char c, FILE* f)
 {
@@ -108,13 +112,6 @@ void cmdline_write_char(char c)
 }
 
 
-void cmdline_init(void)
-{
-       rdline_init(&xbeeboard.rdl, cmdline_write_char, cmdline_valid_buffer, complete_buffer);
-       snprintf_P(xbeeboard.prompt, sizeof(xbeeboard.prompt), PSTR("mainboard > "));
-}
-
-
 /* sending "pop" on cmdline uart resets the robot */
 void emergency(char c)
 {
@@ -132,8 +129,7 @@ void emergency(char c)
        }
 }
 
-/* log function, add a command to configure
- * it dynamically */
+/* log function, configured dynamically */
 void mylog(struct error * e, ...)
 {
 #ifndef HOST_VERSION
@@ -142,7 +138,13 @@ void mylog(struct error * e, ...)
        va_list ap;
        uint8_t i, flags;
        uint32_t ms;
+       uint8_t prio;
 
+       /* too many logs */
+       if (log_count >= LOG_PER_SEC_MAX)
+               return;
+
+       /* higher log value means lower criticity */
        if (e->severity > ERROR_SEVERITY_ERROR) {
                if (xbeeboard.log_level < e->severity)
                        return;
@@ -154,21 +156,42 @@ void mylog(struct error * e, ...)
                        return;
        }
 
-       va_start(ap, e);
+       /* get time */
        IRQ_LOCK(flags);
        ms = global_ms;
        IRQ_UNLOCK(flags);
 
-       printf_P(PSTR("%d.%.3d: "), (int)(ms/1000UL), (int)(ms%1000UL));
+       /* prevent flush log to occur */
+       prio = callout_mgr_set_prio(&xbeeboard.intr_cm,
+               LOW_PRIO);
 
+       /* display the log */
+       va_start(ap, e);
+       printf_P(PSTR("%d.%.3d: "), (int)(ms/1000UL), (int)(ms%1000UL));
        vfprintf_P(stdout, e->text, ap);
        printf_P(PSTR("\r\n"));
        va_end(ap);
+
 #ifndef HOST_VERSION
        stdout->flags = stream_flags;
 #endif
+       callout_mgr_restore_prio(&xbeeboard.intr_cm, prio);
+}
+
+static void flush_logs_cb(struct callout_mgr *cm, struct callout *tim,
+       void *arg)
+{
+       (void)cm;
+       (void)tim;
+       (void)arg;
+
+       if (log_count == LOG_PER_SEC_MAX)
+               printf_P("some logs were dropped\n");
+       callout_reschedule(&xbeeboard.intr_cm, &flush_log_timer,
+               FLUSH_LOGS_MS);
 }
 
+
 int cmdline_poll(void)
 {
        const char *history, *buffer;
@@ -199,3 +222,15 @@ int cmdline_poll(void)
        return 0;
 }
 
+void cmdline_init(void)
+{
+       /* init command line */
+       rdline_init(&xbeeboard.rdl, cmdline_write_char, cmdline_valid_buffer,
+               complete_buffer);
+       snprintf_P(xbeeboard.prompt, sizeof(xbeeboard.prompt),
+               PSTR("mainboard > "));
+
+       /* load a timer for flushing logs */
+       callout_init(&flush_log_timer, flush_logs_cb, NULL, LOW_PRIO);
+       callout_schedule(&xbeeboard.intr_cm, &flush_log_timer, FLUSH_LOGS_MS);
+}