【freeRTOS】API功能列表


任務建立

xTaskCreate

[ task.h ]

用以建立動態的任務

BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,
			const char * const pcName,
			const configSTACK_DEPTH_TYPE uxStackDepth,
			void *pvParameters,
			UBaseType_t uxPriority,
			TaskHandle_t *pxCreatedTask
			);  
    configSUPPORT_DYNAMIC_ALLOCATION 為1才可使用,如FreeRTOSConfig.h未宣告 不妨去FreeRTOS.h找找,預設為1
    pvTaskCode:任務函式
    pcName:Debug時供辨識的任務名稱, FreeRTOSConfig.h的 configMAX_TASK_NAME_LEN 定義長度
    uxStackDepth:stack所需分配的空間
    pvParameters:參數傳遞,可為NULL
    uxPriority:任務的優先權,FreeRTOSConfig.h的 configMAX_PRIORITIES定義最大值
    pxCreatedTask:任務的handle,可用以操作task,可為NULL

實際的例子

TaskHandle_t xHandle

void vTaskCode( void * pvParameters )
{
    configASSERT( ( ( uint32_t ) pvParameters ) == 1 );

    for( ;; )
    {
        /* Task code goes here. */
        vTaskDelay( pdMS_TO_TICKS(100) );
    }
}

void vOtherFunction( void )
{
    BaseType_t xReturned;
    TaskHandle_t xHandle = NULL;

    xReturned = xTaskCreate(
                    vTaskCode,       				
                    "NAME",          				
                    configMINIMAL_STACK_SIZE +60,	
                    ( void * ) 1,    
                    configMAX_PRIORITIES -1,
                    &xHandle );

    if( xReturned == pdPASS )
    {
        /* The task was created.  Use the task's handle to delete the task. */
        vTaskDelete( xHandle );
    }
}

vTaskDelete

[ task.h ]

刪除任務

void vTaskDelete( TaskHandle_t xTask );  
    xTask:預備刪除任務的handle


任務控制

vTaskDelay

[ task.h ]

讓目前任務進入Blocked阻塞,並倒數tick直至timeout然後回復為 Running mode;

void vTaskDelay( const TickType_t xTicksToDelay ); 
    FreeRTOSConfig.h的 INCLUDE_vTaskDelay 為1才可使用
    portTICK_PERIOD_MS 用以計算實際時間數值 ( 或pdMS_TO_TICKS )
    xTicksToDelay:任務阻塞tick的長度

vTaskDelayUntil

[ task.h ]

讓任務進入Blocked阻塞,並週期性的喚醒任務

void vTaskDelayUntil( TickType_t *pxPreviousWakeTime,
                      const TickType_t xTimeIncrement );  
    FreeRTOSConfig.h的 INCLUDE_vTaskDelayUntil 為1才可使用
    pxPreviousWakeTime:初次使用以xTaskGetTickCount()取後系統目前的時間,之後每次喚醒都會更新
    xTimeIncrement:任務週期性阻塞tick的長度

實際的例子

void vTaskFunction( void * pvParameters )
{
    TickType_t xLastWakeTime;
    const TickType_t xFrequency = pdMS_TO_TICKS(10);
    BaseType_t xWasDelayed;

    // xLastWakeTime取得目前的系統時間
    xLastWakeTime = xTaskGetTickCount ();
    for( ;; )
    {
        // Wait for the next cycle.
        xWasDelayed = xTaskDelayUntil( &xLastWakeTime, xFrequency );
    }
}
vTaskDelay 與 vTaskDelayUntil 的差異 請參考

vTaskSuspend

[ task.h ]

暫停任務

void vTaskSuspend( TaskHandle_t xTaskToSuspend ); 
    FreeRTOSConfig.h的 INCLUDE_vTaskSuspend 為1才可使用
    xTaskToSuspend:預被暫停任務的handle

vTaskResume

[ task.h ]

恢復被暫停(suspend)的任務

void vTaskResume( TaskHandle_t xTaskToResume ); 
    FreeRTOSConfig.h的 INCLUDE_vTaskSuspend 為1才可使用
    xTaskToResume:要恢復任務的handle

xTaskResumeFromISR

[ task.h ]

處于ISR中斷要恢復被暫停(suspend)的任務

BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume );
    FreeRTOSConfig.h的 include_vTaskSuspend 和 INCLUDE_xTaskResumeFromISR 為1才可使用
    xTaskToResume:要恢復任務的handle

xTaskAbortDelay

[ task.h ]

強制任務脫離阻塞blocked狀態

BaseType_t xTaskAbortDelay( TaskHandle_t xTask );
    FreeRTOSConfig.h的 INCLUDE_xTaskAbortDelay 為1才可使用
    xTask:強制脫離阻塞任務的handle
    return:pdFAIL即任務不在blocked狀態,pdPASS為喚醒成功

uxTaskPriorityGet

[ task.h ]

查詢任務的優先權數值

UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask );
    FreeRTOSConfig.h的 INCLUDE_uxTaskPriorityGet 為1才可使用
    xTask:查詢優先權任務的handle
    return:優先權值

uxTaskPriorityGetFromISR

[ task.h ]

在ISR中斷查詢任務的優先權數值

UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask );
    FreeRTOSConfig.h的 INCLUDE_uxTaskPriorityGet 為1才可使用
    xTask:查詢優先權任務的handle
    return:優先權值

vTaskPrioritySet

[ task.h ]

修改任務的優先權數值

void vTaskPrioritySet( TaskHandle_t xTask,
                       UBaseType_t uxNewPriority );
    FreeRTOSConfig.h的 INCLUDE_vTaskPrioritySet 為1才可使用
    xTask:修改優先權任務的handle
    uxNewPriority:想要設置的優先權數值

範例

void vAFunction( void )
{
    // Use the handle to raise the priority of the created task.
    vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 )

    // Use a NULL handle to raise our priority to the same value.
    vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
}


進階控制

vTaskDelay

[ task.h ]

讓目前任務進入Blocked阻塞,並倒數tick直至timeout然後回復為 Running mode;

void vTaskDelay( const TickType_t xTicksToDelay ); 
    FreeRTOSConfig.h的 INCLUDE_vTaskDelay 為1才可使用
    portTICK_PERIOD_MS 用以計算實際時間數值 ( 或pdMS_TO_TICKS )
    xTicksToDelay:任務阻塞tick的長度


核心控制

taskYIELD

[ task.h ]

讓出系統使用權

void taskYIELD( void ); 

vTaskStartScheduler

[ task.h ]

啟動任務排程

void vTaskStartScheduler( void );

vTaskEndScheduler

[ task.h ]

結束任務排程

void vTaskEndScheduler( void );

vTaskSuspendAll

[ task.h ]

暫停所有任務

void vTaskSuspendAll( void );

xTaskResumeAll

[ task.h ]

恢復所有被暫停(suspend)的任務

BaseType_t xTaskResumeAll( void );
    return:成功回覆pdTRUE,失敗pdFALSE


軟件計時器

xTimerCreate

[ timers.h ]

建立軟件計時器

 TimerHandle_t xTimerCreate
                 ( const char * const pcTimerName,
                   const TickType_t xTimerPeriod,
                   const UBaseType_t uxAutoReload,
                   void * const pvTimerID,
                   TimerCallbackFunction_t pxCallbackFunction );
    FreeRTOSConfig.h的 configUSE_TIMERS 和 configSUPPORT_DYNAMIC_ALLOCATION 為1才可使用
    pcTimerName:Debug時使用的名稱
    xTimerPeriod:以tick為單位計數的長度,可用 pdMS_TO_TICKS(tick)把時間轉換為tick值
    uxAutoReload:pdTRUE 計時器重覆循環,pdFALSE 計時到點後即休眠
    pvTimerID:分配給timer的ID,配合vTimerSetTimerID() 和 pvTimerGetTimerID() 使用
    pxCallbackFunction:計時到點時呼叫的函式
    return:software timer建立成功則得到timer handle;失敗則得到NULL

例子

TimerHandle_t timer_handle; 
  
static void software_timer_callback (void * pvParameter)
{
    UNUSED_PARAMETER(pvParameter);
    LED_TOGGLE();
}

void main()
{
    timer_handle = xTimerCreate( "LED1", \
                                  pdMS_TO_TICKS(300), \
                                  pdTRUE, \
                                  NULL, \
                                  software_timer_callback);
    xTimerStart(timer_handle, 0);
}

xTimerIsTimerActive

[ timers.h ]

確認software timer目前的狀態

BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );
    xTimer:timer的handle
    return:timer在活動狀態回覆pdTRUE,timer在休眠狀態則回pdFALSE

例子

 void vAFunction( TimerHandle_t xTimer )
 {
     /* or more simply and equivalently
     "if( xTimerIsTimerActive( xTimer ) )" */
     if( xTimerIsTimerActive( xTimer ) != pdFALSE )
     {
         /* xTimer is active, do something. */
     }
     else
     {
         /* xTimer is not active, do something else. */
     }
 }

xTimerStart

[ timers.h ]

啟動software timer

BaseType_t xTimerStart( TimerHandle_t xTimer,
                            TickType_t xBlockTime );
    configUSE_TIMERS 為1才可使用
    xTimer:timer的handle
    xBlockTime:如果核心隊列已滿,調用software timer的任務即進入阻塞blocked,並以xBlockTime的數值倒數
    return:成功啟動則回覆pdTRUE,經過xBlockTime後仍失敗回覆pdFALSE

xTimerStop

[ timers.h ]

停止software timer

BaseType_t xTimerStop( TimerHandle_t xTimer,
                           TickType_t xBlockTime );
    configUSE_TIMERS 為1才可使用
    xTimer:timer的handle
    xBlockTime:如果核心隊列已滿,調用software timer的任務即進入阻塞blocked,並以xBlockTime的數值倒數
    return:成功啟動則回覆pdTRUE,經過xBlockTime後仍失敗回覆pdFALSE

xTimerChangePeriod

[ timers.h ]

停止software timer

BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,
                                TickType_t xNewPeriod,
                                TickType_t xBlockTime );
    configUSE_TIMERS 為1才可使用
    xTimer:timer的handle
    xNewPeriod:預更新的計時數值
    xBlockTime:如果核心隊列已滿,調用software timer的任務即進入阻塞blocked,並以xBlockTime的數值倒數
    return:成功啟動則回覆pdTRUE,經過xBlockTime後仍失敗回覆pdFALSE

xTimerDelete

[ timers.h ]

刪除處于非活動的software timer

BaseType_t xTimerDelete( TimerHandle_t xTimer,
                             TickType_t xBlockTime );
    configUSE_TIMERS 為1才可使用
    xTimer:timer的handle
    xBlockTime:如果核心隊列已滿,調用software timer的任務即進入阻塞blocked,並以xBlockTime的數值倒數
    return:成功回覆pdTRUE,經過xBlockTime後仍失敗回覆pdFALSE

xTimerReset

[ timers.h ]

重置software timer

BaseType_t xTimerReset( TimerHandle_t xTimer,
                            TickType_t xBlockTime );
    configUSE_TIMERS 為1才可使用
    xTimer:timer的handle
    xBlockTime:如果核心隊列已滿,調用software timer的任務即進入阻塞blocked,並以xBlockTime的數值倒數
    return:成功回覆pdTRUE,經過xBlockTime後仍失敗回覆pdFALSE


Semaphore

xSemaphoreCreateMutex

[ semphr.h ]

建立互斥的訊號鎖

SemaphoreHandle_t xSemaphoreCreateMutex( void )
    FreeRTOSConfig.h的 configSUPPORT_DYNAMIC_ALLOCATION 和 configUSE_MUTEXES 為1才可使用
    Give須在和Take同個任務裡操作
    ISR中斷裡不可使用
    return:建立成功回傳Semaphore的handler;失敗則得到NULL

例子

SemaphoreHandle_t xSemaphore = NULL;

void vATask( void * pvParameters )
{
    /* 建立mutex 的semaphore */
    xSemaphore = xSemaphoreCreateMutex();
}

void vAnotherTask( void * pvParameters )
{
    if( xSemaphore != NULL )
    {
        /* xSemaphoreTake第二個參數不為0時,如take失敗將阻塞所在的task,並倒數tick值 */
        if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
        {
            /* 釋放 semaphore 使用權 */
            xSemaphoreGive( xSemaphore );
        }
        else
        {
            /* We could not obtain the semaphore and can therefore not access
            the shared resource safely. */
        }
    }
}

xSemaphoreTake

[ semphr.h ]

獲取Semaphore使用權

xSemaphoreTake( SemaphoreHandle_t xSemaphore,
                 TickType_t xTicksToWait );
    xSemaphore :Semaphore的handle
    xTicksToWait:數值不為0時,當Take權限失敗則blcoked阻塞目前所在的任務,倒數tick的值
    return:成功回覆pdTRUE,經過xTicksToWait後仍失敗回覆pdFALSE

xSemaphoreGive

[ semphr.h ]

釋放Semaphore使用權

xSemaphoreGive( SemaphoreHandle_t xSemaphore );
    xSemaphore :Semaphore的handle
    return:成功回覆pdTRUE,失敗回覆pdFALSE

xSemaphoreCreateBinary

[ semphr.h ]

建立二進制的訊號鎖

SemaphoreHandle_t xSemaphoreCreateBinary( void );
    FreeRTOSConfig.h的 configSUPPORT_DYNAMIC_ALLOCATION 為1才可使用
    與Mutex不同,可在ISR中斷間操作
    與Mutex不同,xSemaphoreCreateBinary()建立後須先Give;Mutex不必
    與Mutex不同,xSemaphoreCreateBinary()的Take和Give可分別在不同任務間操作
    return:建立成功回傳Semaphore的handler;失敗則得到NULL

例子


  

vSemaphoreDelete

[ semphr.h ]

刪除semaphore

void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );
    xSemaphore:Semaphore的handler


任務通知

xTaskNotifyGive

[ task.h ]

藉由任務建立時的hanlder來取消任務的阻塞狀態

BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );
    FreeRTOSConfig.h的 configUSE_TASK_NOTIFICATIONS 和 configTASK_NOTIFICATION_ARRAY_ENTRIES 為1才可使用
    xTaskToNotify:任務建立時的handler

例子

static void prvTask1( void *pvParameters );
static void prvTask2( void *pvParameters );

static TaskHandle_t xTask1 = NULL, xTask2 = NULL;

void main( void )
{
    xTaskCreate( prvTask1, "Task1", 200, NULL, tskIDLE_PRIORITY, &xTask1 );
    xTaskCreate( prvTask2, "Task2", 200, NULL, tskIDLE_PRIORITY, &xTask2 );
    vTaskStartScheduler();
}

static void prvTask1( void *pvParameters )
{
    for( ;; )
    {
        /* Send notification to prvTask2(), bringing it out of the 
        Blocked state. */
        xTaskNotifyGive( xTask2, 0 );

        /* Block to wait for prvTask2() to notify this task. */
        ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
    }
}

static void prvTask2( void *pvParameters )
{
    for( ;; )
    {
        /* Block to wait for prvTask1() to notify this task. */
        ulTaskNotifyTake( pdTRUE, portMAX_DELAY );

        /* Send a notification to prvTask1(), bringing it out of the 
        Blocked state. */
        xTaskNotifyGive( xTask1 );
    }
}

ulTaskNotifyTake

[ task.h ]

建立二進制的訊號鎖

uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit,
                            TickType_t xTicksToWait );
    FreeRTOSConfig.h的 configUSE_TASK_NOTIFICATIONS 和 configTASK_NOTIFICATION_ARRAY_ENTRIES 為1才可使用
    與Mutex不同,可在ISR中斷間操作
    xClearCountOnExit:pdFALSE 在收到通知時計數減1,pdTRUE 收到通知則清為0
    xTicksToWait:在阻塞狀態下ticks的數值
    return:被清除或遞減時任務的通知的值


隊列

xQueueCreate

[ queue.h ]

建立隊列

QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength,
                             UBaseType_t uxItemSize );
    FreeRTOSConfig.h的 configSUPPORT_DYNAMIC_ALLOCATION 為1才可使用
    uxQueueLength:收送資料的長度
    uxItemSize:收送資料的大小
    return:成功則回覆隊列的handler;失敗回NULL

例子

struct AMessage
{
    char ucMessageID;
    char ucData[ 20 ];
};

void vATask( void *pvParameters )
{
    QueueHandle_t xQueue1, xQueue2;

    if( xQueue1 == NULL )
    {
        /* Queue was not created and must not be used. */
    }

    xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );

    if( xQueue2 == NULL )
    {
        /* Queue was not created and must not be used. */
    }
 }

vQueueDelete

[ queue.h ]

刪除隊列的任務

void vQueueDelete( QueueHandle_t xQueue );
    xQueue:預刪除隊列的handler

xQueueSend

[ queue.h ]

發送資料到隊列

BaseType_t xQueueSend(
                            QueueHandle_t xQueue,
                            const void * pvItemToQueue,
                            TickType_t xTicksToWait
                         );
    xQueue:隊列的handler
    pvItemToQueue:發送的資料
    xTicksToWait:隊列填滿後進入阻塞的時間長度 (INCLUDE_vTaskSuspend為1時將無限期的阻塞)
    return:成功則回覆隊列的handler;失敗回NULL

例子

QueueHandle_t xQueue1;

void main(void)
{
    xQueue1 = xQueueCreate( 6, sizeof( uint8_t ) );
}

static void task_function_1 (void * pvParameter)
{
    int ulVar = 3;    

    while(true){
      ulVar++;
      if( xQueue1 != 0 ){
          if( xQueueSend( xQueue1,
                         ( void * ) &ulVar,
                         ( TickType_t ) pdMS_TO_TICKS(100) ) != pdPASS )
          {
              /* Failed to post the message, even after 10 ticks. */
          }else{
              /* 成功寫入資料 */
          }
      }
    }
}

static void task_function_2 (void * pvParameter)
{
    uint8_t box[10];

    while(true){
      if( xQueue1 != 0 ){
          if( xQueueReceive( xQueue1,
                         &( box ),
                         ( TickType_t ) 0 ) == pdPASS )
          {
             /* 成功取出資料 */
          }else{
             /* 取完資料後讓出控制權 */          	
              taskYIELD();
          }
      }
    }
}

xQueueReceive

[ queue.h ]

從隊列接收資料

BaseType_t xQueueReceive(
                               QueueHandle_t xQueue,
                               void *pvBuffer,
                               TickType_t xTicksToWait
                            );
    xQueue:隊列的handler
    pvItemToQueue:接收的資料
    xTicksToWait:隊列填滿後進入阻塞的時間長度 (INCLUDE_vTaskSuspend為1時將無限期的阻塞)
    return:成功則回覆隊列的handler;失敗回NULL