文档: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 )
#endifxTaskCreatePinnedToCore()这个函数的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
   ......
}上面的代码已经证明了。
 
