From a9982beacf184ccdc4bf1221852c900b0809537d Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Mon, 7 Aug 2017 11:33:31 -0400 Subject: [PATCH] sched: Introduce sched_wake_tasks() function to wake up tasks Add function to indicate when tasks need to be run. This will allow the scheduler code to know if there are any tasks that need to be processed. Signed-off-by: Kevin O'Connor --- lib/README | 4 ++- lib/pjrc_usb_serial/usb_serial.c | 12 +++++++-- lib/pjrc_usb_serial/usb_serial.patch | 39 +++++++++++++++++++++++++--- src/avr/serial.c | 3 +++ src/avr/usbserial.c | 4 ++- src/command.c | 2 +- src/pru/main.c | 6 +++-- src/sam3x8e/serial.c | 3 +++ src/sched.c | 10 +++++++ src/sched.h | 1 + 10 files changed, 74 insertions(+), 10 deletions(-) diff --git a/lib/README b/lib/README index 90c38ede..e6bdb7fd 100644 --- a/lib/README +++ b/lib/README @@ -3,7 +3,9 @@ This directory contains external library code. The pjrc_usb_serial directory contains code from: http://www.pjrc.com/teensy/usb_serial.html version 1.7 (extracted on 20160605). It has been modified to compile -on recent versions of gcc. See usb_serial.patch for the modifications. +on recent versions of gcc, to support asynchronous notification of +incoming data, and to not use SOF interrupts. See usb_serial.patch for +the modifications. The cmsis-sam3x8e directory contains code from the Arduino project: https://www.arduino.cc/ diff --git a/lib/pjrc_usb_serial/usb_serial.c b/lib/pjrc_usb_serial/usb_serial.c index ac5bc8a2..0c2488d5 100644 --- a/lib/pjrc_usb_serial/usb_serial.c +++ b/lib/pjrc_usb_serial/usb_serial.c @@ -325,7 +325,7 @@ void usb_init(void) UDCON = 0; // enable attach resistor usb_configuration = 0; cdc_line_rtsdtr = 0; - UDIEN = (1<= sizeof(receive_buf)) // Serial overflow - ignore it as crc error will force retransmit return; @@ -104,6 +106,7 @@ console_pop_input(uint8_t len) memmove(&receive_buf[copied], &receive_buf[copied + len] , needcopy - copied); copied = needcopy; + sched_wake_tasks(); } irqstatus_t flag = irq_save(); if (rpos != readb(&receive_pos)) { diff --git a/src/avr/usbserial.c b/src/avr/usbserial.c index 1b42d6d3..cc7bb12c 100644 --- a/src/avr/usbserial.c +++ b/src/avr/usbserial.c @@ -42,8 +42,10 @@ static void console_pop_input(uint8_t len) { uint8_t needcopy = receive_pos - len; - if (needcopy) + if (needcopy) { memmove(receive_buf, &receive_buf[len], needcopy); + sched_wake_tasks(); + } receive_pos = needcopy; } diff --git a/src/command.c b/src/command.c index 53263a8f..87284ee8 100644 --- a/src/command.c +++ b/src/command.c @@ -11,7 +11,7 @@ #include "board/misc.h" // crc16_ccitt #include "board/pgm.h" // READP #include "command.h" // output_P -#include "sched.h" // DECL_TASK +#include "sched.h" // sched_is_shutdown static uint8_t next_sequence = MESSAGE_DEST; diff --git a/src/pru/main.c b/src/pru/main.c index 3c2a2725..04d440df 100644 --- a/src/pru/main.c +++ b/src/pru/main.c @@ -85,7 +85,10 @@ timer_kick(void) static void _irq_poll(void) { - if (CT_INTC.SECR0 & (1 << IEP_EVENT)) { + uint32_t secr0 = CT_INTC.SECR0; + if (secr0 & (1 << KICK_PRU1_EVENT)) + sched_wake_tasks(); + if (secr0 & (1 << IEP_EVENT)) { CT_IEP.TMR_CMP_STS = 0xff; uint32_t next = timer_dispatch_many(); timer_set(next); @@ -121,7 +124,6 @@ console_task(void) const struct command_parser *cp = SHARED_MEM->next_command; if (!cp) return; - barrier(); if (sched_is_shutdown() && !(cp->flags & HF_IN_SHUTDOWN)) { sched_report_shutdown(); diff --git a/src/sam3x8e/serial.c b/src/sam3x8e/serial.c index 713c6337..7741d6f8 100644 --- a/src/sam3x8e/serial.c +++ b/src/sam3x8e/serial.c @@ -56,6 +56,8 @@ UART_Handler(void) uint32_t status = UART->UART_SR; if (status & UART_SR_RXRDY) { uint8_t data = UART->UART_RHR; + if (data == MESSAGE_SYNC) + sched_wake_tasks(); if (receive_pos >= sizeof(receive_buf)) // Serial overflow - ignore it as crc error will force retransmit return; @@ -94,6 +96,7 @@ console_pop_input(uint32_t len) memmove(&receive_buf[copied], &receive_buf[copied + len] , needcopy - copied); copied = needcopy; + sched_wake_tasks(); } irqstatus_t flag = irq_save(); if (rpos != readl(&receive_pos)) { diff --git a/src/sched.c b/src/sched.c index 0aadcc75..a2f5fea8 100644 --- a/src/sched.c +++ b/src/sched.c @@ -28,6 +28,9 @@ static struct timer sentinel_timer, deleted_timer; static uint_fast8_t periodic_event(struct timer *t) { + // Make sure the stats task runs periodically + sched_wake_tasks(); + // Reschedule timer periodic_timer.waketime += timer_from_us(100000); sentinel_timer.waketime = periodic_timer.waketime + 0x80000000; return SF_RESCHEDULE; @@ -177,10 +180,17 @@ sched_timer_reset(void) * Task waking ****************************************************************/ +// Note that at least one task is ready to run +void +sched_wake_tasks(void) +{ +} + // Note that a task is ready to run void sched_wake_task(struct task_wake *w) { + sched_wake_tasks(); writeb(&w->wake, 1); } diff --git a/src/sched.h b/src/sched.h index bb6bb975..ba883778 100644 --- a/src/sched.h +++ b/src/sched.h @@ -29,6 +29,7 @@ struct task_wake { void sched_add_timer(struct timer*); void sched_del_timer(struct timer *del); unsigned int sched_timer_dispatch(void); +void sched_wake_tasks(void); void sched_wake_task(struct task_wake *w); uint8_t sched_check_wake(struct task_wake *w); uint8_t sched_is_shutdown(void);