supervisor: factor supervisor_background_tasks from sundry ports

This commit is contained in:
Jeff Epler 2020-07-13 10:33:58 -05:00
parent 6160d11c5a
commit 1df48176ce
21 changed files with 95 additions and 261 deletions

2
main.c
View File

@ -101,8 +101,6 @@ void start_mp(supervisor_allocation* heap) {
reset_status_led(); reset_status_led();
autoreload_stop(); autoreload_stop();
background_tasks_reset();
// Stack limit should be less than real stack size, so we have a chance // Stack limit should be less than real stack size, so we have a chance
// to recover from limit hit. (Limit is measured in bytes.) // to recover from limit hit. (Limit is measured in bytes.)
mp_stack_ctrl_init(); mp_stack_ctrl_init();

View File

@ -39,59 +39,21 @@
#include "shared-module/displayio/__init__.h" #include "shared-module/displayio/__init__.h"
#endif #endif
volatile uint64_t last_finished_tick = 0;
bool stack_ok_so_far = true;
static bool running_background_tasks = false;
#ifdef MONITOR_BACKGROUND_TASKS #ifdef MONITOR_BACKGROUND_TASKS
// PB03 is physical pin "SCL" on the Metro M4 express // PB03 is physical pin "SCL" on the Metro M4 express
// so you can't use this code AND an i2c peripheral // so you can't use this code AND an i2c peripheral
// at the same time unless you change this // at the same time unless you change this
STATIC void start_background_task(void) { void port_start_background_task(void) {
REG_PORT_DIRSET1 = (1<<3); REG_PORT_DIRSET1 = (1<<3);
REG_PORT_OUTSET1 = (1<<3); REG_PORT_OUTSET1 = (1<<3);
} }
STATIC void finish_background_task(void) { void port_finish_background_task(void) {
REG_PORT_OUTCLR1 = (1<<3); REG_PORT_OUTCLR1 = (1<<3);
} }
#else #else
STATIC void start_background_task(void) {} void port_start_background_task(void) {}
STATIC void finish_background_task(void) {} void port_finish_background_task(void) {}
#endif #endif
void background_tasks_reset(void) { void port_background_task(void) {}
running_background_tasks = false;
}
void run_background_tasks(void) {
// Don't call ourselves recursively.
if (running_background_tasks) {
return;
}
start_background_task();
assert_heap_ok();
running_background_tasks = true;
#if CIRCUITPY_DISPLAYIO
displayio_background();
#endif
#if CIRCUITPY_NETWORK
network_module_background();
#endif
filesystem_background();
running_background_tasks = false;
assert_heap_ok();
last_finished_tick = port_get_raw_ticks(NULL);
finish_background_task();
}
bool background_tasks_ok(void) {
return port_get_raw_ticks(NULL) - last_finished_tick < 1024;
}

View File

@ -29,9 +29,4 @@
#include <stdbool.h> #include <stdbool.h>
void background_tasks_reset(void);
void run_background_tasks(void);
void run_background_vm_tasks(void);
bool background_tasks_ok(void);
#endif // MICROPY_INCLUDED_ATMEL_SAMD_BACKGROUND_H #endif // MICROPY_INCLUDED_ATMEL_SAMD_BACKGROUND_H

View File

@ -46,6 +46,7 @@
#include "hpl_gclk_config.h" #include "hpl_gclk_config.h"
#include "shared-bindings/time/__init__.h" #include "shared-bindings/time/__init__.h"
#include "supervisor/shared/tick.h"
#include "supervisor/shared/translate.h" #include "supervisor/shared/translate.h"
#ifdef SAMD21 #ifdef SAMD21
@ -132,7 +133,7 @@ void frequencyin_interrupt_handler(uint8_t index) {
} }
// Check if we've reached the upper limit of detection // Check if we've reached the upper limit of detection
if (!background_tasks_ok() || self->errored_too_fast) { if (!supervisor_background_tasks_ok() || self->errored_too_fast) {
self->errored_too_fast = true; self->errored_too_fast = true;
frequencyin_emergency_cancel_capture(i); frequencyin_emergency_cancel_capture(i);
} }

View File

@ -42,6 +42,7 @@
#include "samd/timers.h" #include "samd/timers.h"
#include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/pulseio/PulseIn.h" #include "shared-bindings/pulseio/PulseIn.h"
#include "supervisor/shared/tick.h"
#include "supervisor/shared/translate.h" #include "supervisor/shared/translate.h"
// This timer is shared amongst all PulseIn objects as a higher resolution clock. // This timer is shared amongst all PulseIn objects as a higher resolution clock.
@ -87,7 +88,7 @@ void pulsein_interrupt_handler(uint8_t channel) {
uint32_t current_count = tc->COUNT16.COUNT.reg; uint32_t current_count = tc->COUNT16.COUNT.reg;
pulseio_pulsein_obj_t* self = get_eic_channel_data(channel); pulseio_pulsein_obj_t* self = get_eic_channel_data(channel);
if (!background_tasks_ok() || self->errored_too_fast) { if (!supervisor_background_tasks_ok() || self->errored_too_fast) {
self->errored_too_fast = true; self->errored_too_fast = true;
common_hal_pulseio_pulsein_pause(self); common_hal_pulseio_pulsein_pause(self);
return; return;

View File

@ -30,24 +30,6 @@
#include "supervisor/filesystem.h" #include "supervisor/filesystem.h"
#include "supervisor/shared/stack.h" #include "supervisor/shared/stack.h"
static bool running_background_tasks = false; void port_background_task(void) {}
void port_start_background_task(void) {}
void background_tasks_reset(void) { void port_finish_background_task(void) {}
running_background_tasks = false;
}
void run_background_tasks(void) {
// Don't call ourselves recursively.
if (running_background_tasks) {
return;
}
assert_heap_ok();
running_background_tasks = true;
usb_background();
filesystem_background();
running_background_tasks = false;
assert_heap_ok();
}

View File

@ -27,7 +27,4 @@
#ifndef MICROPY_INCLUDED_CXD56_BACKGROUND_H #ifndef MICROPY_INCLUDED_CXD56_BACKGROUND_H
#define MICROPY_INCLUDED_CXD56_BACKGROUND_H #define MICROPY_INCLUDED_CXD56_BACKGROUND_H
void background_tasks_reset(void);
void run_background_tasks(void);
#endif // MICROPY_INCLUDED_CXD56_BACKGROUND_H #endif // MICROPY_INCLUDED_CXD56_BACKGROUND_H

View File

@ -35,27 +35,12 @@
#include "shared-module/displayio/__init__.h" #include "shared-module/displayio/__init__.h"
#endif #endif
static bool running_background_tasks = false;
void background_tasks_reset(void) {
running_background_tasks = false;
}
void run_background_tasks(void) {
// Don't call ourselves recursively.
if (running_background_tasks) {
return;
}
void port_background_task(void) {
// Zero delay in case FreeRTOS wants to switch to something else. // Zero delay in case FreeRTOS wants to switch to something else.
vTaskDelay(0); vTaskDelay(0);
running_background_tasks = true;
filesystem_background();
#if CIRCUITPY_DISPLAYIO
displayio_background();
#endif
running_background_tasks = false;
assert_heap_ok();
} }
void port_start_background_task(void) {}
void port_finish_background_task(void) {}

View File

@ -29,7 +29,4 @@
#include <stdbool.h> #include <stdbool.h>
void background_tasks_reset(void);
void run_background_tasks(void);
#endif // MICROPY_INCLUDED_ESP32S2_BACKGROUND_H #endif // MICROPY_INCLUDED_ESP32S2_BACKGROUND_H

View File

@ -29,32 +29,6 @@
#include "supervisor/usb.h" #include "supervisor/usb.h"
#include "supervisor/shared/stack.h" #include "supervisor/shared/stack.h"
#if CIRCUITPY_DISPLAYIO void port_background_task(void) {}
#include "shared-module/displayio/__init__.h" void port_start_background_task(void) {}
#endif void port_finish_background_task(void) {}
static bool running_background_tasks = false;
void background_tasks_reset(void) {
running_background_tasks = false;
}
void run_background_tasks(void) {
// Don't call ourselves recursively.
if (running_background_tasks) {
return;
}
running_background_tasks = true;
filesystem_background();
#if USB_AVAILABLE
usb_background();
#endif
#if CIRCUITPY_DISPLAYIO
displayio_background();
#endif
running_background_tasks = false;
assert_heap_ok();
}

View File

@ -27,9 +27,4 @@
#ifndef MICROPY_INCLUDED_LITEX_BACKGROUND_H #ifndef MICROPY_INCLUDED_LITEX_BACKGROUND_H
#define MICROPY_INCLUDED_LITEX_BACKGROUND_H #define MICROPY_INCLUDED_LITEX_BACKGROUND_H
#include <stdbool.h>
void background_tasks_reset(void);
void run_background_tasks(void);
#endif // MICROPY_INCLUDED_LITEX_BACKGROUND_H #endif // MICROPY_INCLUDED_LITEX_BACKGROUND_H

View File

@ -24,58 +24,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include "background.h"
//#include "audio_dma.h" #include "supervisor/port.h"
#include "supervisor/filesystem.h"
#include "supervisor/shared/tick.h"
#include "supervisor/usb.h"
#include "py/runtime.h"
#include "shared-module/network/__init__.h"
#include "supervisor/linker.h"
#include "supervisor/shared/stack.h"
#ifdef CIRCUITPY_DISPLAYIO
#include "shared-module/displayio/__init__.h"
#endif
volatile uint64_t last_finished_tick = 0;
bool stack_ok_so_far = true;
static bool running_background_tasks = false;
void background_tasks_reset(void) {
running_background_tasks = false;
}
void PLACE_IN_ITCM(run_background_tasks)(void) {
// Don't call ourselves recursively.
if (running_background_tasks) {
return;
}
assert_heap_ok();
running_background_tasks = true;
void port_background_task(void) {
#if CIRCUITPY_AUDIOIO || CIRCUITPY_AUDIOBUSIO #if CIRCUITPY_AUDIOIO || CIRCUITPY_AUDIOBUSIO
audio_dma_background(); audio_dma_background();
#endif #endif
#if CIRCUITPY_DISPLAYIO
displayio_background();
#endif
#if CIRCUITPY_NETWORK
network_module_background();
#endif
filesystem_background();
usb_background();
running_background_tasks = false;
assert_heap_ok();
last_finished_tick = supervisor_ticks_ms64();
}
bool background_tasks_ok(void) {
return supervisor_ticks_ms64() - last_finished_tick < 1000;
} }
void port_start_background_task(void) {}
void port_finish_background_task(void) {}

View File

@ -28,11 +28,4 @@
#ifndef MICROPY_INCLUDED_MIMXRT10XX_BACKGROUND_H #ifndef MICROPY_INCLUDED_MIMXRT10XX_BACKGROUND_H
#define MICROPY_INCLUDED_MIMXRT10XX_BACKGROUND_H #define MICROPY_INCLUDED_MIMXRT10XX_BACKGROUND_H
#include <stdbool.h>
void background_tasks_reset(void);
void run_background_tasks(void);
void run_background_vm_tasks(void);
bool background_tasks_ok(void);
#endif // MICROPY_INCLUDED_MIMXRT10XX_BACKGROUND_H #endif // MICROPY_INCLUDED_MIMXRT10XX_BACKGROUND_H

View File

@ -64,7 +64,7 @@
// // last ms. // // last ms.
// current_us = 1000 - current_us; // current_us = 1000 - current_us;
// pulseio_pulsein_obj_t* self = get_eic_channel_data(channel); // pulseio_pulsein_obj_t* self = get_eic_channel_data(channel);
// if (!background_tasks_ok() || self->errored_too_fast) { // if (!supervisor_background_tasks_ok() || self->errored_too_fast) {
// self->errored_too_fast = true; // self->errored_too_fast = true;
// common_hal_pulseio_pulsein_pause(self); // common_hal_pulseio_pulsein_pause(self);
// return; // return;

View File

@ -46,35 +46,14 @@
#include "common-hal/_bleio/bonding.h" #include "common-hal/_bleio/bonding.h"
#endif #endif
static bool running_background_tasks = false; void port_start_background_task(void) {}
void port_finish_background_task(void) {}
void background_tasks_reset(void) { void port_background_task(void) {
running_background_tasks = false;
}
void run_background_tasks(void) {
// Don't call ourselves recursively.
if (running_background_tasks) {
return;
}
running_background_tasks = true;
filesystem_background();
#if CIRCUITPY_AUDIOPWMIO #if CIRCUITPY_AUDIOPWMIO
audiopwmout_background(); audiopwmout_background();
#endif #endif
#if CIRCUITPY_AUDIOBUSIO #if CIRCUITPY_AUDIOBUSIO
i2s_background(); i2s_background();
#endif #endif
#if CIRCUITPY_BLEIO
supervisor_bluetooth_background();
bonding_background();
#endif
#if CIRCUITPY_DISPLAYIO
displayio_background();
#endif
running_background_tasks = false;
assert_heap_ok();
} }

View File

@ -27,9 +27,4 @@
#ifndef MICROPY_INCLUDED_NRF_BACKGROUND_H #ifndef MICROPY_INCLUDED_NRF_BACKGROUND_H
#define MICROPY_INCLUDED_NRF_BACKGROUND_H #define MICROPY_INCLUDED_NRF_BACKGROUND_H
#include <stdbool.h>
void background_tasks_reset(void);
void run_background_tasks(void);
#endif // MICROPY_INCLUDED_NRF_BACKGROUND_H #endif // MICROPY_INCLUDED_NRF_BACKGROUND_H

View File

@ -33,28 +33,6 @@
#include "shared-module/displayio/__init__.h" #include "shared-module/displayio/__init__.h"
#endif #endif
static bool running_background_tasks = false; void port_background_task(void) {}
void port_start_background_task(void) {}
void background_tasks_reset(void) { void port_finish_background_task(void) {}
running_background_tasks = false;
}
void run_background_tasks(void) {
// Don't call ourselves recursively.
if (running_background_tasks) {
return;
}
running_background_tasks = true;
filesystem_background();
#if USB_AVAILABLE
usb_background();
#endif
#if CIRCUITPY_DISPLAYIO
displayio_background();
#endif
running_background_tasks = false;
assert_heap_ok();
}

View File

@ -27,9 +27,4 @@
#ifndef MICROPY_INCLUDED_STM32_BACKGROUND_H #ifndef MICROPY_INCLUDED_STM32_BACKGROUND_H
#define MICROPY_INCLUDED_STM32_BACKGROUND_H #define MICROPY_INCLUDED_STM32_BACKGROUND_H
#include <stdbool.h>
void background_tasks_reset(void);
void run_background_tasks(void);
#endif // MICROPY_INCLUDED_STM32_BACKGROUND_H #endif // MICROPY_INCLUDED_STM32_BACKGROUND_H

View File

@ -91,4 +91,12 @@ void port_interrupt_after_ticks(uint32_t ticks);
// Sleep the CPU until an interrupt is received. // Sleep the CPU until an interrupt is received.
void port_sleep_until_interrupt(void); void port_sleep_until_interrupt(void);
// Execute port specific actions during background tasks.
void port_background_task(void);
// Take port specific actions at the beginning and end of background tasks.
// This is used e.g., to set a monitoring pin for debug purposes. "Actual
// work" should be done in port_background_task() instead.
void port_start_background_task(void);
void port_finish_background_task(void);
#endif // MICROPY_INCLUDED_SUPERVISOR_PORT_H #endif // MICROPY_INCLUDED_SUPERVISOR_PORT_H

View File

@ -32,8 +32,16 @@
#include "supervisor/background_callback.h" #include "supervisor/background_callback.h"
#include "supervisor/port.h" #include "supervisor/port.h"
#include "supervisor/shared/autoreload.h" #include "supervisor/shared/autoreload.h"
#include "supervisor/shared/stack.h"
static volatile uint64_t PLACE_IN_DTCM_BSS(background_ticks); #if CIRCUITPY_BLEIO
#include "supervisor/shared/bluetooth.h"
#include "common-hal/_bleio/bonding.h"
#endif
#if CIRCUITPY_DISPLAYIO
#include "shared-module/displayio/__init__.h"
#endif
#if CIRCUITPY_GAMEPAD #if CIRCUITPY_GAMEPAD
#include "shared-module/gamepad/__init__.h" #include "shared-module/gamepad/__init__.h"
@ -43,6 +51,10 @@ static volatile uint64_t PLACE_IN_DTCM_BSS(background_ticks);
#include "shared-module/gamepadshift/__init__.h" #include "shared-module/gamepadshift/__init__.h"
#endif #endif
#if CIRCUITPY_NETWORK
#include "shared-module/network/__init__.h"
#endif
#include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/__init__.h"
#if CIRCUITPY_WATCHDOG #if CIRCUITPY_WATCHDOG
@ -52,12 +64,42 @@ static volatile uint64_t PLACE_IN_DTCM_BSS(background_ticks);
#define WATCHDOG_EXCEPTION_CHECK() 0 #define WATCHDOG_EXCEPTION_CHECK() 0
#endif #endif
static volatile uint64_t PLACE_IN_DTCM_BSS(background_ticks);
static background_callback_t callback; static background_callback_t callback;
extern void run_background_tasks(void); volatile uint64_t last_finished_tick = 0;
void background_task_tick(void *unused) { void supervisor_background_tasks(void *unused) {
run_background_tasks(); port_start_background_task();
assert_heap_ok();
#if CIRCUITPY_DISPLAYIO
displayio_background();
#endif
#if CIRCUITPY_NETWORK
network_module_background();
#endif
filesystem_background();
#if CIRCUITPY_BLEIO
supervisor_bluetooth_background();
bonding_background();
#endif
port_background_task();
assert_heap_ok();
last_finished_tick = port_get_raw_ticks(NULL);
port_finish_background_task();
}
bool supervisor_background_tasks_ok(void) {
return port_get_raw_ticks(NULL) - last_finished_tick < 1024;
} }
void supervisor_tick(void) { void supervisor_tick(void) {
@ -77,7 +119,7 @@ void supervisor_tick(void) {
#endif #endif
} }
#endif #endif
background_callback_add(&callback, background_task_tick, NULL); background_callback_add(&callback, supervisor_background_tasks, NULL);
} }
uint64_t supervisor_ticks_ms64() { uint64_t supervisor_ticks_ms64() {

View File

@ -28,6 +28,7 @@
#define __INCLUDED_SUPERVISOR_TICK_H #define __INCLUDED_SUPERVISOR_TICK_H
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
/** @brief To be called once every ms /** @brief To be called once every ms
* *
@ -36,13 +37,6 @@
* interrupt context. * interrupt context.
*/ */
extern void supervisor_tick(void); extern void supervisor_tick(void);
/** @brief Cause background tasks to be called soon
*
* Normally, background tasks are only run once per tick. For other cases where
* an event noticed from an interrupt context needs to be completed by a background
* task activity, the interrupt can call supervisor_fake_tick.
*/
extern void supervisor_fake_tick(void);
/** @brief Get the lower 32 bits of the time in milliseconds /** @brief Get the lower 32 bits of the time in milliseconds
* *
* This can be more efficient than supervisor_ticks_ms64, for sites where a wraparound * This can be more efficient than supervisor_ticks_ms64, for sites where a wraparound
@ -67,4 +61,12 @@ extern void supervisor_run_background_if_tick(void);
extern void supervisor_enable_tick(void); extern void supervisor_enable_tick(void);
extern void supervisor_disable_tick(void); extern void supervisor_disable_tick(void);
/**
* @brief Return true if tick-based background tasks ran within the last 1s
*
* Note that when ticks are not enabled, this function can return false; this is
* intended.
*/
extern bool supervisor_background_tasks_ok(void);
#endif #endif