@@ -42,12 +42,25 @@ wifi_radio_obj_t common_hal_wifi_radio_obj;
4242
4343#include "components/log/include/esp_log.h"
4444
45+ #include "supervisor/port.h"
4546#include "supervisor/workflow.h"
4647
48+ #include "esp_ipc.h"
49+
4750static const char * TAG = "CP wifi" ;
4851
52+ STATIC void schedule_background_on_cp_core (void * arg ) {
53+ supervisor_workflow_request_background ();
54+
55+ // CircuitPython's VM is run in a separate FreeRTOS task from wifi callbacks. So, we have to
56+ // notify the main task every time in case it's waiting for us.
57+ port_wake_main_task ();
58+ }
59+
4960static void event_handler (void * arg , esp_event_base_t event_base ,
5061 int32_t event_id , void * event_data ) {
62+ // This runs on the PRO CORE! It cannot share CP interrupt enable/disable
63+ // directly.
5164 wifi_radio_obj_t * radio = arg ;
5265 if (event_base == WIFI_EVENT ) {
5366 switch (event_id ) {
@@ -108,7 +121,14 @@ static void event_handler(void *arg, esp_event_base_t event_base,
108121 radio -> retries_left = radio -> starting_retries ;
109122 xEventGroupSetBits (radio -> event_group_handle , WIFI_CONNECTED_BIT );
110123 }
111- supervisor_workflow_request_background ();
124+ // Use IPC to ensure we run schedule background on the same core as CircuitPython.
125+ #if defined(CONFIG_FREERTOS_UNICORE ) && CONFIG_FREERTOS_UNICORE
126+ schedule_background_on_cp_core (NULL );
127+ #else
128+ // This only blocks until the start of the function. That's ok since the PRO
129+ // core shouldn't care what we do.
130+ esp_ipc_call (CONFIG_ESP_MAIN_TASK_AFFINITY , schedule_background_on_cp_core , NULL );
131+ #endif
112132}
113133
114134static bool wifi_inited ;
0 commit comments