FreeRTOS為操作隊列提供了非常豐富的API函數(shù),包括隊列的創(chuàng)建、刪除,靈活的入隊和出隊方式、帶中斷保護的入隊和出隊等等。下面就來詳細講述這些API函數(shù)。 1.獲取隊列入隊信息數(shù)目1.1函數(shù)描述 UBaseType_t uxQueueMessagesWaiting( QueueHandle_t xQueue ); 返回隊列中存儲的信息數(shù)目。具有中斷保護的版本為uxQueueMessagesWaitingFromISR(),原型為:UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue )。 1.2參數(shù)描述2.獲取隊列的空閑數(shù)目2.1函數(shù)描述 UBaseType_t uxQueueSpacesAvailable( QueueHandle_t xQueue ); 返回隊列的空閑數(shù)目。 2.2參數(shù)描述3.刪除隊列3.1函數(shù)描述 void vQueueDelete( QueueHandle_t xQueue ); 刪除隊列并釋放所有分配給隊列的內(nèi)存。 3.2參數(shù)描述 4.復位隊列4.1函數(shù)描述 BaseType_t xQueueReset( QueueHandle_t xQueue ); 將隊列復位到初始狀態(tài)。 4.2參數(shù)描述4.3返回值 FreeRTOSV7.2.0以及以后的版本總是返回pdPASS。 5.創(chuàng)建隊列5.1函數(shù)描述 QueueHandle_t xQueueCreate (UBaseType_t uxQueueLength, UBaseType_t uxItemSize); 創(chuàng)建新隊列。為新隊列分配指定的存儲空間并返回隊列句柄。 5.2參數(shù)描述- usQueueLength:隊列項數(shù)目
- uxItemSize:每個隊列項大小,單位是字節(jié)。隊列項通過拷貝入隊而不是通過引用入隊,因此需要隊列項的大小。每個隊列項的大小必須相同。
5.3返回值 成功創(chuàng)建隊列返回隊列句柄,否自返回0。 5.4用法舉例 void vATask( void*pvParameters ) xQueueHandle xQueue1, xQueue2; // 創(chuàng)建一個隊列,隊列能包含10個unsigned long類型的值。 xQueue1 = xQueueCreate( 10, sizeof( unsigned portLONG )); // 創(chuàng)建一個隊列,隊列能包含10個 Amessage結(jié)構(gòu)體指針類型的值。 // 這樣可以通過傳遞指針變量來包含大量數(shù)據(jù)。 xQueue2 =xQueueCreate( 10, sizeof( struct AMessage * ) );
6.向隊列投遞隊列項6.1 函數(shù)描述 BaseType_t xQueueSend(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait ); 其實是一個宏,真正被調(diào)用的函數(shù)是xQueueGenericSend()。定義這個宏是為了向后兼容那些不包含函數(shù)xQueueSendToFront()和xQueueSendToBack()宏的FreeRTOS版本。它與xQueueSendToBack()等同。 這個宏向隊列尾部投遞一個隊列項。項目以拷貝的形式入隊,而不是引用形式入隊。絕不可以在中斷服務例程中調(diào)用這個宏,使用帶有中斷保護的版本xQueueSendFromISR()來完成相同的功能。 6.2參數(shù)描述 - xQueue:隊列句柄。
- pvItemToQueue:指針,指向要入隊的項目。要保存到隊列中的項目字節(jié)數(shù)在隊列創(chuàng)建時就已確定。因此要從指針pvItemToQueue指向的區(qū)域拷貝到隊列存儲區(qū)域的字節(jié)數(shù),也已確定。
- xTicksToWait:如果隊列滿,任務等待隊列空閑的最大時間。如果隊列滿并且xTicksToWait被設置成0,函數(shù)立刻返回。時間單位為系統(tǒng)節(jié)拍時鐘周期,因此宏portTICK_PERIOD_MS可以用來輔助計算真實延時值。如果INCLUDE_vTaskSuspend設置成1,并且指定延時為portMAX_DELAY將引起任務無限阻塞(沒有超時)。
6.3返回值 隊列項入隊成功返回pdTRUE,否則返回errQUEUE_FULL。 6.4用法舉例 unsigned portLONG ulVar = 10UL; void vATask( void *pvParameters ) xQueueHandle xQueue1, xQueue2; struct AMessage *pxMessage; /*創(chuàng)建一個隊列,隊列能包含10個unsigned long類型的值。*/ xQueue1 = xQueueCreate( 10, sizeof( unsigned portLONG ) ); /* 創(chuàng)建一個隊列,隊列能包含10個 Amessage結(jié)構(gòu)體指針類型的值。 這樣可以通過傳遞指針變量來包含大量數(shù)據(jù)。*/ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) ); /*1個unsigned long型數(shù)據(jù)入隊.如果需要等待隊列空間變的有效, 會最多等待10個系統(tǒng)節(jié)拍周期*/ if( xQueueSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) !=pdPASS ) /* 發(fā)送一個指向結(jié)構(gòu)體Amessage的對象,如果隊列滿也不等待 */ xQueueSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
7.向隊列投遞隊列項(帶中斷保護)7.1函數(shù)描述 BaseType_t xQueueSendFromISR (QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken);
其實是一個宏,真正被調(diào)用的函數(shù)是xQueueGenericSendFromISR()。這個宏是xQueueSend()的中斷保護版本,用于中斷服務程序,等價于xQueueSendToBackFromISR()。 在中斷服務例程中向隊列尾部投遞一個隊列項。 7.2參數(shù)描述- xQueue:隊列句柄。
- pvItemToQueue:指針,指向要入隊的項目。要保存到隊列中的項目字節(jié)數(shù)在隊列創(chuàng)建時就已確定。因此要從指針pvItemToQueue指向的區(qū)域拷貝到隊列存儲區(qū)域的字節(jié)數(shù),也已確定。
- pxHigherPriorityTaskWoken:如果入隊導致一個任務解鎖,并且解鎖的任務優(yōu)先級高于當前運行的任務,則該函數(shù)將*pxHigherPriorityTaskWoken設置成pdTRUE。如果xQueueSendFromISR()設置這個值為pdTRUE,則中斷退出前需要一次上下文切換。從FreeRTOS V7.3.0起,pxHigherPriorityTaskWoken稱為一個可選參數(shù),并可以設置為NULL。
7.3返回值 列項入隊成功返回pdTRUE,否則返回errQUEUE_FULL。 7.4用法舉例 portBASE_TYPE xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; /* 從緩沖區(qū)獲得一個字節(jié)數(shù)據(jù) */ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken ); }while( portINPUT_BYTE( BUFFER_COUNT ) ); /* 這里緩沖區(qū)已空,如果需要進行一個上下文切換*/ /*根據(jù)不同移植平臺,這個函數(shù)也不同*/ portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
8.向隊列尾部投遞隊列項8.1函數(shù)描述 BaseType_t xQueueSendToBack(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait );
其實是一個宏,真正被調(diào)用的函數(shù)是xQueueGenericSend()。這個宏等價于xQueueSend()。 向隊列尾投遞一個隊列項。絕不可以在中斷中調(diào)用這個宏,可以使用帶有中斷保護的版本xQueueSendToBackFromISR ()來完成相同功能。 8.2參數(shù)描述 同xQueueSend()。 8.3返回值 同xQueueSend()。 8.4用法舉例 同xQueueSend()。 9.向隊列尾部投遞隊列項(帶中斷保護)9.1函數(shù)描述 BaseType_t xQueueSendToBackFromISR (QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken );
其實是一個宏,真正被調(diào)用的函數(shù)是xQueueGenericSendFromISR()。這個宏是xQueueSendToBack()的中斷保護版本,用于中斷服務程序,等價于xQueueSendFromISR()。 在中斷服務例程中向隊列尾部投遞一個隊列項。 9.2參數(shù)描述 同QueueSendFromISR()。 9.3返回值 同QueueSendFromISR()。 9.4用法舉例 同QueueSendFromISR()。 10.向隊列首部投遞隊列項10.1函數(shù)描述 BaseType_t xQueueSendToFront(QueueHandle_t xQueue, const void * pvItemToQueue,TickType_t xTicksToWait);
其實是一個宏,真正被調(diào)用的函數(shù)是xQueueGenericSend()。 這個宏向隊列首部投遞一個隊列項。絕不可以在中斷服務例程中調(diào)用這個宏,可以使用帶有中斷保護的版本xQueueSendToFrontFromISR ()來完成相同功能。 10.2參數(shù)描述- xQueue:隊列句柄。
- pvItemToQueue:指針,指向要入隊的項目。要保存到隊列中的項目字節(jié)數(shù)在隊列創(chuàng)建時就已確定。因此要從指針pvItemToQueue指向的區(qū)域拷貝到隊列存儲區(qū)域的字節(jié)數(shù),也已確定。
- xTicksToWait:如果隊列滿,任務等待隊列空閑的最大時間。如果隊列滿并且xTicksToWait被設置成0,函數(shù)立刻返回。時間單位為系統(tǒng)節(jié)拍時鐘周期,因此宏portTICK_PERIOD_MS可以用來輔助計算真實延時值。如果INCLUDE_vTaskSuspend設置成1,并且指定延時為portMAX_DELAY將引起任務無限阻塞(沒有超時)。
10.3返回值 隊列項入隊成功返回pdTRUE,否則返回errQUEUE_FULL。 11.向隊列首部投遞隊列項(帶中斷保護)11.1函數(shù)描述 BaseType_t xQueueSendToFrontFromISR (QueueHandle_t xQueue, const void *pvItemToQueue,BaseType_t *pxHigherPriorityTaskWoken);
其實是一個宏,真正被調(diào)用的函數(shù)是xQueueGenericSendFromISR()。這個宏是xQueueSendToFront ()的中斷保護版本,用于中斷服務程序。 11.2參數(shù)描述- xQueue:隊列句柄。
- pvItemToQueue:指針,指向要入隊的項目。要保存到隊列中的項目字節(jié)數(shù)在隊列創(chuàng)建時就已確定。因此要從指針pvItemToQueue指向的區(qū)域拷貝到隊列存儲區(qū)域的字節(jié)數(shù),也已確定。
- pxHigherPriorityTaskWoken:如果入隊導致一個任務解鎖,并且解鎖的任務優(yōu)先級高于當前運行的任務,則該函數(shù)將*pxHigherPriorityTaskWoken設置成pdTRUE。如果xQueueSendFromISR()設置這個值為pdTRUE,則中斷退出前需要一次上下文切換。從FreeRTOS V7.3.0起,pxHigherPriorityTaskWoken稱為一個可選參數(shù),并可以設置為NULL。
11.3返回值 列項入隊成功返回pdTRUE,否則返回errQUEUE_FULL。 12.讀取并移除隊列項12.1函數(shù)描述 BaseType_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer,TickType_t xTicksToWait);
其實是一個宏,真正被調(diào)用的函數(shù)是xQueueGenericReceive()。 這個宏從隊列中讀取一個隊列項并把該隊列項從隊列中刪除。讀取隊列項是以拷貝的形式完成,而不是以引用的形式,因此必須提供足夠大的緩沖區(qū)以便容納隊列項。參數(shù)pvBuffer指向這個緩沖區(qū)。 絕不可以在中斷服務例程中調(diào)用這個宏,可以使用使用帶有中斷保護的版本xQueueReceiveFromISR來完成相同功能。 12.2參數(shù)描述- pxQueue:隊列句柄。
- pvBuffer:指向一個緩沖區(qū),用于拷貝接收到的列表項。
- xTicksToWait:要接收的項目隊列為空時,允許任務最大阻塞時間。如果設置該參數(shù)為0,則表示即隊列為空也立即返回。阻塞時間的單位是系統(tǒng)節(jié)拍周期,宏portTICK_RATE_MS可輔助計算真實阻塞時間。如果INCLUDE_vTaskSuspend設置成1,并且阻塞時間設置成portMAX_DELAY,將會引起任務無限阻塞(不會有超時)。
12.3返回值 成功接收到列表項返回pdTRUE,否則返回pdFALSE。 12.4用法舉例void vATask( void *pvParameters ) struct AMessage *pxMessage; // 創(chuàng)建一個隊列,隊列能包含10個 Amessage結(jié)構(gòu)體指針類型的值。 // 這樣可以通過傳遞指針變量來包含大量數(shù)據(jù)。 xQueue =xQueueCreate( 10, sizeof( struct AMessage * ) ); // 向隊列發(fā)送一個指向結(jié)構(gòu)體對象Amessage的指針,如果隊列滿不等待 xQueueSend(xQueue, ( void * ) &pxMessage, ( portTickType ) 0 ); voidvADifferentTask( void *pvParameters ) struct AMessage *pxRxedMessage; // 從創(chuàng)建的隊列中接收一個消息,如果消息無效,最多阻塞10個系統(tǒng)節(jié)拍周期 if(xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) ) // 現(xiàn)在pcRxedMessage 指向由vATask任務投遞進來的結(jié)構(gòu)體Amessage變量
13讀取并移除隊列項(帶中斷保護)13.1函數(shù)描述 BaseType_t xQueueReceiveFromISR (QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxHigherPriorityTaskWoken);
從隊列中讀取一個隊列項并把該隊列項從隊列中刪除。功能與xQueueReceive()相同,用于中斷服務函數(shù)。 13.2參數(shù)描述- pxQueue:隊列句柄。
- pvBuffer:指向一個緩沖區(qū),用于拷貝接收到的列表項。
- pxHigherPriorityTaskWoken:如果入隊導致一個任務解鎖,并且解鎖的任務優(yōu)先級高于當前運行的任務,則該函數(shù)將*pxHigherPriorityTaskWoken設置成pdTRUE。如果xQueueSendFromISR()設置這個值為pdTRUE,則中斷退出前需要一次上下文切換。從FreeRTOS V7.3.0起,pxHigherPriorityTaskWoken稱為一個可選參數(shù),并可以設置為NULL。
13.3返回值 成功接收到列表項返回pdTRUE,否則返回pdFALSE。 13.4用法舉例/* 該函數(shù)創(chuàng)建一個隊列并投遞一些值 */ voidvAFunction( void *pvParameters ) const portTickType xBlockTime = (portTickType )0xff; /*創(chuàng)建一個隊列,可以容納10個portCHAR型變量 */ xQueue = xQueueCreate( 10, sizeof( portCHAR ) ); /* 投遞一些字符,在ISR中使用。如果隊列滿,任務將會阻塞xBlockTime 個系統(tǒng)節(jié)拍周期 */ xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime ); xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime ); /*... 繼續(xù)投遞字符 ... 當隊列滿時,這個任務會阻塞*/ xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime ); portBASE_TYPE xTaskWokenByReceive = pdFALSE; while( xQueueReceiveFromISR( xQueue, ( void *) &cRxedChar, &xTaskWokenByReceive) ) vOutputCharacter( cRxedChar ); /* 如果從隊列移除一個字符串后喚醒了向此隊列投遞字符的任務,那么參數(shù)xTaskWokenByReceive將會設置成pdTRUE,這個循環(huán)無論重復多少次,僅會 /*這里緩沖區(qū)已空,如果需要進行一個上下文切換根據(jù)不同移植平臺,這個函數(shù)也不同 */ portYIELD_FROM_ISR(xTaskWokenByReceive);
14.讀取但不移除隊列項14.1函數(shù)描述 BaseType_t xQueuePeek(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait);
其實是一個宏,真正被調(diào)用的函數(shù)是xQueueGenericReceive()。 這個宏從隊列中讀取一個隊列項,但不會把該隊列項從隊列中移除。這個宏絕不可以用在中斷服務例程中,可以使用使用帶有中斷保護的版本xQueuePeekFromIS()來完成相同功能。 14.2參數(shù)描述 同xQueueReceive()。 14.3返回值 同xQueueReceive()。 14.4用法舉例 同xQueueReceive()。 15.讀取但不移除隊列項(帶中斷保護)15.1函數(shù)描述 BaseType_t xQueuePeekFromISR(QueueHandle_t xQueue, void *pvBuffer,); 功能與xQueuePeek()相同,用于中斷服務程序。 15.2參數(shù)描述- pxQueue:隊列句柄。
- pvBuffer:指向一個緩沖區(qū),用于拷貝接收到的列表項。
15.3返回值 成功接收到列表項返回pdTRUE,否則返回pdFALSE。 16.隊列注冊16.1函數(shù)描述 void vQueueAddToRegistry(QueueHandle_t xQueue, char *pcQueueName,); 為隊列分配名字并進行注冊。 16.2參數(shù)描述- l xQueue:隊列句柄
- l pcQueueName:分配給隊列的名字。這僅是一個有助于調(diào)試的字符串。隊列注冊僅存儲指向隊列名字符串的指針,因此這個字符串必須是靜態(tài)的(全局變量活著存儲在ROM/Flash中),不可以定義到堆棧中。
隊列注冊有兩個目的,這兩個目的都是為了調(diào)試RTOS內(nèi)核: - 它允許隊列具有一個相關(guān)的文本名字,在GUI調(diào)試中可以容易的標識隊列;
- 包含調(diào)試器用于定位每一個已經(jīng)注冊的隊列和信號量時所需的信息。
隊列注冊僅用于調(diào)試器。 宏configQUEUE_REGISTRY_SIZE定義了可以注冊的隊列和信號量的最大數(shù)量。僅當你想使用可視化調(diào)試內(nèi)核時,才進行隊列和信號量注冊。 16.3用法舉例 /*創(chuàng)建一個隊列,可以容納10個char類型數(shù)值 */ xQueue = xQueueCreate( 10, sizeof( portCHAR ) ); /* 我們想可視化調(diào)試,所以注冊它*/ vQueueAddToRegistry( xQueue, "AMeaningfulName" );
17.解除注冊17.1函數(shù)描述 void vQueueUnregisterQueue(QueueHandle_t xQueue); 從隊列注冊表中移除指定的隊列。 17.2參數(shù)描述 18.查詢隊列是否為空(僅用于中斷服務程序)18.1函數(shù)描述 BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ); 查詢隊列是否為空。這個函數(shù)僅用于ISR。 18.2參數(shù)描述18.3返回值 隊列非空返回pdFALSE,其它值表示隊列為空。 19.查詢隊列是否滿(僅用于中斷服務程序)19.1函數(shù)描述 BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ); 查詢隊列是否滿,僅用于ISR。 19.2參數(shù)描述19.3返回值 隊列沒有滿返回pdFALSE,其它值表示隊列滿。 20.向隊列尾部覆蓋式投遞隊列項20.1函數(shù)描述 BaseType_t xQueueOverwrite(QueueHandle_t xQueue, const void * pvItemToQueue); 其實是個宏,真正被調(diào)用的函數(shù)是xQueueGenericSend()。這個宏是xQueueSendToBack()的另一個版本,向隊列尾投遞一個隊列項,如果隊列已滿,則覆蓋之前的隊列項。一般用于只有一個隊列項的隊列中,如果隊列的隊列項超過1個,使用這個宏會觸發(fā)一個斷言(已經(jīng)正確定義configASSERT()的情況下)。這個宏絕不可以在中斷服務程序中調(diào)用,可以使用使用帶有中斷保護的版本xQueueOverwriteFromISR()來完成相同功能。 20.2參數(shù)描述- xQueue:隊列句柄。
- pvItemToQueue:指針,指向要入隊的項目。要保存到隊列中的項目字節(jié)數(shù)在隊列創(chuàng)建時就已確定。因此要從指針pvItemToQueue指向的區(qū)域拷貝到隊列存儲區(qū)域的字節(jié)數(shù),也已確定。
20.3返回值 總是返回pdPASS。 20.4用法舉例void vFunction( void *pvParameters ) unsigned long ulVarToSend, ulValReceived; /*創(chuàng)建隊列,保存一個unsignedlong值。如果一個隊列的隊列項超過1個,強烈建議不要使用xQueueOverwrite(),如果使用xQueueOverwrite()會觸發(fā)一個斷言(已經(jīng)正確定義configASSERT()的情況下)。*/ xQueue = xQueueCreate( 1, sizeof( unsigned long ) ); /*使用 xQueueOverwrite().向隊列寫入10*/ xQueueOverwrite( xQueue, &ulVarToSend ); /*從隊列讀取值,但是不把這個值從隊列中刪除。*/ xQueuePeek( xQueue, &ulValReceived, 0 ); if( ulValReceived != 10 ) /*到這里隊列仍是滿的。使用xQueueOverwrite()覆寫隊列,寫入值100 */ xQueueOverwrite( xQueue, &ulVarToSend ); xQueueReceive( xQueue, &ulValReceived, 0 ); if( ulValReceived != 100 )
21向隊列尾部覆蓋式投遞隊列項(帶中斷保護)21.1函數(shù)描述 BaseType_t xQueueOverwriteFromISR (QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken);
其實是個宏,真正被調(diào)用的函數(shù)是xQueueGenericSendFromISR()。這個宏的功能與xQueueOverwrite()相同,用在中斷服務程序中。 21.2參數(shù)描述- xQueue:隊列句柄。
- pvItemToQueue:指針,指向要入隊的項目。要保存到隊列中的項目字節(jié)數(shù)在隊列創(chuàng)建時就已確定。因此要從指針pvItemToQueue指向的區(qū)域拷貝到隊列存儲區(qū)域的字節(jié)數(shù),也已確定。
- pxHigherPriorityTaskWoken:如果入隊導致一個任務解鎖,并且解鎖的任務優(yōu)先級高于當前運行的任務,則該函數(shù)將*pxHigherPriorityTaskWoken設置成pdTRUE。如果xQueueSendFromISR()設置這個值為pdTRUE,則中斷退出前需要一次上下文切換。從FreeRTOS V7.3.0起,pxHigherPriorityTaskWoken稱為一個可選參數(shù),并可以設置為NULL。
21.3返回值 總是返回pdPASS。
|