文档: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
......
}
上面的代码已经证明了。