Register / Login  |  Desktop view  |  Jump to bottom of page

IoAbstraction & TaskManagerIO » TaskManagerIO specifying a core for a task on ESP32

Author: dobrien32
12/02/2021 02:02:23
I have an ESP32 running IO reading, processing and writing functions using TaskManagerIO and the IoAbstraction libraries which have been fantastic.
If I understand correctly all these tasks will be running on one default core of the ESP32 (say core 1)
I have now added a serial interface and would like it to run on the other core (say core 0) of ESP32 so as to isolate interface handling from the real-time functions.
Does anyone have suggestions on an appropriate way for this is done with or alongside TaskManagerIO?

// tasks to run on core 1
            taskManager.scheduleFixedRate(FAST_UPDATE_INTERVAL, [] {
                updateRelays();
            }, TIME_MILLIS);

            taskManager.scheduleFixedRate(ANALOG_ALARM_UPDATE_INTERVAL, [] {
                processAnalogAlarms();
            }, TIME_MILLIS);

            taskManager.scheduleFixedRate(LED_UPDATE_INTERVAL, [] {
                updateLEDs();
            }, TIME_MILLIS);

// Task to run on core 0
            taskManager.scheduleFixedRate(100, [] {
            if (MySUI.checkForUser(0)) {   
                /* Now we keep handling the serial user's
                ** requests until they exit or timeout.
                */
                if (MySUI.userPresent()) {
                // actually respond to requests, using
                for(int i=1; i <=100; i++){
                    MySUI.handleRequests();
                }
                }
            } /* end if we had a user on the serial line */
        }, TIME_MILLIS);


Author: davetcc
12/02/2021 08:31:19
Hi there,

You can signal task manager from anywhere, on any thread, by scheduling or executing work. Or even an event. You can also create a second task manager for that, on the other thread (task). In the thread-proc you would run the second loop. You can interact between taskManager instances using events or by scheduling work on the other one.

Task manager runs all its tasks on a single thread, so it means that the items working on task manager don't need to be thread-safe. However, task manager itself is thread-safe, you can schedule safely from another thread, you can signal from any thread.

Conceptually something like the following:

TaskManager taskManagerThread2;

void myThreadProc() {
   while(systemIsRunning) {
     taskManagerThread2.runLoop();
  }
}

taskManagerThread2.scheduleFixedRate(1000, [] { 
   if(needToSignalOtherTaskManager) {
      taskManager.execute(taskToRunOnOtherTaskManager);
});


Or alternatively, you could create an event that was registered with one of the task managers, and signalled by the other thread. See the events section here: https://www.thecoderscorner.com/products/arduino-libraries/taskmanager-io/


Author: davetcc
12/02/2021 08:34:13
I'd just like to add that on ESP32 and mbed, it's using atomic CAS for thread safety, so it is atomically safe across cores. We have tests on mbed and ESP32 that check the threading.

Author: davetcc
12/02/2021 19:21:02
So in summary:

* use two task managers, one for each thread, create a runLoop in the second thread.
* you can submit work to either taskmanager from another thread, but it will be executed on the task manager you submit it to.
* you can use events, where one task manager would have the event registered, and the other would trigger the event, to indicate the condition was true, as linked above. https://github.com/davetcc/TaskManagerIO/blob/master/examples/eventHandling/eventHandling.ino
* you can submit work to another thread using an executable, or a task with parameters - https://www.thecoderscorner.com/products/arduino-libraries/taskmanager-io/task-manager-scheduling-guide/

Very important note: Just remember that any data that is passed between tasks or threads must be declared in a thread safe manner. IE: either using the ESP / C++ provided atomic access primitives, or declaring with volatile may be enough.





Register / Login  |  Desktop view  |  Jump to top of page