任務建立
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
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