0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

FreeRTOS任務(wù)應(yīng)用函數(shù)介紹

安芯教育科技 ? 來(lái)源:極術(shù)社區(qū) ? 作者:朱工 ? 2021-03-19 10:22 ? 次閱讀

任務(wù)應(yīng)用函數(shù)是一組輔助類函數(shù),一般用于調(diào)試信息輸出、獲取任務(wù)句柄、獲取任務(wù)狀態(tài)、操作任務(wù)標(biāo)簽值等等。

1. 獲取任務(wù)系統(tǒng)狀態(tài)

1.1 函數(shù)描述

UBaseType_t uxTaskGetSystemState( TaskStatus_t * constpxTaskStatusArray, const UBaseType_tuxArraySize, unsigned long * constpulTotalRunTime );

該函數(shù)向TaskStatus_t結(jié)構(gòu)體填充相關(guān)信息,系統(tǒng)中每一個(gè)任務(wù)的信息都可以填充到TaskStatus_t結(jié)構(gòu)體數(shù)組中,數(shù)組大小由uxArraySize指定。結(jié)構(gòu)體TaskStatus_t定義如下:

typedef struct xTASK_STATUS{ /* 任務(wù)句柄*/ TaskHandle_t xHandle; /* 指針,指向任務(wù)名*/ const signed char *pcTaskName; /*任務(wù)ID,是一個(gè)獨(dú)一無(wú)二的數(shù)字*/ UBaseType_t xTaskNumber; /*填充結(jié)構(gòu)體時(shí),任務(wù)當(dāng)前的狀態(tài)(運(yùn)行、就緒、掛起等等)*/ eTaskState eCurrentState;/*填充結(jié)構(gòu)體時(shí),任務(wù)運(yùn)行(或繼承)的優(yōu)先級(jí)。*/ UBaseType_t uxCurrentPriority; /* 當(dāng)任務(wù)因繼承而改變優(yōu)先級(jí)時(shí),該變量保存任務(wù)最初的優(yōu)先級(jí)。僅當(dāng)configUSE_MUTEXES定義為1有效。*/ UBaseType_t uxBasePriority; /* 分配給任務(wù)的總運(yùn)行時(shí)間。僅當(dāng)宏configGENERATE_RUN_TIME_STATS為1時(shí)有效。*/ unsigned long ulRunTimeCounter; /* 從任務(wù)創(chuàng)建起,堆棧剩余的最小數(shù)量,這個(gè)值越接近0,堆棧溢出的可能越大。*/ unsigned short usStackHighWaterMark;}TaskStatus_t;

注意,這個(gè)函數(shù)僅用來(lái)調(diào)試用,調(diào)用此函數(shù)會(huì)掛起所有任務(wù),直到函數(shù)最后才恢復(fù)掛起的任務(wù),因此任務(wù)可能被掛起很長(zhǎng)時(shí)間。在文件FreeRTOSConfig.h中,宏configUSE_TRACE_FACILITY必須設(shè)置為1,此函數(shù)才有效。

1.2 參數(shù)描述

pxTaskStatusArray:指向TaskStatus_t類型的結(jié)構(gòu)體數(shù)組。這個(gè)數(shù)組至少要包含1個(gè)元素。RTOS控制的任務(wù)數(shù)量可以使用API函數(shù)uxTaskGetNumberOfTasks()獲取。

uxArraySize:參數(shù)pxTaskStatusArray指向的數(shù)組大小,也就是該數(shù)組的索引數(shù)目。

pulTotalRunTime:如果在文件FreeRTOSConfig.h中設(shè)置宏configGENERATE_RUN_TIME_STATS為1,則該函數(shù)將總運(yùn)行時(shí)間寫入*pulTotalRunTime中。pulTotalRunTime可以設(shè)置為NULL,表示忽略總運(yùn)行時(shí)間。

1.3 返回值

被填充的TaskStatus_t結(jié)構(gòu)體數(shù)量。這個(gè)值應(yīng)該等于通過調(diào)用API函數(shù)uxTaskGetNumberOfTasks()返回的值,但如果傳遞給uxArraySize參數(shù)的值太小,則返回0。

1.4 用法舉例

/*本例演示如是使用uxTaskGetSystemState()函數(shù)來(lái)獲取運(yùn)行時(shí)間信息,并將其轉(zhuǎn)化為程序員更易識(shí)別的字符格式,這些轉(zhuǎn)化后的字符保存到pcWriteBuffer中。*/void vTaskGetRunTimeStats(signed char *pcWriteBuffer ){ TaskStatus_t*pxTaskStatusArray;

volatileUBaseType_t uxArraySize, x; unsignedlong ulTotalRunTime, ulStatsAsPercentage; /* 防御性代碼,確保字符串有合理的結(jié)束*/ *pcWriteBuffer = 0x00; /* 獲取任務(wù)總數(shù)目*/ uxArraySize = uxTaskGetNumberOfTasks (); /*為每個(gè)任務(wù)的TaskStatus_t結(jié)構(gòu)體分配內(nèi)存,也可以靜態(tài)的分配一個(gè)足夠大的數(shù)組 */ pxTaskStatusArray = pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ));

if(pxTaskStatusArray != NULL ) { /*獲取每個(gè)任務(wù)的狀態(tài)信息 */ uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize,&ulTotalRunTime ); /* 百分比計(jì)算 */ ulTotalRunTime /= 100UL; /* 避免除零錯(cuò)誤 */ if(ulTotalRunTime 》 0 ) { /* 將獲得的每一個(gè)任務(wù)狀態(tài)信息部分的轉(zhuǎn)化為程序員容易識(shí)別的字符串格式*/

for( x = 0; x 《 uxArraySize; x++ )

{ /* 計(jì)算任務(wù)運(yùn)行時(shí)間與總運(yùn)行時(shí)間的百分比。*/ ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter /ulTotalRunTime; if( ulStatsAsPercentage 》 0UL ) { sprintf( pcWriteBuffer, “%s %lu %lu%% ”, pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage ); }

else { /* 任務(wù)運(yùn)行時(shí)間不足總運(yùn)行時(shí)間的1%*/sprintf( pcWriteBuffer, “%s %lu 《1%% ”, pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[x ].ulRunTimeCounter ); } pcWriteBuffer += strlen( ( char * ) pcWriteBuffer ); } } /* 釋放之前申請(qǐng)的內(nèi)存*/ vPortFree( pxTaskStatusArray ); }}

2. 獲取當(dāng)前任務(wù)句柄

2.1 函數(shù)描述

TaskHandle_t xTaskGetCurrentTaskHandle(void );

在文件FreeRTOSConfig.h中,宏INCLUDE_xTaskGetCurrentTaskHandle必須設(shè)置為1,此函數(shù)才有效。

2.2 返回值

返回當(dāng)前任務(wù)(調(diào)用該函數(shù)的任務(wù))的句柄。

3. 獲取空閑任務(wù)句柄

3.1 函數(shù)描述

TaskHandle_t xTaskGetIdleTaskHandle(void );

在文件FreeRTOSConfig.h中,宏INCLUDE_xTaskGetIdleTaskHandle必須設(shè)置為1,此函數(shù)才有效。

3.2 返回值

返回空閑任務(wù)句柄。空閑任務(wù)在RTOS調(diào)度器啟動(dòng)時(shí)自動(dòng)創(chuàng)建。

4. 獲取任務(wù)堆棧最大使用深度

4.1 函數(shù)描述

UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );

任務(wù)的堆棧空間會(huì)隨著任務(wù)執(zhí)行以及中斷處理而增長(zhǎng)或縮小。該函數(shù)可以返回任務(wù)啟動(dòng)后的最小剩余堆??臻g。換句話說(shuō),可以間接估算出一個(gè)任務(wù)最多需要多少堆棧空間。在文件FreeRTOSConfig.h中,宏INCLUDE_uxTaskGetStackHighWaterMark 必須設(shè)置成1,此函數(shù)才有效。

4.2 參數(shù)描述

xTask:任務(wù)句柄。NULL表示查看當(dāng)前任務(wù)的堆棧使用情況。

4.3 返回值

返回最小剩余堆??臻g,以字為單位。比如一個(gè)32為架構(gòu)處理器,返回值為1表示有4字節(jié)堆??臻g沒有使用過。如果返回值為0,則任務(wù)很可能已經(jīng)發(fā)生了堆棧溢出。

4.4 用法舉例

void vTask1( void * pvParameters ){ UBaseType_tuxHighWaterMark; /* 入口處檢測(cè)一次 */ uxHighWaterMark =uxTaskGetStackHighWaterMark( NULL ); for( ;; ) { /* 正常調(diào)用函數(shù) */ vTaskDelay( 1000 ); /* 測(cè)量堆棧使用情況 */ uxHighWaterMark =uxTaskGetStackHighWaterMark( NULL ); }}

5. 獲取任務(wù)狀態(tài)

5.1 函數(shù)描述

eTaskState eTaskGetState( TaskHandle_txTask );

返回一個(gè)枚舉類型的任務(wù)狀態(tài)值。在文件FreeRTOSConfig.h中,宏INCLUDE_eTaskGetState必須設(shè)置為1,此函數(shù)才有效。

5.2 參數(shù)描述

xTask:任務(wù)句柄

5.3 返回值

下表列出返回值和對(duì)應(yīng)的任務(wù)狀態(tài)。

6. 獲取任務(wù)描述內(nèi)容

6.1 函數(shù)描述

char * pcTaskGetTaskName( TaskHandle_txTaskToQuery );

獲取任務(wù)的描述內(nèi)容,在文件FreeRTOSConfig.h中,宏INCLUDE_pcTaskGetTaskName必須設(shè)置成1,此函數(shù)才有效。

6.2 參數(shù)描述

xTaskToQuery:任務(wù)的句柄。NULL表示獲取當(dāng)前任務(wù)的描述內(nèi)容指針。

6.3 返回值

一個(gè)指針,指向任務(wù)描述字符串。

7. 獲取系統(tǒng)節(jié)拍次數(shù)

7.1 函數(shù)描述

volatile TickType_t xTaskGetTickCount(void );

這個(gè)函數(shù)不能在ISR中調(diào)用。在ISR中用xTaskGetTickCountFromISR(),原型為volatileTickType_t xTaskGetTickCountFromISR( void )。

7.2 返回值

返回從vTaskStartScheduler函數(shù)調(diào)用后的系統(tǒng)時(shí)鐘節(jié)拍次數(shù)。

8. 獲取調(diào)度器狀態(tài)

8.1 函數(shù)描述

BaseType_t xTaskGetSchedulerState( void);

獲取調(diào)度器當(dāng)前狀態(tài)。在文件FreeRTOSConfig.h中,宏INCLUDE_xTaskGetSchedulerState或configUSE_TIMERS必須定義為1,此函數(shù)才有效。

8.2 返回值

返回值是以下常量之一(定義在task.h):taskSCHEDULER_NOT_STARTED(未啟動(dòng))、taskSCHEDULER_RUNNING(正常運(yùn)行)、taskSCHEDULER_SUSPENDED(掛起)。

9. 獲取任務(wù)總數(shù)

9.1 函數(shù)描述

UBaseType_t uxTaskGetNumberOfTasks(void );

獲取RTOS內(nèi)核當(dāng)前管理的任務(wù)總數(shù)。包含所有就緒、阻塞和掛起狀態(tài)的任務(wù)。對(duì)于一個(gè)刪除的任務(wù),如果它的堆??臻g還沒有被空閑任務(wù)釋放掉,則這個(gè)被刪除的任務(wù)也含在計(jì)數(shù)值中。

9.2 返回值

返回RTOS內(nèi)核當(dāng)前管理的任務(wù)總數(shù)。

10. 獲取所有任務(wù)詳情

10.1 函數(shù)描述

void vTaskList( char *pcWriteBuffer );

將每個(gè)任務(wù)的狀態(tài)、堆棧使用情況等以字符的形式保存到參數(shù)pcWriteBuffer指向的區(qū)域。vTaskList()函數(shù)調(diào)用usTaskGetSystemState()函數(shù),然后將得到的信息格式化為程序員易讀的字符形式。輸出的內(nèi)容例子如下圖所示,圖中State一欄中,B表示阻塞、R表示就緒、D表示刪除(等待清除內(nèi)存)、S表示掛起或阻塞。

注意,調(diào)用這個(gè)函數(shù)會(huì)掛起所有任務(wù),這一過程可能持續(xù)較長(zhǎng)時(shí)間,因此本函數(shù)僅在調(diào)試時(shí)使用。在文件FreeRTOSConfig.h中,宏configUSE_TRACE_FACILITY和configUSE_STATS_FORMATTING_FUNCTIONS必須定義為1,此函數(shù)才有效。

10.2 參數(shù)描述

pcWriteBuffer:任務(wù)的信息會(huì)寫入這個(gè)緩沖區(qū),為ASCII表單形式。這個(gè)緩沖區(qū)要足夠大,以容納生成的報(bào)告,每個(gè)任務(wù)大約需要40個(gè)字節(jié)。

11. 獲取任務(wù)運(yùn)行時(shí)間

11.1 函數(shù)描述

void vTaskGetRunTimeStats( char*pcWriteBuffer );

這個(gè)函數(shù)用于統(tǒng)計(jì)每個(gè)任務(wù)的運(yùn)行時(shí)間。要使用這個(gè)函數(shù)必須滿足一些條件,那就是必須有一個(gè)用于時(shí)間統(tǒng)計(jì)的定時(shí)器或計(jì)數(shù)器,這個(gè)定時(shí)器或計(jì)數(shù)器的精度要至少大于10倍的系統(tǒng)節(jié)拍周期。這個(gè)定時(shí)器或計(jì)數(shù)器的配置以及獲取定時(shí)時(shí)間是由兩個(gè)宏定義實(shí)現(xiàn)的,這兩個(gè)宏一般在文件FreeRTOSConfig.h中定義。配置定時(shí)器或計(jì)數(shù)器的宏為portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(),獲取定時(shí)時(shí)間的宏為portGET_RUN_TIME_COUNTER_VALUE。實(shí)現(xiàn)了這兩個(gè)宏定義后,還必須在文件FreeRTOSConfig.h中將宏configGENERATE_RUN_TIME_STATS和configUSE_STATS_FORMATTING_FUNCTIONS設(shè)置為1,此API函數(shù)才有效。

這個(gè)API函數(shù)調(diào)用usTaskGetSystemState()函數(shù)獲取每個(gè)任務(wù)的狀態(tài)信息,并把其中的運(yùn)行時(shí)間格式化為程序員易讀的字符形式,并將這些信息保存到參數(shù)pcWriteBuffer指向的區(qū)域。

注意,調(diào)用這個(gè)函數(shù)會(huì)掛起所有任務(wù),這一過程可能持續(xù)較長(zhǎng)時(shí)間,因此本函數(shù)僅在調(diào)試時(shí)使用。

11.2 參數(shù)描述

pcWriteBuffer:任務(wù)的運(yùn)行時(shí)間信息會(huì)寫入這個(gè)緩沖區(qū),為ASCII表單形式。這個(gè)緩沖區(qū)要足夠大,以容納生成的報(bào)告,每個(gè)任務(wù)大約需要40個(gè)字節(jié)。

11.3 用法舉例

lpc17xx系列為控制為例,我們使用定時(shí)器0來(lái)作為統(tǒng)計(jì)基準(zhǔn)時(shí)鐘。

11.3.1 使能函數(shù)宏

在文件FreeRTOSConfig.h中,設(shè)置宏configGENERATE_RUN_TIME_STATS和configUSE_STATS_FORMATTING_FUNCTIONS為1,

11.3.2 定時(shí)初始化定時(shí)器代碼

void vConfigureTimerForRunTimeStats( void ){ /* 使能定時(shí)器0的外設(shè)電源,配置外設(shè)時(shí)鐘 */ PCONP |= 0x02UL; PCLKSEL0 = (PCLKSEL0& (~(0x3《《2))) | (0x01 《《 2); /* 復(fù)位定時(shí)器 0 */ T0TCR = 0x02; /* 作為計(jì)數(shù)器 */ T0CTCR = 0x00; /* 預(yù)分頻,設(shè)置合適的分辨率即可 */ T0PR = ( configCPU_CLOCK_HZ / 10000UL ) - 1UL; /* 啟動(dòng)計(jì)數(shù)器 */ T0TCR = 0x01;}

11.3.3 定義配置定時(shí)器和獲取定時(shí)時(shí)間宏

在文件FreeRTOSConfig.h中,定義下列代碼:

extern void vConfigureTimerForRunTimeStats( void );#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()#defineportGET_RUN_TIME_COUNTER_VALUE() T0TC

12. 設(shè)置任務(wù)標(biāo)簽值

12.1 函數(shù)描述

voidvTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_tpxTagValue );

可以給每個(gè)任務(wù)分配一個(gè)標(biāo)簽值。這個(gè)值一般用于應(yīng)用程序,RTOS內(nèi)核不會(huì)使用。在文件FreeRTOSConfig.h中,宏configUSE_APPLICATION_TASK_TAG必須設(shè)置為1,此函數(shù)才有效。

12.2 參數(shù)描述

xTask:任務(wù)句柄。NULL表示當(dāng)前任務(wù)。

pxTagValue:要分配給任務(wù)的標(biāo)簽值。這是一個(gè)TaskHookFunction_t類型的函數(shù)指針,但也可以給任務(wù)標(biāo)簽分配任意的值。

注:TaskHookFunction_t原型定義:typedef BaseType_t (*TaskHookFunctio

12.3 用法舉例

/* 在這個(gè)例子中,給任務(wù)設(shè)置一個(gè)整形標(biāo)簽值。例子中使用了RTOS跟蹤鉤子宏。*/void vATask( void *pvParameters ){ /* 為自己的標(biāo)簽分配一個(gè)整形值 */ vTaskSetApplicationTaskTag( NULL, ( void * ) 1 ); for( ;; ) { /* 任務(wù)主體代碼

*/}}/*****************************************************************************/ /*在這個(gè)任務(wù)中,給任務(wù)設(shè)置一個(gè)函數(shù)標(biāo)簽值。首先定義一個(gè)回調(diào)函數(shù),這個(gè)函數(shù)必須聲明為TaskHookFunction_t類型。*/static BaseType_t prvExampleTaskHook( void * pvParameter ){ /* 這里為用戶定義代碼 –可能是記錄數(shù)據(jù)、更新任務(wù)狀態(tài)值等。*/ return 0;} /* 將回調(diào)函數(shù)設(shè)置為任務(wù)的標(biāo)簽值。*/void vAnotherTask( void *pvParameters ){ /* 注冊(cè)回調(diào)函數(shù)*/ vTaskSetApplicationTaskTag( NULL, prvExampleTaskHook ); for( ;; ) { /* 任務(wù)主體代碼 */ }} /* 每當(dāng)任務(wù)切換時(shí),會(huì)調(diào)用xTaskCallApplicationTaskHook 函數(shù)(見14.)。*/#define traceTASK_SWITCHED_OUT() xTaskCallApplicationTaskHook(pxCurrentTCB,0 )

13. 獲取任務(wù)標(biāo)簽值

13.1 函數(shù)描述

TaskHookFunction_txTaskGetApplicationTaskTag( TaskHandle_t xTask );

返回分配給任務(wù)的標(biāo)簽值。程序員定義標(biāo)簽值,RTOS內(nèi)核通常不會(huì)訪問標(biāo)簽值。

函數(shù)僅對(duì)高級(jí)用戶使用。在文件FreeRTOSConfig.h中,宏configUSE_APPLICATION_TASK_TAG必須設(shè)置為1,此函數(shù)才有效。

13.2 參數(shù)描述

xTask:任務(wù)句柄。NULL表示當(dāng)前任務(wù)。

13.3 返回值

返回指定任務(wù)的標(biāo)簽值。

14. 執(zhí)行任務(wù)的應(yīng)用鉤子函數(shù)

14.1 函數(shù)描述

BaseType_txTaskCallApplicationTaskHook( TaskHandle_txTask, void*pvParameter );

可以為每個(gè)任務(wù)分配一個(gè)標(biāo)簽值,當(dāng)這個(gè)值是一個(gè)TaskHookFunction_t類型函數(shù)指針時(shí),相當(dāng)于應(yīng)用程序向任務(wù)注冊(cè)了一個(gè)回調(diào)函數(shù),而API函數(shù)xTaskCallApplicationTaskHook用來(lái)調(diào)用這個(gè)回調(diào)函數(shù)。

一般這個(gè)函數(shù)配合RTOS跟蹤鉤子宏使用,見12.設(shè)置任務(wù)標(biāo)簽值一節(jié)的用法舉例。

14.2 參數(shù)描述

xTask:任務(wù)句柄。NULL表示當(dāng)前任務(wù)。 pvParameter:作為參數(shù)傳遞給應(yīng)用鉤子函數(shù)

15. 設(shè)置線程本地存儲(chǔ)指針

15.1 函數(shù)描述

void vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet, BaseType_t xIndex, void*pvValue )

此函數(shù)僅用于高級(jí)用戶。

線程本地存儲(chǔ)允許應(yīng)用程序在任務(wù)的控制塊中存儲(chǔ)一些值,每個(gè)任務(wù)都有自己獨(dú)立的儲(chǔ)存空間。

比如,許多庫(kù)函數(shù)都包含一個(gè)叫做errno的全局變量。某些庫(kù)函數(shù)使用errno返回庫(kù)函數(shù)錯(cuò)誤信息,應(yīng)用程序檢查這個(gè)全局變量來(lái)確定發(fā)生了那些錯(cuò)誤。在單線程程序中,將errno定義成全局變量是可以的,但是在多線程應(yīng)用中,每個(gè)線程(任務(wù))必須具有自己獨(dú)有的errno值,否則,一個(gè)任務(wù)可能會(huì)讀取到另一個(gè)任務(wù)的errno值。

FreeRTOS提供了一個(gè)靈活的機(jī)制,使得應(yīng)用程序可以使用線程本地存儲(chǔ)指針來(lái)讀寫線程本地存儲(chǔ)。在文件FreeRTOSConfig.h中,宏configNUM_THREAD_LOCAL_STORAGE_POINTERS指定每個(gè)任務(wù)線程本地存儲(chǔ)指針數(shù)組的大小。API函數(shù)vTaskSetThreadLocalStoragePointer()用于向指針數(shù)組中寫入值,API函數(shù)pvTaskGetThreadLocalStoragePointer()用于從指針數(shù)組中讀取值。

15.2 參數(shù)描述

xTaskToSet:任務(wù)句柄。NULL表示當(dāng)前任務(wù)。

xIndex:寫入到線程本地存儲(chǔ)數(shù)組的索引號(hào),線程本篤存儲(chǔ)數(shù)組的大小由宏configNUM_THREAD_LOCAL_STORAGE_POINTERS設(shè)定,該宏在文件FreeRTOSConfig.h中。

pvValue:寫入到指定索引地址的數(shù)據(jù)值

15.3 用法舉例

參見16.獲取線程本地存儲(chǔ)指針一節(jié)。

16. 讀取線程本地存儲(chǔ)指針

16.1 函數(shù)描述

void*pvTaskGetThreadLocalStoragePointer( TaskHandle_txTaskToQuery, BaseType_txIndex );

此函數(shù)僅用于高級(jí)用戶。從線程本地存儲(chǔ)指針數(shù)組中讀取值。更詳細(xì)描述見15.設(shè)置線程本地存儲(chǔ)指針一節(jié)。

16.2 參數(shù)描寫

xTaskToQuery:任務(wù)句柄。NULL表示當(dāng)前任務(wù)。

xIndex:寫入到線程本地存儲(chǔ)數(shù)組的索引號(hào),線程本篤存儲(chǔ)數(shù)組的大小由宏configNUM_THREAD_LOCAL_STORAGE_POINTERS設(shè)定,該宏在文件FreeRTOSConfig.h中。

16.3 返回值

返回一個(gè)指針,這個(gè)指針存儲(chǔ)在線程本地存儲(chǔ)指針數(shù)組中,數(shù)組索引由參數(shù)xIndex指定。

16.4 用法舉例

16.4.1 存儲(chǔ)一個(gè)整形數(shù)

uint32_tulVariable;

/* 向當(dāng)前任務(wù)的線程本地存儲(chǔ)數(shù)組下標(biāo)為1的位置寫入一個(gè)指向32位常量值的指針。*/vTaskSetThreadLocalStoragePointer(NULL, 1, ( void * ) 0x12345678 ); /*向當(dāng)前任務(wù)的線程本地存儲(chǔ)數(shù)組下標(biāo)為0的位置寫入一個(gè)指向32整形值的指針*/

ulVariable= ERROR_CODE;vTaskSetThreadLocalStoragePointer(NULL, 0, ( void * ) ulVariable ); /*從當(dāng)前任務(wù)的線程本地存儲(chǔ)數(shù)組下標(biāo)為5的位置讀取出一個(gè)指針并賦值給32位整形變量。*/ulVariable= ( uint32_t ) pvTaskGetThreadLocalStoragePointer( NULL, 5 );16.4.2存儲(chǔ)結(jié)構(gòu)提t(yī)ypedefstruct{ uint32_t ulValue1; uint32_t ulValue2;}xExampleStruct; xExampleStruct*pxStruct; /*為結(jié)構(gòu)體分配內(nèi)存*/pxStruct= pvPortMalloc( sizeof( xExampleStruct ) );

/*為結(jié)構(gòu)體成員賦值*/pxStruct-》ulValue1= 0;pxStruct-》ulValue2= 1; /*向當(dāng)前任務(wù)的線程本地存儲(chǔ)數(shù)組下標(biāo)為0的位置寫入一個(gè)指向結(jié)構(gòu)體變量的指針*/vTaskSetThreadLocalStoragePointer(NULL, 0, ( void * ) pxStruct ); /*從當(dāng)前任務(wù)的線程本地存儲(chǔ)數(shù)組下標(biāo)為0的位置讀取出一個(gè)結(jié)構(gòu)體指針*/pxStruct= ( xExampleStruct * ) pvTaskGetThreadLocalStoragePointer( NULL, 0 );

17. 設(shè)置超時(shí)狀態(tài)

17.1 函數(shù)描述

void vTaskSetTimeOutState( TimeOut_t *const pxTimeOut );

此函數(shù)僅用于高級(jí)用戶,通常與API函數(shù)xTaskCheckForTimeOut()共同使用。任務(wù)因?yàn)榈却呈录M(jìn)入阻塞狀態(tài),通常情況下任務(wù)會(huì)設(shè)置一個(gè)等待超時(shí)周期。如果在等待事件超時(shí),任務(wù)會(huì)退出阻塞狀態(tài)。想象一個(gè)這樣的應(yīng)用,某任務(wù)等待一個(gè)事件而進(jìn)入阻塞狀態(tài),但是事件遲遲不發(fā)生,超時(shí)后任務(wù)退出阻塞狀態(tài)繼續(xù)執(zhí)行任務(wù)。假如任務(wù)等待的事件仍然沒有發(fā)生,則任務(wù)又會(huì)阻塞在該事件下。只要任務(wù)等待的事件一直不發(fā)生,這個(gè)任務(wù)進(jìn)入阻塞然后超時(shí)退出阻塞,再進(jìn)入阻塞的循環(huán)就會(huì)一直存在。是不是可以設(shè)定一個(gè)總超時(shí)時(shí)間,只要總阻塞時(shí)間大于這個(gè)總超時(shí)時(shí)間,則可以結(jié)束這個(gè)任務(wù)或進(jìn)行相應(yīng)記錄?freeRTOS提供了兩個(gè)API函數(shù)來(lái)完成這個(gè)功能,這就是vTaskSetTimeOutState()和xTaskCheckForTimeOut()。

vTaskSetTimeOutState()函數(shù)用于設(shè)置初始條件,之后調(diào)用xTaskCheckForTimeOut()函數(shù)檢查任務(wù)總阻塞時(shí)間是否超過總超時(shí)時(shí)間,如果沒有超過,則調(diào)整剩余的超時(shí)時(shí)間計(jì)數(shù)器。

17.2 參數(shù)描述

pxTimeOut:指向一個(gè)結(jié)構(gòu)體的指針,該結(jié)構(gòu)體用來(lái)保存確定超時(shí)是否發(fā)生的必要信息。vTaskSetTimeOutState()函數(shù)會(huì)設(shè)置結(jié)構(gòu)體的成員。

17.3 用法舉例

參見18.超時(shí)檢測(cè)。

18. 超時(shí)檢測(cè)

18.1 函數(shù)描述

BaseType_t xTaskCheckForTimeOut(TimeOut_t * const pxTimeOut, TickType_t* const pxTicksToWait );

此函數(shù)僅用于高級(jí)用戶,通常與API函數(shù)vTaskSetTimeOutState共同使用。詳細(xì)描述見17.設(shè)置超時(shí)狀態(tài)。

18.2 參數(shù)描述

pxTimeOut:指向一個(gè)結(jié)構(gòu)體的指針。該結(jié)構(gòu)體保存確定超時(shí)是否發(fā)生的必要信息。使用API函數(shù)vTaskSetTimeOutState初始化該結(jié)構(gòu)體。

pxTicksToWait:TickType_t指針,指向的變量保存總超時(shí)時(shí)間。

18.3 返回值

pdTRUE:總超時(shí)發(fā)生

pdFALSE:總超時(shí)未發(fā)生

18.4 用法舉例

函數(shù)用于從RX緩沖區(qū)中接收uxWantedBytes字節(jié)數(shù)據(jù),RX緩沖區(qū)由UART中斷填充。如果RX緩沖區(qū)沒有足夠的數(shù)據(jù),則任務(wù)進(jìn)入阻塞狀態(tài),直到RX緩沖區(qū)有足夠數(shù)據(jù)或者發(fā)生超時(shí)。如果超時(shí)后仍然沒有足夠的數(shù)據(jù),則任務(wù)會(huì)再次進(jìn)入阻塞狀態(tài),xTaskCheckForTimeOut()函數(shù)用于重新計(jì)算總超時(shí)時(shí)間以確??傋枞麪顟B(tài)時(shí)間不超過MAX_TIME_TO_WAIT。如果總阻塞狀態(tài)時(shí)間大于了總超時(shí)時(shí)間,則不管RX緩沖區(qū)是否有充足數(shù)據(jù),都將這些數(shù)據(jù)讀出來(lái)。

size_txUART_Receive( uint8_t *pucBuffer, size_t uxWantedBytes ){ size_t uxReceived = 0; TickType_t xTicksToWait = MAX_TIME_TO_WAIT; TimeOut_t xTimeOut; /* 初始化結(jié)構(gòu)體變量xTimeOut。*/ vTaskSetTimeOutState( &xTimeOut ); /* 無(wú)限循環(huán),直到緩沖區(qū)包含足夠的數(shù)據(jù)或者阻塞超時(shí)發(fā)生。*/ while( UART_bytes_in_rx_buffer(pxUARTInstance ) 《 uxWantedBytes ) { /* RX緩沖區(qū)沒有足夠多的數(shù)據(jù),表示任務(wù)已經(jīng)進(jìn)入過一次阻塞狀態(tài)。調(diào)用API函數(shù)xTaskCheckForTimeOut檢查總阻塞時(shí)間是否超過總超時(shí)時(shí)間,如果沒有,則調(diào)整剩余的總超時(shí)時(shí)間。

*/ if( xTaskCheckForTimeOut( &xTimeOut,&xTicksToWait ) != pdFALSE ) { /* 如果總阻塞時(shí)間大于總超時(shí)時(shí)間,則退出這個(gè)循環(huán) */ break; } /* 在等待了xTicksToWait個(gè)系統(tǒng)節(jié)拍周期后,向接收中斷發(fā)出通知,需要更多數(shù)據(jù)。*/ ulTaskNotifyTake( pdTRUE, xTicksToWait ); } /*從RX緩沖區(qū)讀取uxWantedBytes個(gè)字節(jié)并放到pucBuffer緩沖區(qū)。*/ uxReceived = UART_read_from_receive_buffer(pxUARTInstance, pucBuffer, uxWantedBytes ); return uxReceived;}

原文標(biāo)題:FreeRTOS系列第12篇---FreeRTOS任務(wù)應(yīng)用函數(shù)

文章出處:【微信公眾號(hào):安芯教育科技】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

責(zé)任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • RTOS
    +關(guān)注

    關(guān)注

    22

    文章

    813

    瀏覽量

    119649
  • FreeRTOS
    +關(guān)注

    關(guān)注

    12

    文章

    484

    瀏覽量

    62182

原文標(biāo)題:FreeRTOS系列第12篇---FreeRTOS任務(wù)應(yīng)用函數(shù)

文章出處:【微信號(hào):Ithingedu,微信公眾號(hào):安芯教育科技】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    freertos最多支持多少個(gè)任務(wù)

    FreeRTOS是一個(gè)輕量級(jí)的實(shí)時(shí)操作系統(tǒng)(RTOS),其設(shè)計(jì)初衷就是為了提供簡(jiǎn)單、可靠且高效的實(shí)時(shí)任務(wù)管理。關(guān)于FreeRTOS最多支持多少個(gè)任務(wù)的問題,實(shí)際上并沒有一個(gè)固定的上限,
    的頭像 發(fā)表于 09-02 14:21 ?915次閱讀

    FreeRTOS中串口重定向使用HAL庫(kù)函數(shù)中斷出現(xiàn)異常的原因?

    由于需要使用到FreeRTOS 考慮到ISR優(yōu)先級(jí)會(huì)比任務(wù)優(yōu)先級(jí)高,并且查看HAL_UART_Transmit函數(shù)實(shí)現(xiàn)需要使用到systick 。 所以在重定義時(shí)使用了函數(shù)
    發(fā)表于 05-22 08:18

    請(qǐng)問一下FREERTOS只能創(chuàng)建4個(gè)任務(wù),修改哪個(gè)宏定義可以增加創(chuàng)建任務(wù)的數(shù)量?

    請(qǐng)問一下FREERTOS只能創(chuàng)建4個(gè)任務(wù),修改哪個(gè)宏定義可以增加創(chuàng)建任務(wù)的數(shù)量?解決方法:增加FREERTOS的堆。
    發(fā)表于 05-13 06:44

    淺析FreeRTOS任務(wù)調(diào)度器的三種調(diào)度算法和應(yīng)用

    FreeRTOS在MCU領(lǐng)域應(yīng)用非常廣泛,今天就給大家講解一下FreeRTOS調(diào)度器中的三種調(diào)度算法,以及在瑞薩RZ/T2L MPU中的應(yīng)用。
    的頭像 發(fā)表于 05-10 14:02 ?7446次閱讀
    淺析<b class='flag-5'>FreeRTOS</b><b class='flag-5'>任務(wù)</b>調(diào)度器的三種調(diào)度算法和應(yīng)用

    求助,關(guān)于stm32f1使用freeRTOS和Fatfs時(shí)任務(wù)堆棧大小問題求解

    哪位使用過freeRTOS和Fatfs時(shí),使用Fatfs系統(tǒng)的函數(shù)如f_open()等等時(shí),此任務(wù)的堆棧大小大致需要多大,當(dāng)前MAX_SS 定義為4096,我分配12K軟件都跑飛了,請(qǐng)哪位使用分享一下經(jīng)驗(yàn),謝謝!~~?
    發(fā)表于 05-09 06:50

    用的cube生成的freertos工程,串口和任務(wù)通過郵箱通訊,結(jié)果任務(wù)反應(yīng)很慢是怎么回事?

    初學(xué)freertos。用的cube生成的freertos工程,單片機(jī)型號(hào)位stm32f103vbt6。 建了三個(gè)人物,一個(gè)是串口任務(wù),一個(gè)是LED每秒翻轉(zhuǎn)一次,一個(gè)是空任務(wù)。 串口
    發(fā)表于 05-08 08:13

    freertos系統(tǒng)如何劃分任務(wù)?

    正在看freertos方面的教程,想請(qǐng)教下如何劃分任務(wù)? 比如之前做的一個(gè)數(shù)據(jù)采集板,用到了單片機(jī)以下功能: 1,單片機(jī)通過SPI1和ADC芯片通訊,同時(shí)還要通過SPI控制ADC電路部分的其他外圍
    發(fā)表于 05-08 07:16

    freertos如何周期性的執(zhí)行一個(gè)任務(wù),比如200ms調(diào)用一次任務(wù), 用定時(shí)器發(fā)消息?

    freertos如何周期性的執(zhí)行一個(gè)任務(wù),比如200ms調(diào)用一次任務(wù), 用定時(shí)器發(fā)消息?有沒有一個(gè)函數(shù)能直接實(shí)現(xiàn)
    發(fā)表于 05-07 08:21

    關(guān)于FreeRTOS任務(wù)劃分及comsis_os函數(shù)使用的疑問求解

    當(dāng)前任務(wù)掛起并喚醒下一個(gè)任務(wù)。比如在首頁(yè),接受到設(shè)置按鍵以后,就將當(dāng)前任務(wù)——首頁(yè)任務(wù)掛起,resume設(shè)置首頁(yè)任務(wù)。 請(qǐng)問這樣劃分行嗎?
    發(fā)表于 05-07 07:49

    FreeRTOS系統(tǒng)使用xTaskCreate產(chǎn)生的任務(wù)與osThreadDef 產(chǎn)生的線程有什么不同?

    請(qǐng)教下是要 FreeRTOS系統(tǒng), 使用 xTaskCreate 產(chǎn)生的任務(wù) 與 osThreadDef產(chǎn)生的線程有什么不同?
    發(fā)表于 04-29 07:20

    freertos任務(wù)創(chuàng)建,每一個(gè)任務(wù)分配的內(nèi)存是多大才好,怎么計(jì)算呢?

    小白剛剛接觸freertos,想問一下就創(chuàng)建任務(wù)而言,每一個(gè)任務(wù)分配的內(nèi)存是多大才好,怎么計(jì)算呢? 另外,每個(gè)任務(wù)的執(zhí)行周期怎么確定?在任務(wù)
    發(fā)表于 04-23 06:39

    為什么CubeMX設(shè)計(jì)的FreeRTOS工程只能正常運(yùn)行3個(gè)任務(wù)?

    用CubeMX4.20設(shè)計(jì)的FreeRTOS工程有六個(gè)任務(wù),出一個(gè)任務(wù)優(yōu)先級(jí)較低外,另外幾個(gè)都是較高優(yōu)先級(jí)。發(fā)現(xiàn)只有3個(gè)任務(wù)是正常運(yùn)行的,還有三個(gè)沒有運(yùn)行的跡象。用斷點(diǎn)跟蹤法在
    發(fā)表于 04-19 08:23

    FreeRTOS里在中斷中掛起任務(wù)出錯(cuò)的原因?怎么解決?

    各位大佬,新手剛學(xué)習(xí)FreeRTOS,現(xiàn)在想在中斷中掛起某個(gè)任務(wù),我在教程里看到說(shuō)有中斷中的恢復(fù)函數(shù)xTaskResumeFromISR,但是沒有在中斷中的掛起函數(shù),我搜了一下,有人說(shuō)
    發(fā)表于 04-16 08:26

    FreeRTOS任務(wù)無(wú)故進(jìn)入掛起狀態(tài)的原因?

    請(qǐng)教大家一個(gè)問題,我子啊使用FreeRTOS的時(shí)候創(chuàng)建了一個(gè)以太網(wǎng)的任務(wù),任務(wù)在使用的過程中被無(wú)故掛起,請(qǐng)問一下出現(xiàn)這種現(xiàn)象有哪幾種原因呢?
    發(fā)表于 04-09 07:20

    verilog中函數(shù)任務(wù)對(duì)比

    在verilog中,函數(shù)任務(wù)均用來(lái)描述共同的代碼段,并且在模式內(nèi)任意位置被調(diào)用,提高代碼效率,讓代碼更加的直觀,提高代碼可讀性。但是在實(shí)際使用的過程中,函數(shù)任務(wù)也存在諸多的不同,下
    的頭像 發(fā)表于 02-12 18:43 ?892次閱讀