admin管理员组

文章数量:1391964

I am working on a project using the ESP32 in combination with VS Code and the ESP IDF. Software is basically working. From some other standard ARM 32 bit controllers I have usually a sequence in the main routine to init all the needed peripherals and modules and then start the normal operation in the while(1) loop.

In my init sequence on the ESP32 I have several tasks that are created during the init. Now I notized that those tasks that I add during the init run inbetween of my init sequence. Actually I don't understand why the scheduler is started before calling the main function. Makes no sense on first view. I would suspect the sequence to be:

  • execute main function
  • do all the inits that are needed, create the tasks that are needed
  • start the scheduling (device is then in normal operation)

How would I do that on the esp32 platform?

Kind regards, Markus

I am working on a project using the ESP32 in combination with VS Code and the ESP IDF. Software is basically working. From some other standard ARM 32 bit controllers I have usually a sequence in the main routine to init all the needed peripherals and modules and then start the normal operation in the while(1) loop.

In my init sequence on the ESP32 I have several tasks that are created during the init. Now I notized that those tasks that I add during the init run inbetween of my init sequence. Actually I don't understand why the scheduler is started before calling the main function. Makes no sense on first view. I would suspect the sequence to be:

  • execute main function
  • do all the inits that are needed, create the tasks that are needed
  • start the scheduling (device is then in normal operation)

How would I do that on the esp32 platform?

Kind regards, Markus

Share Improve this question asked Mar 13 at 14:43 hdMKhdMK 351 silver badge4 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 3

If you read the ESP IDF documentation on Application Startup then it describes three stages where user code can be injected

  1. Port Initialization: very low level initialization to get the CPU and critical peripherals up and running.
    You very probably don't want to touch this one.

  2. System Initialization: regular system initialization before FreeRTOS scheduler is started.
    It calls a weak function start_cpu0() which you can override and initialize your hardware. Just don't fet to call start_cpu0_default() as first thing, or you'll skip the built-in initialization code.

  3. Main Task: the FreeRTOS scheduler is started, so now the system is running in full multithreading mode. For your convenience it creates one task solely for running app_main() which you are expected to define.This is the intended place for initializing your application and for launching other tasks. I would suggest you try to use it for your init purposes - usually there's nothing wrong with initializing high-level hardware after the scheduler has started (the HAL is built to work in multi-threading mode).

It's all laid out in the (quite well readable) ESP IDF source code, should you wish to see the details. Have a look at how start_cpu0_default() initializes the system in step 2 or how esp_startup_start_app() creates the main task and starts the scheduler in step 3.

On the ESP32, you usually do it in one of two ways:

a) do all initialization a task needs and only then create the task, or

b) have each task do its own initializations before it enters its while(1).

Notably in FreeRTOS creating a task is always also starting the task.

Another option is to make each task wait (e.g. on a notification) before actually becoming 'active'. Then you can create the tasks as you wish but each will not do anything until it gets its "go" signal.

本文标签: cESP32FreeRTOS stop scheduler at beginning of mainthen init tasks and restart schedulerStack Overflow