From 309b929837ae90447bcf8b0e75c72b540f2d6c38 Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Mon, 10 Mar 2014 22:14:37 +0000 Subject: [PATCH] Fix bug in irq code --- hw2/main.cpp | 79 +++++++++++++++++++++++++----------------------- hw2/serial_irq.c | 25 ++++----------- 2 files changed, 47 insertions(+), 57 deletions(-) diff --git a/hw2/main.cpp b/hw2/main.cpp index aafb879..9292124 100644 --- a/hw2/main.cpp +++ b/hw2/main.cpp @@ -20,17 +20,6 @@ * Time synchronization is performed in both directions. */ -/**************** - * Testing vars * - ****************/ - -uint32_t test_xmt_enab = 0; -uint64_t test_xmt_time0 = 0; -uint64_t test_xmt_time1 = 0; - -uint32_t test_rcv_enab = 0; -uint64_t test_rcv_time = 0; - /******************* * Timer functions * *******************/ @@ -112,7 +101,7 @@ void time_ext_sync(uint64_t local, uint64_t world) world = time_last_world; //#ifdef VERBOSE -#if 0 +#if 1 uint64_t error = world > guess ? world - guess : guess > world ? guess - world : 0; int ahead = guess > world; @@ -150,7 +139,7 @@ static uint64_t emit_start = 0; // transmit start time (world time) static uint64_t emit_period = 0; // transmit period static uint64_t emit_due = 0; // next transmit (world time) -static uint32_t emit_slack = 0; // how far ahead we need to schedule +static uint32_t emit_slack = 0; // how far ahead we need to schedule, in us static uint32_t emit_worst = 0; // worst-case latency in task table void emit_init(int alt, PinName pin, PinMode mode) @@ -190,11 +179,13 @@ void emit_init(int alt, PinName pin, PinMode mode) void emit_enable(uint64_t start, uint64_t period) { + const int slack_tick = 0xC000; // tune based on emit_worst + emit_start = start; emit_period = period; emit_due = start + period; - emit_slack = 10000; // tune based on emit_worst + emit_slack = slack_tick * 1000 / 24; time_printf("emit scheduled", emit_due); } @@ -219,19 +210,17 @@ void emit_schedule(uint64_t when) | TPM_SC_CMOD(1); // Debug - //sirq_printf("emitting event\r\n"); + sirq_printf("emitting event\r\n"); } -void emit_transmit(void) +void emit_transmit(uint64_t local, uint64_t world) { - static uint64_t prev; - - // Get a fresh timestamp - uint64_t world = time_to_world(tdma_time()); + static uint64_t prev = 0; // Record how how much time we have to reschedule - if (prev && world - prev > emit_worst) - emit_worst = prev; + if (prev && (local-prev) > emit_worst) + emit_worst = (local-prev); + prev = local; // Schedule task if needed if (emit_due && emit_period && @@ -319,25 +308,17 @@ void serial_send_sync(sirq_t *port, uint64_t now) tdma_stop(serial_tdma_rcv); - test_xmt_enab = 1; - test_xmt_time0 = 0; - test_xmt_time1 = 0; - tdma_start(serial_tdma_xmt); sirq_write(port, &head, sizeof(head)); sirq_write(port, &body, sizeof(body)); tdma_stop(serial_tdma_xmt); // save transmit time - //local = test_xmt_time1; int valid = tdma_stamp(serial_tdma_xmt, &local); - if (!valid) { + if (!valid) sirq_printf("sync transmit time -- missed\r\n"); - } else { + else //time_printf("sync transmit time ", local); - //time_printf("sync transmit test0", test_xmt_time0); - //time_printf("sync transmit test1", test_xmt_time1); - } tdma_start(serial_tdma_rcv); @@ -380,10 +361,6 @@ void serial_send_event(uint16_t event, uint64_t local) tdma_stop(serial_tdma_rcv); - test_xmt_enab = 1; - test_xmt_time0 = 0; - test_xmt_time1 = 0; - tdma_start(serial_tdma_xmt); sirq_write(port, &head, sizeof(head)); sirq_write(port, &body, sizeof(body)); @@ -612,7 +589,7 @@ void task_leds(uint64_t local, uint64_t world) void task_emit(uint64_t local, uint64_t world) { - emit_transmit(); + emit_transmit(local, world); } void task_debug(uint64_t local, uint64_t world) @@ -730,10 +707,36 @@ int main(int argc, char **argv) //sirq_printf("MGC - C10 %02hx\r\n", MCG->C10); // 00 // Run background loop - printf("hello"); while (true) background(); + // Performance testing + //uint64_t prev = 0, due = 0; + //uint64_t worst[10] = {}; + //int count = 0; + //while (true) { + // uint64_t local = tdma_time(); + // if (prev && (local-prev) > worst[count]) + // worst[count] = (local-prev); + // prev = local; + // if (local > due) { + // if (count == 5) { + // static char str[] = "background background background\r\n"; + // sirq_write(sirq_dbg, str, sizeof(str)); + // } + // if (count == 9) { + // sirq_printf("background\r\n"); + // for (int i = 0; i < 10; i++) { + // sirq_printf(" worst[%d] = 0.%09u\r\n", + // i, worst[i]); + // worst[i] = 0; + // } + // } + // due += NSEC_PER_SEC; + // count = (count + 1) % 10; + // } + //} + // Run tests //test_main(); diff --git a/hw2/serial_irq.c b/hw2/serial_irq.c index 68945cf..e002ce9 100644 --- a/hw2/serial_irq.c +++ b/hw2/serial_irq.c @@ -20,16 +20,9 @@ struct sirq_t { serial_t uart; queue_t xmt; queue_t rcv; + int irq; }; -/* Test data */ -extern uint32_t test_xmt_enab; -extern uint64_t test_xmt_time0; -extern uint64_t test_xmt_time1; - -extern uint32_t test_rcv_enab; -extern uint64_t test_rcv_time; - /* Port data */ static sirq_t sirq_ports[SIRQ_NUM_UART]; @@ -41,20 +34,11 @@ void sirq_handler(uint32_t _port, SerialIrq event) // Handle transmit if (event == TxIrq && port->xmt.rix != port->xmt.wix) { int byte = port->xmt.buf[port->xmt.rix]; - - uint64_t time0 = tdma_time(); serial_putc(&port->uart, byte); - uint64_t time1 = tdma_time(); - - if (test_xmt_enab) { - test_xmt_time0 = time0; - test_xmt_time1 = time1; - test_xmt_enab = 0; - } - port->xmt.rix = (port->xmt.rix+1) % SIRQ_LEN; } else { serial_irq_set(&port->uart, TxIrq, 0); + port->irq = 0; } // Handle receive @@ -87,7 +71,10 @@ void sirq_putc(sirq_t *port, int byte) { port->xmt.buf[port->xmt.wix] = byte; port->xmt.wix = (port->xmt.wix+1) % SIRQ_LEN; - serial_irq_set(&port->uart, TxIrq, 1); + if (!port->irq) { + port->irq = 1; + serial_irq_set(&port->uart, TxIrq, 1); + } } /* Read byte from the port */ -- 2.43.2