ESP32 Arduino FreeRTOS创建任务双核运行

  • Post author:
  • Post category:其他


文档:readme_smp.txt

This version of FreeRTOS has been modified by Espressif to be SMP-aware. The

API is similar to the original FreeRTOS API, with the following changes:

– The xTaskCreate() function now creates tasks that will run on the first

core only, for backwards compatibility. To schedule tasks on another core,

use xTaskCreatePinnedToCore(), which will accept a core ID as the last

argument. If this is the constant tskNO_AFFINITY, the task will be dynamically

scheduled on whichever core has time.

– vTaskSuspendAll/vTaskResumeAll in non-SMP FreeRTOS will suspend the scheduler

so no other tasks than the current one will run. In this SMP version, it will

only suspend the scheduler ON THE CURRENT CORE. That is, tasks scheduled to

run on the other core(s) or without a specific CPU affinity, will still be

able to run.

– Enabling and disabling interrupts will only affect the current core.

Disabling the interrupts will not disallow other tasks to run as

it would on a single-core system: the other core still will keep on

executing all it’s own. Use a mux, queue or semaphore to protect your

structures instead.

– This FreeRTOS version has the task local storage backported from the 8.2.x

versions. It, however, has an addition: you can also set a callback when you

set the pointer. This callback will be called by the idle task, with the

pointer as an argument, when the thread is destroyed. This depends on the idle

task getting CPU time; when a thread is hogging the CPU without yielding,

the idle thread won’t be called and the delete callback won’t be called either.

上面这段话的意思是:此版本的FreeRTOS修改为支持SMP。SMP构架的系统中所有CPU共享系统内存和外设资源,由操作系统负责处理器间协作,并保持数据结构的一致性。使用多核时请使用xTaskCreatePinnedToCore()函数创建任务。

SMP构架的系统中所有CPU共享系统内存和外设资源,由操作系统负责处理器间协作,并保持数据结构的一致性.

#if CONFIG_AUTOSTART_ARDUINO

#if CONFIG_FREERTOS_UNICORE
#define ARDUINO_RUNNING_CORE 0
#else
#define ARDUINO_RUNNING_CORE 1
#endif


#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
    BaseType_t xTaskCreatePinnedToCore(	TaskFunction_t pxTaskCode,
							            const char * const pcName,
							            const uint32_t usStackDepth,
							            void * const pvParameters,
							            UBaseType_t uxPriority,
							            TaskHandle_t * const pxCreatedTask,
							            const BaseType_t xCoreID);

#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) \
xTaskCreatePinnedToCore( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), tskNO_AFFINITY )
#endif

xTaskCreatePinnedToCore()这个函数的xCoreID参数使用ARDUINO_RUNNING_CORE即应用在PRO CPU上跑, 使用ARDUINO_RUNNING_CORE即应用在APPCPU上跑。tskNO_AFFINITY则是支持将在有时间的任何核心上动态调度任务SMP。

代码:

现象:

一开始编程,我还担心双核都使用同一路UART会不会冲突。

后来追踪了一下源码:

其中 CONFIG_DISABLE_HAL_LOCKS 这个宏为 0 。

故开始了互斥量保护。

uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted)
{
   ......

#if !CONFIG_DISABLE_HAL_LOCKS
    if(uart->lock == NULL) {
        uart->lock = xSemaphoreCreateMutex();   //互斥锁保护
        if(uart->lock == NULL) {
            return NULL;
        }
    }
#endif
   ......
}

上面的代码已经证明了。



版权声明:本文为sudaroot原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。