8000 esp32: Reduce latency for handling of scheduled Python callbacks. · micropython/micropython@14ab81e · GitHub
[go: up one dir, main page]

Skip to content

Commit 14ab81e

Browse files
nickovsdpgeorge
authored andcommitted
esp32: Reduce latency for handling of scheduled Python callbacks.
Prior to this patch there was a large latency for executing scheduled callbacks when when Python code is sleeping: at the heart of the implementation of sleep_ms() is a call to vTaskDelay(1), which always sleeps for one 100Hz tick, before performing another call to MICROPY_EVENT_POLL_HOOK. This patch fixes this issue by using FreeRTOS Task Notifications to signal the main thread that a new callback is pending.
1 parent bccf9d3 commit 14ab81e

File tree

5 files changed

+28
-4
lines changed

5 files changed

+28
-4
lines changed

ports/esp32/machine_pin.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
#include "py/runtime.h"
3535
#include "py/mphal.h"
36+
#include "mphalport.h"
3637
#include "modmachine.h"
3738
#include "extmod/virtpin.h"
3839
#include "machine_rtc.h"
@@ -115,6 +116,7 @@ STATIC void IRAM_ATTR machine_pin_isr_handler(void *arg) {
115116
machine_pin_obj_t *self = arg;
116117
mp_obj_t handler = MP_STATE_PORT(machine_pin_irq_handler)[self->id];
117118
mp_sched_schedule(handler, MP_OBJ_FROM_PTR(self));
119+
mp_hal_wake_main_task_from_isr();
118120
}
119121

120122
gpio_num_t machine_pin_get_id(mp_obj_t pin_in) {

ports/esp32/machine_timer.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "py/obj.h"
3535
#include "py/runtime.h"
3636
#include "modmachine.h"
37+
#include "mphalport.h"
3738

3839
#define TIMER_INTR_SEL TIMER_INTR_LEVEL
3940
#define TIMER_DIVIDER 40000
@@ -109,6 +110,7 @@ STATIC void machine_timer_isr(void *self_in) {
109110
device->hw_timer[self->index].config.alarm_en = self->repeat;
110111

111112
mp_sched_schedule(self->callback, self);
113+
mp_hal_wake_main_task_from_isr();
112114
}
113115

114116
STATIC void machine_timer_enable(machine_timer_obj_t *self) {

ports/esp32/main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ void mp_task(void *pvParameter) {
131131

132132
void app_main(void) {
133133
nvs_flash_init();
134-
xTaskCreateStaticPinnedToCore(mp_task, "mp_task", MP_TASK_STACK_LEN, NULL, MP_TASK_PRIORITY,
135-
&mp_task_stack[0], &mp_task_tcb, 0);
134+
mp_main_task_handle = xTaskCreateStaticPinnedToCore(mp_task, "mp_task", MP_TASK_STACK_LEN, NULL, MP_TASK_PRIORITY,
135+
&mp_task_stack[0], &mp_task_tcb, 0);
136136
}
137137

138138
void nlr_jump_fail(void *val) {

ports/esp32/mphalport.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
#include "py/mphal.h"
3939
#include "extmod/misc.h"
4040
#include "lib/utils/pyexec.h"
41+
#include "mphalport.h"
42+
43+
TaskHandle_t mp_main_task_handle;
4144

4245
STATIC uint8_t stdin_ringbuf_array[256];
4346
ringbuf_t stdin_ringbuf = {stdin_ringbuf_array, sizeof(stdin_ringbuf_array)};
@@ -49,7 +52,7 @@ int mp_hal_stdin_rx_chr(void) {
4952
return c;
5053
}
5154
MICROPY_EVENT_POLL_HOOK
52-
vTaskDelay(1);
55+
ulTaskNotifyTake(pdFALSE, 1);
5356
}
5457
}
5558

@@ -106,7 +109,7 @@ void mp_hal_delay_ms(uint32_t ms) {
106109
break;
107110
}
108111
MICROPY_EVENT_POLL_HOOK
109-
vTaskDelay(1);
112+
ulTaskNotifyTake(pdFALSE, 1);
110113
}
111114
if (dt < us) {
112115
// do the remaining delay accurately
@@ -154,3 +157,12 @@ int *__errno() {
154157
return &mp_stream_errno;
155158
}
156159
*/
160+
161+
// Wake up the main task if it is sleeping
162+
void mp_hal_wake_main_task_from_isr(void) {
163+
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
164+
vTaskNotifyGiveFromISR(mp_main_task_handle, &xHigherPriorityTaskWoken);
165+
if (xHigherPriorityTaskWoken == pdTRUE) {
166+
portYIELD_FROM_ISR();
167+
}
168+
}

ports/esp32/mphalport.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@
3232
#include "py/ringbuf.h"
3333
#include "lib/utils/interrupt_char.h"
3434

35+
#include "freertos/FreeRTOS.h"
36+
#include "freertos/task.h"
37+
38+
extern TaskHandle_t mp_main_task_handle;
39+
3540
extern ringbuf_t stdin_ringbuf;
3641

3742
uint32_t mp_hal_ticks_us(void);
@@ -49,6 +54,9 @@ uint32_t mp_hal_get_cpu_freq(void);
4954
#define mp_hal_quiet_timing_enter() MICROPY_BEGIN_ATOMIC_SECTION()
5055
#define mp_hal_quiet_timing_exit(irq_state) MICROPY_END_ATOMIC_SECTION(irq_state)
5156

57+
// Wake up the main task if it is sleeping
58+
void mp_hal_wake_main_task_from_isr(void);
59+
5260
// C-level pin HAL
5361
#include "py/obj.h"
5462
#include "driver/gpio.h"

0 commit comments

Comments
 (0)
0