Isolating Application Code to APP Core
Posted: Tue Jul 02, 2019 9:02 pm
Hello All,
I am new to the ESP32 and attempting to learn as much as I can as fast as I can. I am attempting to architect a design which will utilize the PRO core for supporting the WiFi and BLE stacks with the FreeRTOS while utilizing the APP core to execute my application-specific code (bare metal). The idea behind this is the desire to allow the PRO core exclusive control of the communications stacks without interruption by the application-specific code. A secondary goal was to reduce the interrupt latency when handling application-specific communications between the ESP32 and the host controller.
Documentation informs me that the developer should create an "app_main" function which will be called by the startup routine provided with the ESP-IDF. In essence, the ESP-IDF provides all the code necessary to startup the device and initialize things before passing control to the developers code (app_main). I found the cpu_start.c module within the ESP-IDF source code which is responsible for this initialization process. From what I can tell, the startup process executes as follows:
1) I presume the call_start_cpu0() function is executed first, while the cpu1 core is held in reset.
2) After initializing memory, it appears the APP CPU (cpu1) is brought out of reset and configured to execute the call_start_cpu1() function. The PRO CPU (cpu0) then waits for the APP_CPU (cpu1) to report it has started.
3a) The PRO_CPU (cpu0) will execute the start_cpu0() function - aliased as start_cpu0_default() - where initialization of cpu0 continues before creating the "main_task" (pinned to core 0) and initiating the task scheduler.
3b) The APP_CPU (cpu1) will execute the start_cpu1() function - aliased as start_cpu1_default() - where the code waits until the task scheduler on cpu0 is running before starting the task scheduler on cpu1.
4) The PRO_CPU will execute the created main_task, which waits until the task scheduler is running on cpu1 before calling app_main().
Since the app_main() function is called from the main_task() routine operating on cpu0, the developer's code will start on cpu0 by default. Documentation and other conversations in the forum mention that the developer's code can create its own tasks and pin them to cpu1 if desired.
I can see how it is necessary for the developer code to provide an app_main() routine which will configure the desired features/characteristics of the ESP-IDF that will be executed on cpu0. Based on the construction of the ESP-IDF code, it is clear the intention is to have an author create tasks which FreeRTOS is capable of executing on either core - as it sees fit.
In order to implement my intended architecture where the application-specific code is executed solely on cpu1, I believe I would have to modify the start_cpu1_default() routine to call an equivalent "app_main" routine which would be responsible for setting up the cpu1 code. Am I interpreting this correctly?
Would I also need to create FreeRTOS tasks pinned to cpu1 in order to interact with the communications stacks running on cpu0?
Thanks in advance!
Mark
I am new to the ESP32 and attempting to learn as much as I can as fast as I can. I am attempting to architect a design which will utilize the PRO core for supporting the WiFi and BLE stacks with the FreeRTOS while utilizing the APP core to execute my application-specific code (bare metal). The idea behind this is the desire to allow the PRO core exclusive control of the communications stacks without interruption by the application-specific code. A secondary goal was to reduce the interrupt latency when handling application-specific communications between the ESP32 and the host controller.
Documentation informs me that the developer should create an "app_main" function which will be called by the startup routine provided with the ESP-IDF. In essence, the ESP-IDF provides all the code necessary to startup the device and initialize things before passing control to the developers code (app_main). I found the cpu_start.c module within the ESP-IDF source code which is responsible for this initialization process. From what I can tell, the startup process executes as follows:
1) I presume the call_start_cpu0() function is executed first, while the cpu1 core is held in reset.
2) After initializing memory, it appears the APP CPU (cpu1) is brought out of reset and configured to execute the call_start_cpu1() function. The PRO CPU (cpu0) then waits for the APP_CPU (cpu1) to report it has started.
3a) The PRO_CPU (cpu0) will execute the start_cpu0() function - aliased as start_cpu0_default() - where initialization of cpu0 continues before creating the "main_task" (pinned to core 0) and initiating the task scheduler.
3b) The APP_CPU (cpu1) will execute the start_cpu1() function - aliased as start_cpu1_default() - where the code waits until the task scheduler on cpu0 is running before starting the task scheduler on cpu1.
4) The PRO_CPU will execute the created main_task, which waits until the task scheduler is running on cpu1 before calling app_main().
Since the app_main() function is called from the main_task() routine operating on cpu0, the developer's code will start on cpu0 by default. Documentation and other conversations in the forum mention that the developer's code can create its own tasks and pin them to cpu1 if desired.
I can see how it is necessary for the developer code to provide an app_main() routine which will configure the desired features/characteristics of the ESP-IDF that will be executed on cpu0. Based on the construction of the ESP-IDF code, it is clear the intention is to have an author create tasks which FreeRTOS is capable of executing on either core - as it sees fit.
In order to implement my intended architecture where the application-specific code is executed solely on cpu1, I believe I would have to modify the start_cpu1_default() routine to call an equivalent "app_main" routine which would be responsible for setting up the cpu1 code. Am I interpreting this correctly?
Would I also need to create FreeRTOS tasks pinned to cpu1 in order to interact with the communications stacks running on cpu0?
Thanks in advance!
Mark