summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmir Gonnen <amirgonnen@gmail.com>2019-07-22 22:59:55 +0300
committerDamien George <damien.p.george@gmail.com>2019-07-25 15:33:47 +1000
commit995f9cfdfcda96698c63de7a707981ef8bf2cecc (patch)
tree7829582ed7405acd43e35373fc968345ed7c08b3
parente3e7e3a781addf8743b783b9f1d464448f1c94bb (diff)
esp32: Pin MicroPython tasks to a specific core.
On this port the GIL is enabled and everything works under the assumption of the GIL, ie that a given task has exclusive access to the uPy state, and any ISRs interrupt the current task and therefore the ISR inherits exclusive access to the uPy state for the duration of its execution. If the MicroPython tasks are not pinned to a specific core then an ISR may be executed on a different core to the task, making it possible for the main task and an ISR to execute in parallel, breaking the assumption of the GIL. The easiest and safest fix for this is to pin all MicroPython related code to the same CPU core, as done by this patch. Then any ISR that accesses MicroPython state must be registered from a MicroPython task, to ensure it is invoked on the same core. See issue #4895.
-rw-r--r--ports/esp32/main.c2
-rw-r--r--ports/esp32/mphalport.h3
-rw-r--r--ports/esp32/mpthreadport.c5
-rw-r--r--ports/esp32/network_ppp.c2
4 files changed, 7 insertions, 5 deletions
diff --git a/ports/esp32/main.c b/ports/esp32/main.c
index d4f79646f..c8dde337c 100644
--- a/ports/esp32/main.c
+++ b/ports/esp32/main.c
@@ -151,7 +151,7 @@ soft_reset:
void app_main(void) {
nvs_flash_init();
- xTaskCreate(mp_task, "mp_task", MP_TASK_STACK_LEN, NULL, MP_TASK_PRIORITY, &mp_main_task_handle);
+ xTaskCreatePinnedToCore(mp_task, "mp_task", MP_TASK_STACK_LEN, NULL, MP_TASK_PRIORITY, &mp_main_task_handle, MP_TASK_COREID);
}
void nlr_jump_fail(void *val) {
diff --git a/ports/esp32/mphalport.h b/ports/esp32/mphalport.h
index ff39b7aa1..575cdbe72 100644
--- a/ports/esp32/mphalport.h
+++ b/ports/esp32/mphalport.h
@@ -35,6 +35,9 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
+// The core that the MicroPython task(s) are pinned to
+#define MP_TASK_COREID (1)
+
extern TaskHandle_t mp_main_task_handle;
extern ringbuf_t stdin_ringbuf;
diff --git a/ports/esp32/mpthreadport.c b/ports/esp32/mpthreadport.c
index 6c4ed9b5e..9557d4071 100644
--- a/ports/esp32/mpthreadport.c
+++ b/ports/esp32/mpthreadport.c
@@ -27,10 +27,9 @@
#include "stdio.h"
-#include "py/mpconfig.h"
-#include "py/mpstate.h"
#include "py/gc.h"
#include "py/mpthread.h"
+#include "py/mphal.h"
#include "mpthreadport.h"
#include "esp_task.h"
@@ -130,7 +129,7 @@ void mp_thread_create_ex(void *(*entry)(void*), void *arg, size_t *stack_size, i
mp_thread_mutex_lock(&thread_mutex, 1);
// create thread
- BaseType_t result = xTaskCreate(freertos_entry, name, *stack_size / sizeof(StackType_t), arg, priority, &th->id);
+ BaseType_t result = xTaskCreatePinnedToCore(freertos_entry, name, *stack_size / sizeof(StackType_t), arg, priority, &th->id, MP_TASK_COREID);
if (result != pdPASS) {
mp_thread_mutex_unlock(&thread_mutex);
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "can't create thread"));
diff --git a/ports/esp32/network_ppp.c b/ports/esp32/network_ppp.c
index 806540915..aca4bbc1e 100644
--- a/ports/esp32/network_ppp.c
+++ b/ports/esp32/network_ppp.c
@@ -133,7 +133,7 @@ STATIC mp_obj_t ppp_active(size_t n_args, const mp_obj_t *args) {
ppp_set_usepeerdns(self->pcb, 1);
pppapi_connect(self->pcb, 0);
- xTaskCreate(pppos_client_task, "ppp", 2048, self, 1, (TaskHandle_t*)&self->client_task_handle);
+ xTaskCreatePinnedToCore(pppos_client_task, "ppp", 2048, self, 1, (TaskHandle_t*)&self->client_task_handle, MP_TASK_COREID);
self->active = true;
} else {
if (!self->active) {