xTaskCreate .

創建新的任務並添加到任務隊列中,準備運行

 

Parameters:
pvTaskCode  指向任務的入口函數. 任務必須執行並且永不返回 (即:無限循環).
pcName  描述任務的名字。主要便於調試。最大長度由configMAX_TASK_NAME_LEN.定義
usStackDepth  指定任務堆棧的大小 ,堆棧能保護變量的數目- 不是字節數. 例如,如果堆棧爲16位寬度,usStackDepth定義爲 100, 200 字節,這些將分配給堆棧。堆棧嵌套深度(堆棧寬度)不能超多最大值——包含了size_t類型的變量
pvParameters  指針用於作爲一個參數傳向創建的任務
uxPriority  任務運行時的優先級( 0 : 優先級最低)
pvCreatedTask  用於傳遞一個處理——引用創建的任務
返回:
pdPASS 是如果任務成功創建並且添加到就緒列中,另外錯誤代碼在projdefs. H文件定義

使用例子:

 

 

 

 

// 使用句柄來刪除任務 vTaskDelete( xHandle ); }

// 創建任務,存儲處理。注意傳遞的參數爲ucParameterToPass //它在任務中不能始終存在, 所以定義爲靜態變量. 如果它是動態堆棧的變量,可能存在 // 沒有那麼長,或者至少隨着時間毀滅, // 新的時間, 嘗試存儲它 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );

// 函數來創建一個任務 void vOtherFunction( void ) { static unsigned char ucParameterToPass; xTaskHandle xHandle;

// 創建任務 void vTaskCode( void * pvParameters ) { for( ;; ) { // 任務代碼 } }

portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, const portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pvCreatedTask );
 
[:以下爲FreeRTOS_v4.5.0在at91sam7s64處理器上的task任務創建函數(gliethtp)] signed portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, const signed portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask ) { signed portBASE_TYPE xReturn; tskTCB * pxNewTCB; #if ( configUSE_TRACE_FACILITY == 1 ) //uxTaskNumber爲任務id號,一般用來調試,每個任務會唯一對應一個處於[0,0xffffffff]範圍之間的數值 //因爲優先級並不能唯一表示一個task,所以爲了能夠唯一標識一個task, //可以使用TCB或者TCB->uxTCBNumber     static unsigned portBASE_TYPE uxTaskNumber = 0; #endif //動態申請tskTCB存儲區和usStackDepth堆棧存儲區 //FreeRTOS提供3中動態內存分配機制,具體可參見《淺析FreeRTOS_v4.5.0內存分配與回收及其改進方案》 //文章地址:http://blog.chinaunix.net/u1/38994/showart_392500.html     pxNewTCB = prvAllocateTCBAndStack( usStackDepth );     if( pxNewTCB != NULL )     {                 portSTACK_TYPE *pxTopOfStack; //對task的 //pxTCB->pcTaskName //pxTCB->uxBasePriority //pxTCB->xGenericListItem //pxTCB->xEventListItem進行初始化, //將xEventListItem->xItemValue值置爲configMAX_PRIORITIES - ( portTickType ) uxPriority //所以xEventListItem->xItemValue的最小值爲1.(注:非0[gliethttp])         prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority );         #if portSTACK_GROWTH < 0         {             //堆棧是向下生長的,at91sam7s64就是以這種方式來生長堆棧             pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );         }         #else         {             pxTopOfStack = pxNewTCB->pxStack;             }         #endif         //初始化該task對應的堆棧空間         //具體可參見《淺析FreeRTOS_v4.5.0的任務切換原理和棧結構》         //文章地址:http://blog.chinaunix.net/u1/38994/showart_391270.html         //需要注意的是pvTaskCode應該+4,即lr-4,這樣來模擬IRQ,         //pxNewTCB->pxTopOfStack存放了當前task使用到的sp棧頂值         pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pvTaskCode, pvParameters );         portENTER_CRITICAL();//原子操作         {             uxCurrentNumberOfTasks++;             if( uxCurrentNumberOfTasks == ( unsigned portBASE_TYPE ) 1 )             {                 //這是FreeRTOS系統創建的第1個任務,那麼初始化FreeRTOS的一些基礎量:                 //1.pxReadyTasksLists隊列鏈表                 //2.xDelayedTaskList1隊列鏈表                 //3.xDelayedTaskList2隊列鏈表                 //4.xPendingReadyList隊列鏈表                 //5.xTasksWaitingTermination隊列鏈表                 //6.xSuspendedTaskList隊列鏈表                 //7.pxDelayedTaskList = &xDelayedTaskList1;暫時的前臺時間隊列鏈表                 //8.pxOverflowDelayedTaskList = &xDelayedTaskList2;暫時的後臺時間隊列鏈表                 pxCurrentTCB = pxNewTCB;                 prvInitialiseTaskLists();             }             else             {                     if( xSchedulerRunning == pdFALSE )                 {//當前FreeRTOS還沒有啓動調度器,                  //那麼當前pxCurrentTCB需要是指向最高優先級任務                     if( pxCurrentTCB->uxPriority <= uxPriority )                     {                         //比它高,所以pxNewTCB應該做當前任務                         pxCurrentTCB = pxNewTCB;                     }                 }             }                             if( pxNewTCB->uxPriority > uxTopUsedPriority )             {                 uxTopUsedPriority = pxNewTCB->uxPriority;//在vTaskList()中使用到了             }             #if ( configUSE_TRACE_FACILITY == 1 )             {                 pxNewTCB->uxTCBNumber = uxTaskNumber;//存儲新創建的task的id號                 uxTaskNumber++;//id號+1,以便供下一個創建的task使用             }             #endif //#define prvAddTaskToReadyQueue( pxTCB )                                       \ //{                                                                             \ //    if( pxTCB->uxPriority > uxTopReadyPriority )                              \ //    {                                                                         \ //        uxTopReadyPriority = pxTCB->uxPriority;                               \ //    }                                                                         \ //    vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) );\ //} //把新創建的task添加到就緒運行隊列鏈表中, //本task會被插入到pxReadyTasksLists中自己優先級所對應的數組下 //這時本task對應優先級的數組可能已經有同優先級的任務在上邊了, //沒關係,只需要將本task添加到輪轉調度的最後位置即可,對於FreeRTOS輪轉調度的理解, //可以參見《淺析FreeRTOS_v4.5.0的任務切換原理和棧結構》 //文章地址:http://blog.chinaunix.net/u1/38994/showart_391270.html             prvAddTaskToReadyQueue( pxNewTCB );             xReturn = pdPASS;//標示成功創建         }         portEXIT_CRITICAL();//原子操作結束     }     else     {         xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;     }     if( xReturn == pdPASS )     {         if( ( void * ) pxCreatedTask != NULL )         {             *pxCreatedTask = ( xTaskHandle ) pxNewTCB;//把創建的TCB,傳遞到外界參數pxCreatedTask中         }         if( xSchedulerRunning != pdFALSE )         {//os已經正常啓動             if( pxCurrentTCB->uxPriority < uxPriority )             {                 //新創建的task-B的優先級比調用創建函數xTaskCreate()的task-A的優先級高                 //那麼task-B立即搶佔task-A,取得cpu的使用權                 //可以參見《淺析FreeRTOS_v4.5.0的任務切換原理和棧結構》                 //文章地址:http://blog.chinaunix.net/u1/38994/showart_391270.html                 taskYIELD();             }         }     }     return xReturn;//返回xTaskCreate()函數的執行結果 }
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章