網(wǎng)站首頁 編程語言 正文
任務應用函數(shù)是一組輔助類函數(shù),一般用于調(diào)試信息輸出、獲取任務句柄、獲取任務狀態(tài)、操作任務標簽值等等。
1.獲取任務系統(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)中每一個任務的信息都可以填充到TaskStatus_t結(jié)構(gòu)體數(shù)組中,數(shù)組大小由uxArraySize指定。結(jié)構(gòu)體TaskStatus_t定義如下:
typedef struct xTASK_STATUS { /* 任務句柄*/ TaskHandle_t xHandle; /* 指針,指向任務名*/ const signed char *pcTaskName; /*任務ID,是一個獨一無二的數(shù)字*/ UBaseType_t xTaskNumber; /*填充結(jié)構(gòu)體時,任務當前的狀態(tài)(運行、就緒、掛起等等)*/ eTaskState eCurrentState; /*填充結(jié)構(gòu)體時,任務運行(或繼承)的優(yōu)先級。*/ UBaseType_t uxCurrentPriority; /* 當任務因繼承而改變優(yōu)先級時,該變量保存任務最初的優(yōu)先級。僅當configUSE_MUTEXES定義為1有效。*/ UBaseType_t uxBasePriority; /* 分配給任務的總運行時間。僅當宏configGENERATE_RUN_TIME_STATS為1時有效。*/ unsigned long ulRunTimeCounter; /* 從任務創(chuàng)建起,堆棧剩余的最小數(shù)量,這個值越接近0,堆棧溢出的可能越大。 */ unsigned short usStackHighWaterMark; }TaskStatus_t;
注意,這個函數(shù)僅用來調(diào)試用,調(diào)用此函數(shù)會掛起所有任務,直到函數(shù)最后才恢復掛起的任務,因此任務可能被掛起很長時間。在文件FreeRTOSConfig.h中,宏configUSE_TRACE_FACILITY必須設置為1,此函數(shù)才有效。
1.2參數(shù)描述
pxTaskStatusArray
:指向TaskStatus_t類型的結(jié)構(gòu)體數(shù)組。這個數(shù)組至少要包含1個元素。RTOS控制的任務數(shù)量可以使用API函數(shù)uxTaskGetNumberOfTasks()獲取。
uxArraySize
:參數(shù)pxTaskStatusArray指向的數(shù)組大小,也就是該數(shù)組的索引數(shù)目。
pulTotalRunTime
:如果在文件FreeRTOSConfig.h中設置宏configGENERATE_RUN_TIME_STATS為1,則該函數(shù)將總運行時間寫入*pulTotalRunTime中。pulTotalRunTime可以設置為NULL,表示忽略總運行時間。
1.3返回值
被填充的TaskStatus_t結(jié)構(gòu)體數(shù)量。這個值應該等于通過調(diào)用API函數(shù)uxTaskGetNumberOfTasks()返回的值,但如果傳遞給uxArraySize參數(shù)的值太小,則返回0。
1.4用法舉例
/*本例演示如是使用uxTaskGetSystemState()函數(shù)來獲取運行時間信息,并將其轉(zhuǎn)化為程序員更易識別的字符格式,這些轉(zhuǎn)化后的字符保存到pcWriteBuffer中。*/ void vTaskGetRunTimeStats(signed char *pcWriteBuffer ) { TaskStatus_t*pxTaskStatusArray; volatileUBaseType_t uxArraySize, x; unsignedlong ulTotalRunTime, ulStatsAsPercentage; /* 防御性代碼,確保字符串有合理的結(jié)束*/ *pcWriteBuffer = 0x00; /* 獲取任務總數(shù)目*/ uxArraySize = uxTaskGetNumberOfTasks (); /*為每個任務的TaskStatus_t結(jié)構(gòu)體分配內(nèi)存,也可以靜態(tài)的分配一個足夠大的數(shù)組 */ pxTaskStatusArray = pvPortMalloc( uxArraySize * sizeof( TaskStatus_t )); if(pxTaskStatusArray != NULL ) { /*獲取每個任務的狀態(tài)信息 */ uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize,&ulTotalRunTime ); /* 百分比計算 */ ulTotalRunTime /= 100UL; /* 避免除零錯誤 */ if(ulTotalRunTime > 0 ) { /* 將獲得的每一個任務狀態(tài)信息部分的轉(zhuǎn)化為程序員容易識別的字符串格式*/ for( x = 0; x < uxArraySize; x++ ) { /* 計算任務運行時間與總運行時間的百分比。*/ ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter /ulTotalRunTime; if( ulStatsAsPercentage > 0UL ) { sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage ); } else { /* 任務運行時間不足總運行時間的1%*/ sprintf( pcWriteBuffer, "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[x ].ulRunTimeCounter ); } pcWriteBuffer += strlen( ( char * ) pcWriteBuffer ); } } /* 釋放之前申請的內(nèi)存*/ vPortFree( pxTaskStatusArray ); } }
2.獲取當前任務句柄
2.1函數(shù)描述
TaskHandle_t xTaskGetCurrentTaskHandle(void );
在文件FreeRTOSConfig.h中,宏INCLUDE_xTaskGetCurrentTaskHandle必須設置為1,此函數(shù)才有效。
2.2返回值
返回當前任務(調(diào)用該函數(shù)的任務)的句柄。
3.獲取空閑任務句柄
3.1函數(shù)描述
TaskHandle_t xTaskGetIdleTaskHandle(void );
在文件FreeRTOSConfig.h中,宏INCLUDE_xTaskGetIdleTaskHandle必須設置為1,此函數(shù)才有效。
3.2返回值
返回空閑任務句柄。空閑任務在RTOS調(diào)度器啟動時自動創(chuàng)建。
4.獲取任務堆棧最大使用深度
4.1函數(shù)描述
UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );
任務的堆棧空間會隨著任務執(zhí)行以及中斷處理而增長或縮小。該函數(shù)可以返回任務啟動后的最小剩余堆棧空間。換句話說,可以間接估算出一個任務最多需要多少堆棧空間。在文件FreeRTOSConfig.h中,宏INCLUDE_uxTaskGetStackHighWaterMark 必須設置成1,此函數(shù)才有效。
4.2參數(shù)描述
xTask:任務句柄。NULL表示查看當前任務的堆棧使用情況。
4.3返回值
返回最小剩余堆棧空間,以字為單位。比如一個32為架構(gòu)處理器,返回值為1表示有4字節(jié)堆棧空間沒有使用過。如果返回值為0,則任務很可能已經(jīng)發(fā)生了堆棧溢出。
4.4用法舉例
void vTask1( void * pvParameters ) { UBaseType_tuxHighWaterMark; /* 入口處檢測一次 */ uxHighWaterMark =uxTaskGetStackHighWaterMark( NULL ); for( ;; ) { /* 正常調(diào)用函數(shù) */ vTaskDelay( 1000 ); /* 測量堆棧使用情況 */ uxHighWaterMark =uxTaskGetStackHighWaterMark( NULL ); } }
5.獲取任務狀態(tài)
5.1函數(shù)描述
eTaskState eTaskGetState( TaskHandle_txTask );
返回一個枚舉類型的任務狀態(tài)值。在文件FreeRTOSConfig.h中,宏INCLUDE_eTaskGetState必須設置為1,此函數(shù)才有效。
5.2參數(shù)描述
xTask:任務句柄
5.3返回值
下表列出返回值和對應的任務狀態(tài)。
6.獲取任務描述內(nèi)容
6.1函數(shù)描述
char * pcTaskGetTaskName( TaskHandle_txTaskToQuery );
獲取任務的描述內(nèi)容,在文件FreeRTOSConfig.h中,宏INCLUDE_pcTaskGetTaskName必須設置成1,此函數(shù)才有效。
6.2參數(shù)描述
xTaskToQuery:任務的句柄。NULL表示獲取當前任務的描述內(nèi)容指針。
6.3返回值
一個指針,指向任務描述字符串。
7.獲取系統(tǒng)節(jié)拍次數(shù)
7.1函數(shù)描述
volatile TickType_t xTaskGetTickCount(void );
這個函數(shù)不能在ISR中調(diào)用。在ISR中用xTaskGetTickCountFromISR(),原型為volatileTickType_t xTaskGetTickCountFromISR( void )。
7.2返回值
返回從vTaskStartScheduler函數(shù)調(diào)用后的系統(tǒng)時鐘節(jié)拍次數(shù)。
8.獲取調(diào)度器狀態(tài)
8.1函數(shù)描述
BaseType_t xTaskGetSchedulerState( void);
獲取調(diào)度器當前狀態(tài)。在文件FreeRTOSConfig.h中,宏INCLUDE_xTaskGetSchedulerState或configUSE_TIMERS必須定義為1,此函數(shù)才有效。
8.2返回值
&&&返回值是以下常量之一(定義在task.h):taskSCHEDULER_NOT_STARTED(未啟動)、taskSCHEDULER_RUNNING(正常運行)、taskSCHEDULER_SUSPENDED(掛起)。
9.獲取任務總數(shù)
9.1函數(shù)描述
UBaseType_t uxTaskGetNumberOfTasks(void );
&&&獲取RTOS內(nèi)核當前管理的任務總數(shù)。包含所有就緒、阻塞和掛起狀態(tài)的任務。對于一個刪除的任務,如果它的堆棧空間還沒有被空閑任務釋放掉,則這個被刪除的任務也含在計數(shù)值中。
9.2返回值
&&&返回RTOS內(nèi)核當前管理的任務總數(shù)。
10.獲取所有任務詳情
10.1函數(shù)描述
void vTaskList( char *pcWriteBuffer );
&&&將每個任務的狀態(tài)、堆棧使用情況等以字符的形式保存到參數(shù)pcWriteBuffer指向的區(qū)域。vTaskList()函數(shù)調(diào)用usTaskGetSystemState()函數(shù),然后將得到的信息格式化為程序員易讀的字符形式。輸出的內(nèi)容例子如下圖所示,圖中State一欄中,B表示阻塞、R表示就緒、D表示刪除(等待清除內(nèi)存)、S表示掛起或阻塞。
&&&注意,調(diào)用這個函數(shù)會掛起所有任務,這一過程可能持續(xù)較長時間,因此本函數(shù)僅在調(diào)試時使用。在文件FreeRTOSConfig.h中,宏configUSE_TRACE_FACILITY和configUSE_STATS_FORMATTING_FUNCTIONS必須定義為1,此函數(shù)才有效。
10.2參數(shù)描述
pcWriteBuffer:任務的信息會寫入這個緩沖區(qū),為ASCII表單形式。這個緩沖區(qū)要足夠大,以容納生成的報告,每個任務大約需要40個字節(jié)。
11.獲取任務運行時間
11.1函數(shù)描述
void vTaskGetRunTimeStats( char*pcWriteBuffer );
這個函數(shù)用于統(tǒng)計每個任務的運行時間。要使用這個函數(shù)必須滿足一些條件,那就是必須有一個用于時間統(tǒng)計的定時器或計數(shù)器,這個定時器或計數(shù)器的精度要至少大于10倍的系統(tǒng)節(jié)拍周期。這個定時器或計數(shù)器的配置以及獲取定時時間是由兩個宏定義實現(xiàn)的,這兩個宏一般在文件FreeRTOSConfig.h中定義。配置定時器或計數(shù)器的宏為portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(),獲取定時時間的宏為portGET_RUN_TIME_COUNTER_VALUE。實現(xiàn)了這兩個宏定義后,還必須在文件FreeRTOSConfig.h中將宏configGENERATE_RUN_TIME_STATS和configUSE_STATS_FORMATTING_FUNCTIONS設置為1,此API函數(shù)才有效。
&&&這個API函數(shù)調(diào)用usTaskGetSystemState()函數(shù)獲取每個任務的狀態(tài)信息,并把其中的運行時間格式化為程序員易讀的字符形式,并將這些信息保存到參數(shù)pcWriteBuffer指向的區(qū)域。
&&&注意,調(diào)用這個函數(shù)會掛起所有任務,這一過程可能持續(xù)較長時間,因此本函數(shù)僅在調(diào)試時使用。
11.2參數(shù)描述
pcWriteBuffer:任務的運行時間信息會寫入這個緩沖區(qū),為ASCII表單形式。這個緩沖區(qū)要足夠大,以容納生成的報告,每個任務大約需要40個字節(jié)。
11.3用法舉例
&&&以lpc17xx系列為控制為例,我們使用定時器0來作為統(tǒng)計基準時鐘。
11.3.1使能函數(shù)宏
&&&在文件FreeRTOSConfig.h中,設置宏configGENERATE_RUN_TIME_STATS和configUSE_STATS_FORMATTING_FUNCTIONS為1,
11.3.2定時初始化定時器代碼
void vConfigureTimerForRunTimeStats( void ) { /* 使能定時器0的外設電源,配置外設時鐘 */ PCONP |= 0x02UL; PCLKSEL0 = (PCLKSEL0& (~(0x3<<2))) | (0x01 << 2); /* 復位定時器 0 */ T0TCR = 0x02; /* 作為計數(shù)器 */ T0CTCR = 0x00; /* 預分頻,設置合適的分辨率即可 */ T0PR = ( configCPU_CLOCK_HZ / 10000UL ) - 1UL; /* 啟動計數(shù)器 */ T0TCR = 0x01; }
11.3.3定義配置定時器和獲取定時時間宏
&&&在文件FreeRTOSConfig.h中,定義下列代碼:
extern void vConfigureTimerForRunTimeStats( void ); #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats() #defineportGET_RUN_TIME_COUNTER_VALUE() T0TC
12.設置任務標簽值
12.1函數(shù)描述
voidvTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_tpxTagValue );
&&&可以給每個任務分配一個標簽值。這個值一般用于應用程序,RTOS內(nèi)核不會使用。在文件FreeRTOSConfig.h中,宏configUSE_APPLICATION_TASK_TAG必須設置為1,此函數(shù)才有效。
12.2參數(shù)描述
xTask:任務句柄。NULL表示當前任務。pxTagValue:要分配給任務的標簽值。這是一個TaskHookFunction_t類型的函數(shù)指針,但也可以給任務標簽分配任意的值。
注:TaskHookFunction_t原型定義:typedef BaseType_t (*TaskHookFunction_t)(void * )
12.3用法舉例
/* 在這個例子中,給任務設置一個整形標簽值。例子中使用了RTOS跟蹤鉤子宏。*/ void vATask( void *pvParameters ) { /* 為自己的標簽分配一個整形值 */ vTaskSetApplicationTaskTag( NULL, ( void * ) 1 ); for( ;; ) { /* 任務主體代碼 */ } } /*****************************************************************************/ /*在這個任務中,給任務設置一個函數(shù)標簽值。首先定義一個回調(diào)函數(shù),這個函數(shù)必須聲明為TaskHookFunction_t類型。 */ static BaseType_t prvExampleTaskHook( void * pvParameter ) { /* 這里為用戶定義代碼 –可能是記錄數(shù)據(jù)、更新任務狀態(tài)值等。*/ return 0; } /* 將回調(diào)函數(shù)設置為任務的標簽值。 */ void vAnotherTask( void *pvParameters ) { /* 注冊回調(diào)函數(shù)*/ vTaskSetApplicationTaskTag( NULL, prvExampleTaskHook ); for( ;; ) { /* 任務主體代碼 */ } } /* 每當任務切換時,會調(diào)用xTaskCallApplicationTaskHook 函數(shù)(見14.)。 */ #define traceTASK_SWITCHED_OUT() xTaskCallApplicationTaskHook(pxCurrentTCB,0 )
13.獲取任務標簽值
13.1函數(shù)描述
TaskHookFunction_txTaskGetApplicationTaskTag( TaskHandle_t xTask );
返回分配給任務的標簽值。程序員定義標簽值,RTOS內(nèi)核通常不會訪問標簽值。
函數(shù)僅對高級用戶使用。在文件FreeRTOSConfig.h中,宏configUSE_APPLICATION_TASK_TAG必須設置為1,此函數(shù)才有效。
13.2參數(shù)描述
xTask:任務句柄。NULL表示當前任務。
13.3返回值
返回指定任務的標簽值。
14.執(zhí)行任務的應用鉤子函數(shù)
14.1函數(shù)描述
BaseType_txTaskCallApplicationTaskHook( TaskHandle_txTask, void*pvParameter );
可以為每個任務分配一個標簽值,當這個值是一個TaskHookFunction_t類型函數(shù)指針時,相當于應用程序向任務注冊了一個回調(diào)函數(shù),而API函數(shù)xTaskCallApplicationTaskHook用來調(diào)用這個回調(diào)函數(shù)。
一般這個函數(shù)配合RTOS跟蹤鉤子宏使用,見12.設置任務標簽值一節(jié)的用法舉例。
14.2參數(shù)描述
xTask:任務句柄。NULL表示當前任務。pvParameter:作為參數(shù)傳遞給應用鉤子函數(shù)
15.設置線程本地存儲指針
15.1函數(shù)描述
void vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet, BaseType_t xIndex, void*pvValue )
此函數(shù)僅用于高級用戶。
線程本地存儲允許應用程序在任務的控制塊中存儲一些值,每個任務都有自己獨立的儲存空間。
比如,許多庫函數(shù)都包含一個叫做errno的全局變量。某些庫函數(shù)使用errno返回庫函數(shù)錯誤信息,應用程序檢查這個全局變量來確定發(fā)生了那些錯誤。在單線程程序中,將errno定義成全局變量是可以的,但是在多線程應用中,每個線程(任務)必須具有自己獨有的errno值,否則,一個任務可能會讀取到另一個任務的errno值。
FreeRTOS提供了一個靈活的機制,使得應用程序可以使用線程本地存儲指針來讀寫線程本地存儲。在文件FreeRTOSConfig.h中,宏configNUM_THREAD_LOCAL_STORAGE_POINTERS指定每個任務線程本地存儲指針數(shù)組的大小。API函數(shù)vTaskSetThreadLocalStoragePointer()用于向指針數(shù)組中寫入值,API函數(shù)pvTaskGetThreadLocalStoragePointer()用于從指針數(shù)組中讀取值。
15.2參數(shù)描述
xTaskToSet
:任務句柄。NULL表示當前任務。
xIndex
:寫入到線程本地存儲數(shù)組的索引號,線程本篤存儲數(shù)組的大小由宏configNUM_THREAD_LOCAL_STORAGE_POINTERS設定,該宏在文件FreeRTOSConfig.h中。
pvValue
:寫入到指定索引地址的數(shù)據(jù)值
15.3用法舉例
&&參見16.獲取線程本地存儲指針一節(jié)。
16.讀取線程本地存儲指針
16.1函數(shù)描述
void*pvTaskGetThreadLocalStoragePointer( TaskHandle_txTaskToQuery, BaseType_txIndex );
此函數(shù)僅用于高級用戶。從線程本地存儲指針數(shù)組中讀取值。更詳細描述見15.設置線程本地存儲指針一節(jié)。
16.2參數(shù)描寫
xTaskToQuery
:任務句柄。NULL表示當前任務。
xIndex
:寫入到線程本地存儲數(shù)組的索引號,線程本篤存儲數(shù)組的大小由宏configNUM_THREAD_LOCAL_STORAGE_POINTERS設定,該宏在文件FreeRTOSConfig.h中。
16.3返回值
返回一個指針,這個指針存儲在線程本地存儲指針數(shù)組中,數(shù)組索引由參數(shù)xIndex指定。
16.4用法舉例
16.4.1存儲一個整形數(shù)
uint32_tulVariable; /* 向當前任務的線程本地存儲數(shù)組下標為1的位置寫入一個指向32位常量值的指針。*/ vTaskSetThreadLocalStoragePointer(NULL, 1, ( void * ) 0x12345678 ); /*向當前任務的線程本地存儲數(shù)組下標為0的位置寫入一個指向32整形值的指針*/ ulVariable= ERROR_CODE; vTaskSetThreadLocalStoragePointer(NULL, 0, ( void * ) ulVariable ); /*從當前任務的線程本地存儲數(shù)組下標為5的位置讀取出一個指針并賦值給32位整形變量。*/ ulVariable= ( uint32_t ) pvTaskGetThreadLocalStoragePointer( NULL, 5 );
16.4.2存儲結(jié)構(gòu)提
typedefstruct { 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; /*向當前任務的線程本地存儲數(shù)組下標為0的位置寫入一個指向結(jié)構(gòu)體變量的指針*/ vTaskSetThreadLocalStoragePointer(NULL, 0, ( void * ) pxStruct ); /*從當前任務的線程本地存儲數(shù)組下標為0的位置讀取出一個結(jié)構(gòu)體指針*/ pxStruct= ( xExampleStruct * ) pvTaskGetThreadLocalStoragePointer( NULL, 0 );
17.設置超時狀態(tài)
17.1函數(shù)描述
void vTaskSetTimeOutState( TimeOut_t *const pxTimeOut );
此函數(shù)僅用于高級用戶,通常與API函數(shù)xTaskCheckForTimeOut()共同使用。
任務因為等待某事件而進入阻塞狀態(tài),通常情況下任務會設置一個等待超時周期。如果在等待事件超時,任務會退出阻塞狀態(tài)。想象一個這樣的應用,某任務等待一個事件而進入阻塞狀態(tài),但是事件遲遲不發(fā)生,超時后任務退出阻塞狀態(tài)繼續(xù)執(zhí)行任務。假如任務等待的事件仍然沒有發(fā)生,則任務又會阻塞在該事件下。只要任務等待的事件一直不發(fā)生,這個任務進入阻塞然后超時退出阻塞,再進入阻塞的循環(huán)就會一直存在。是不是可以設定一個總超時時間,只要總阻塞時間大于這個總超時時間,則可以結(jié)束這個任務或進行相應記錄?freeRTOS提供了兩個API函數(shù)來完成這個功能,這就是vTaskSetTimeOutState()和xTaskCheckForTimeOut()。
vTaskSetTimeOutState()函數(shù)用于設置初始條件,之后調(diào)用xTaskCheckForTimeOut()函數(shù)檢查任務總阻塞時間是否超過總超時時間,如果沒有超過,則調(diào)整剩余的超時時間計數(shù)器。
17.2參數(shù)描述
pxTimeOut:指向一個結(jié)構(gòu)體的指針,該結(jié)構(gòu)體用來保存確定超時是否發(fā)生的必要信息。vTaskSetTimeOutState()函數(shù)會設置結(jié)構(gòu)體的成員。
17.3用法舉例
參見18.超時檢測。
18.超時檢測
18.1函數(shù)描述
BaseType_t xTaskCheckForTimeOut(TimeOut_t * const pxTimeOut, TickType_t* const pxTicksToWait );
此函數(shù)僅用于高級用戶,通常與API函數(shù)vTaskSetTimeOutState共同使用。
詳細描述見17.設置超時狀態(tài)。
18.2參數(shù)描述
pxTimeOut
:指向一個結(jié)構(gòu)體的指針。該結(jié)構(gòu)體保存確定超時是否發(fā)生的必要信息。使用API函數(shù)vTaskSetTimeOutState初始化該結(jié)構(gòu)體。
pxTicksToWait
:TickType_t指針,指向的變量保存總超時時間。
18.3返回值
pdTRUE:總超時發(fā)生pdFALSE:總超時未發(fā)生
18.4用法舉例
/* 函數(shù)用于從RX緩沖區(qū)中接收uxWantedBytes字節(jié)數(shù)據(jù),RX緩沖區(qū)由UART中斷填充。如果RX緩沖區(qū)沒有足夠的數(shù)據(jù),則任務進入阻塞狀態(tài),直到RX緩沖區(qū)有足夠數(shù)據(jù)或者發(fā)生超時。如果超時后仍然沒有足夠的數(shù)據(jù),則任務會再次進入阻塞狀態(tài),xTaskCheckForTimeOut()函數(shù)用于重新計算總超時時間以確保總阻塞狀態(tài)時間不超過MAX_TIME_TO_WAIT。如果總阻塞狀態(tài)時間大于了總超時時間,則不管RX緩沖區(qū)是否有充足數(shù)據(jù),都將這些數(shù)據(jù)讀出來。 */ 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 ); /* 無限循環(huán),直到緩沖區(qū)包含足夠的數(shù)據(jù)或者阻塞超時發(fā)生。*/ while( UART_bytes_in_rx_buffer(pxUARTInstance ) < uxWantedBytes ) { /* RX緩沖區(qū)沒有足夠多的數(shù)據(jù),表示任務已經(jīng)進入過一次阻塞狀態(tài)。調(diào)用API函數(shù)xTaskCheckForTimeOut檢查總阻塞時間是否超過總超時時間,如果沒有,則調(diào)整剩余的總超時時間。*/ if( xTaskCheckForTimeOut( &xTimeOut,&xTicksToWait ) != pdFALSE ) { /* 如果總阻塞時間大于總超時時間,則退出這個循環(huán) */ break; } /* 在等待了xTicksToWait個系統(tǒng)節(jié)拍周期后,向接收中斷發(fā)出通知,需要更多數(shù)據(jù)。 */ ulTaskNotifyTake( pdTRUE, xTicksToWait ); } /*從RX緩沖區(qū)讀取uxWantedBytes個字節(jié)并放到pucBuffer緩沖區(qū)。*/ uxReceived = UART_read_from_receive_buffer(pxUARTInstance, pucBuffer, uxWantedBytes ); return uxReceived; }
原文鏈接:https://freertos.blog.csdn.net/article/details/50498173
相關(guān)推薦
- 2022-07-11 CentOS 7安裝SQL Server 2019
- 2025-02-10 window11 系統(tǒng)安裝 yarn
- 2022-08-31 python中ndarray數(shù)組的索引和切片的使用_python
- 2022-10-02 Selenium+Python自動化測試入門_python
- 2022-08-11 python使用prettytable內(nèi)置庫美化輸出表格_python
- 2022-04-01 k8s集群中移除節(jié)點后重新加入
- 2022-12-02 React?Hook中的useState函數(shù)的詳細解析_React
- 2022-05-10 一文帶你了解中Typescript中type與interface的區(qū)別
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支