Fix auto-wifi created crash

The wifi event_handler runs on the other core so we need to be
careful when calling into CP APIs.

Fixes #6503
This commit is contained in:
Scott Shawcroft 2022-06-29 11:53:10 -07:00
parent a055113ed5
commit 8dc8265275
No known key found for this signature in database
GPG Key ID: 0DFD512649C052DA
2 changed files with 24 additions and 4 deletions

View File

@ -65,6 +65,7 @@ volatile uint32_t nesting_count = 0;
static portMUX_TYPE cp_mutex = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE cp_mutex = portMUX_INITIALIZER_UNLOCKED;
void common_hal_mcu_disable_interrupts(void) { void common_hal_mcu_disable_interrupts(void) {
assert(xPortGetCoreID() == CONFIG_ESP_MAIN_TASK_AFFINITY);
if (nesting_count == 0) { if (nesting_count == 0) {
portENTER_CRITICAL(&cp_mutex); portENTER_CRITICAL(&cp_mutex);
} }
@ -72,9 +73,8 @@ void common_hal_mcu_disable_interrupts(void) {
} }
void common_hal_mcu_enable_interrupts(void) { void common_hal_mcu_enable_interrupts(void) {
if (nesting_count == 0) { assert(xPortGetCoreID() == CONFIG_ESP_MAIN_TASK_AFFINITY);
// Maybe log here because it's very bad. assert(nesting_count > 0);
}
nesting_count--; nesting_count--;
if (nesting_count > 0) { if (nesting_count > 0) {
return; return;

View File

@ -42,12 +42,25 @@ wifi_radio_obj_t common_hal_wifi_radio_obj;
#include "components/log/include/esp_log.h" #include "components/log/include/esp_log.h"
#include "supervisor/port.h"
#include "supervisor/workflow.h" #include "supervisor/workflow.h"
#include "esp_ipc.h"
static const char *TAG = "wifi"; static const char *TAG = "wifi";
STATIC void schedule_background_on_cp_core(void *arg) {
supervisor_workflow_request_background();
// CircuitPython's VM is run in a separate FreeRTOS task from wifi callbacks. So, we have to
// notify the main task every time in case it's waiting for us.
port_wake_main_task();
}
static void event_handler(void *arg, esp_event_base_t event_base, static void event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data) { int32_t event_id, void *event_data) {
// This runs on the PRO CORE! It cannot share CP interrupt enable/disable
// directly.
wifi_radio_obj_t *radio = arg; wifi_radio_obj_t *radio = arg;
if (event_base == WIFI_EVENT) { if (event_base == WIFI_EVENT) {
switch (event_id) { switch (event_id) {
@ -108,7 +121,14 @@ static void event_handler(void *arg, esp_event_base_t event_base,
radio->retries_left = radio->starting_retries; radio->retries_left = radio->starting_retries;
xEventGroupSetBits(radio->event_group_handle, WIFI_CONNECTED_BIT); xEventGroupSetBits(radio->event_group_handle, WIFI_CONNECTED_BIT);
} }
supervisor_workflow_request_background(); // Use IPC to ensure we run schedule background on the same core as CircuitPython.
#if defined(CONFIG_FREERTOS_UNICORE) && CONFIG_FREERTOS_UNICORE
schedule_background_on_cp_core(NULL);
#else
// This only blocks until the start of the function. That's ok since the PRO
// core shouldn't care what we do.
esp_ipc_call(CONFIG_ESP_MAIN_TASK_AFFINITY, schedule_background_on_cp_core, NULL);
#endif
} }
static bool wifi_inited; static bool wifi_inited;