标签:
FreeRTOS为操作队列提供了非常丰富的API函数,包括队列的创建、删除,灵活的入队和出队方式、带中断保护的入队和出队等等。下面就来详细讲述这些API函数。
UBaseType_t uxQueueMessagesWaiting( QueueHandle_t xQueue );
返回队列中存储的信息数目。具有中断保护的版本为uxQueueMessagesWaitingFromISR(),原型为:UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue )。
UBaseType_t uxQueueSpacesAvailable( QueueHandle_t xQueue );
返回队列的空闲数目。
void vQueueDelete( QueueHandle_t xQueue );
删除队列并释放所有分配给队列的内存。
3.2参数描述
BaseType_t xQueueReset( QueueHandle_t xQueue );
将队列复位到初始状态。
FreeRTOSV7.2.0以及以后的版本总是返回pdPASS。
QueueHandle_t xQueueCreate (UBaseType_t uxQueueLength, UBaseType_t uxItemSize);
创建新队列。为新队列分配指定的存储空间并返回队列句柄。
成功创建队列返回队列句柄,否自返回0。
struct AMessage { portCHAR ucMessageID; portCHAR ucData[ 20 ]; }; void vATask( void*pvParameters ) { xQueueHandle xQueue1, xQueue2; // 创建一个队列,队列能包含10个unsigned long类型的值。 xQueue1 = xQueueCreate( 10, sizeof( unsigned portLONG )); if( xQueue1 ==0 ) { // 队列创建失败,不可以使用 } // 创建一个队列,队列能包含10个 Amessage结构体指针类型的值。 // 这样可以通过传递指针变量来包含大量数据。 xQueue2 =xQueueCreate( 10, sizeof( struct AMessage * ) ); if( xQueue2 ==0 ) { // 队列创建失败,不可以使用 } // ... 任务的其它代码. }
BaseType_t xQueueSend(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait );
其实是一个宏,真正被调用的函数是xQueueGenericSend()。定义这个宏是为了向后兼容那些不包含函数xQueueSendToFront()和xQueueSendToBack()宏的FreeRTOS版本。它与xQueueSendToBack()等同。
这个宏向队列尾部投递一个队列项。项目以拷贝的形式入队,而不是引用形式入队。绝不可以在中断服务例程中调用这个宏,使用带有中断保护的版本xQueueSendFromISR()来完成相同的功能。
6.2参数描述
队列项入队成功返回pdTRUE,否则返回errQUEUE_FULL。
struct AMessage { portCHAR ucMessageID; portCHAR ucData[ 20 ]; }xMessage; unsigned portLONG ulVar = 10UL; void vATask( void *pvParameters ) { xQueueHandle xQueue1, xQueue2; struct AMessage *pxMessage; /*创建一个队列,队列能包含10个unsigned long类型的值。*/ xQueue1 = xQueueCreate( 10, sizeof( unsigned portLONG ) ); /* 创建一个队列,队列能包含10个 Amessage结构体指针类型的值。 这样可以通过传递指针变量来包含大量数据。*/ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) ); // ... if( xQueue1 != 0 ) { /*1个unsigned long型数据入队.如果需要等待队列空间变的有效, 会最多等待10个系统节拍周期*/ if( xQueueSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) !=pdPASS ) { /*消息入队失败*/ } } if( xQueue2 != 0 ) { /* 发送一个指向结构体Amessage的对象,如果队列满也不等待 */ pxMessage = & xMessage; xQueueSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 ); } //... 任务其余代码. }
BaseType_t xQueueSendFromISR (QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken);
其实是一个宏,真正被调用的函数是xQueueGenericSendFromISR()。这个宏是xQueueSend()的中断保护版本,用于中断服务程序,等价于xQueueSendToBackFromISR()。
在中断服务例程中向队列尾部投递一个队列项。
列项入队成功返回pdTRUE,否则返回errQUEUE_FULL。
void vBufferISR( void ) { portCHARcIn; portBASE_TYPE xHigherPriorityTaskWoken; /* 初始化,没有唤醒任务*/ xHigherPriorityTaskWoken = pdFALSE; /* 直到缓冲区为空 */ do { /* 从缓冲区获得一个字节数据 */ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS ); /* 投递这个数据 */ xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken ); }while( portINPUT_BYTE( BUFFER_COUNT ) ); /* 这里缓冲区已空,如果需要进行一个上下文切换*/ /*根据不同移植平台,这个函数也不同*/ portYIELD_FROM_ISR(xHigherPriorityTaskWoken); }
BaseType_t xQueueSendToBack(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait );
其实是一个宏,真正被调用的函数是xQueueGenericSend()。这个宏等价于xQueueSend()。
向队列尾投递一个队列项。绝不可以在中断中调用这个宏,可以使用带有中断保护的版本xQueueSendToBackFromISR ()来完成相同功能。
同xQueueSend()。
同xQueueSend()。
同xQueueSend()。
BaseType_t xQueueSendToBackFromISR (QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken );
其实是一个宏,真正被调用的函数是xQueueGenericSendFromISR()。这个宏是xQueueSendToBack()的中断保护版本,用于中断服务程序,等价于xQueueSendFromISR()。
在中断服务例程中向队列尾部投递一个队列项。
同QueueSendFromISR()。
同QueueSendFromISR()。
同QueueSendFromISR()。
BaseType_t xQueueSendToFront(QueueHandle_t xQueue, const void * pvItemToQueue,TickType_t xTicksToWait);
其实是一个宏,真正被调用的函数是xQueueGenericSend()。
这个宏向队列首部投递一个队列项。绝不可以在中断服务例程中调用这个宏,可以使用带有中断保护的版本xQueueSendToFrontFromISR ()来完成相同功能。
队列项入队成功返回pdTRUE,否则返回errQUEUE_FULL。
BaseType_t xQueueSendToFrontFromISR (QueueHandle_t xQueue, const void *pvItemToQueue,BaseType_t *pxHigherPriorityTaskWoken);
其实是一个宏,真正被调用的函数是xQueueGenericSendFromISR()。这个宏是xQueueSendToFront ()的中断保护版本,用于中断服务程序。
列项入队成功返回pdTRUE,否则返回errQUEUE_FULL。
BaseType_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer,TickType_t xTicksToWait);
其实是一个宏,真正被调用的函数是xQueueGenericReceive()。
这个宏从队列中读取一个队列项并把该队列项从队列中删除。读取队列项是以拷贝的形式完成,而不是以引用的形式,因此必须提供足够大的缓冲区以便容纳队列项。参数pvBuffer指向这个缓冲区。
绝不可以在中断服务例程中调用这个宏,可以使用使用带有中断保护的版本xQueueReceiveFromISR来完成相同功能。
成功接收到列表项返回pdTRUE,否则返回pdFALSE。
struct AMessage { portCHAR ucMessageID; portCHAR ucData[ 20 ]; } xMessage; xQueueHandle xQueue; // 创建一个队列并投递一个值 void vATask( void *pvParameters ) { struct AMessage *pxMessage; // 创建一个队列,队列能包含10个 Amessage结构体指针类型的值。 // 这样可以通过传递指针变量来包含大量数据。 xQueue =xQueueCreate( 10, sizeof( struct AMessage * ) ); if( xQueue == 0) { // 创建队列失败 } // ... // 向队列发送一个指向结构体对象Amessage的指针,如果队列满不等待 pxMessage = & xMessage; xQueueSend(xQueue, ( void * ) &pxMessage, ( portTickType ) 0 ); // ... 其它代码 } // 该任务从队列中接收一个队列项 voidvADifferentTask( void *pvParameters ) { struct AMessage *pxRxedMessage; if( xQueue != 0) { // 从创建的队列中接收一个消息,如果消息无效,最多阻塞10个系统节拍周期 if(xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) ) { // 现在pcRxedMessage 指向由vATask任务投递进来的结构体Amessage变量 } } // ... 其它代码 }
BaseType_t xQueueReceiveFromISR (QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxHigherPriorityTaskWoken);
从队列中读取一个队列项并把该队列项从队列中删除。功能与xQueueReceive()相同,用于中断服务函数。
成功接收到列表项返回pdTRUE,否则返回pdFALSE。
xQueueHandle xQueue; /* 该函数创建一个队列并投递一些值 */ voidvAFunction( void *pvParameters ) { portCHAR cValueToPost; const portTickType xBlockTime = (portTickType )0xff; /*创建一个队列,可以容纳10个portCHAR型变量 */ xQueue = xQueueCreate( 10, sizeof( portCHAR ) ); if( xQueue == 0 ) { /* 队列创建失败 */ } /*…... */ /* 投递一些字符,在ISR中使用。如果队列满,任务将会阻塞xBlockTime 个系统节拍周期 */ cValueToPost = ‘a‘; xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime ); cValueToPost = ‘b‘; xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime ); /*... 继续投递字符 ... 当队列满时,这个任务会阻塞*/ cValueToPost = ‘c‘; xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime ); } /* ISR:输出从队列接收到的所有字符 */ voidvISR_Routine( void ) { portBASE_TYPE xTaskWokenByReceive = pdFALSE; portCHAR cRxedChar; while( xQueueReceiveFromISR( xQueue, ( void *) &cRxedChar, &xTaskWokenByReceive) ) { /* 接收到一个字符串,输出.*/ vOutputCharacter( cRxedChar ); /* 如果从队列移除一个字符串后唤醒了向此队列投递字符的任务,那么参数xTaskWokenByReceive将会设置成pdTRUE,这个循环无论重复多少次,仅会 有一个任务被唤醒。*/ } /*这里缓冲区已空,如果需要进行一个上下文切换根据不同移植平台,这个函数也不同 */ portYIELD_FROM_ISR(xTaskWokenByReceive); }
BaseType_t xQueuePeek(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait);
其实是一个宏,真正被调用的函数是xQueueGenericReceive()。
这个宏从队列中读取一个队列项,但不会把该队列项从队列中移除。这个宏绝不可以用在中断服务例程中,可以使用使用带有中断保护的版本xQueuePeekFromIS()来完成相同功能。
同xQueueReceive()。
同xQueueReceive()。
同xQueueReceive()。
BaseType_t xQueuePeekFromISR(QueueHandle_t xQueue, void *pvBuffer,);
功能与xQueuePeek()相同,用于中断服务程序。
成功接收到列表项返回pdTRUE,否则返回pdFALSE。
void vQueueAddToRegistry(QueueHandle_t xQueue, char *pcQueueName,);
为队列分配名字并进行注册。
队列注册有两个目的,这两个目的都是为了调试RTOS内核:
队列注册仅用于调试器。
宏configQUEUE_REGISTRY_SIZE定义了可以注册的队列和信号量的最大数量。仅当你想使用可视化调试内核时,才进行队列和信号量注册。
void vAFunction( void ) { xQueueHandle xQueue; /*创建一个队列,可以容纳10个char类型数值 */ xQueue = xQueueCreate( 10, sizeof( portCHAR ) ); /* 我们想可视化调试,所以注册它*/ vQueueAddToRegistry( xQueue, "AMeaningfulName" ); }
void vQueueUnregisterQueue(QueueHandle_t xQueue);
从队列注册表中移除指定的队列。
17.2参数描述
BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue );
查询队列是否为空。这个函数仅用于ISR。
队列非空返回pdFALSE,其它值表示队列为空。
BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue );
查询队列是否满,仅用于ISR。
队列没有满返回pdFALSE,其它值表示队列满。
BaseType_t xQueueOverwrite(QueueHandle_t xQueue, const void * pvItemToQueue);
其实是个宏,真正被调用的函数是xQueueGenericSend()。这个宏是xQueueSendToBack()的另一个版本,向队列尾投递一个队列项,如果队列已满,则覆盖之前的队列项。一般用于只有一个队列项的队列中,如果队列的队列项超过1个,使用这个宏会触发一个断言(已经正确定义configASSERT()的情况下)。这个宏绝不可以在中断服务程序中调用,可以使用使用带有中断保护的版本xQueueOverwriteFromISR()来完成相同功能。
总是返回pdPASS。
void vFunction( void *pvParameters ) { QueueHandle_t xQueue; unsigned long ulVarToSend, ulValReceived; /*创建队列,保存一个unsignedlong值。如果一个队列的队列项超过1个,强烈建议不要使用xQueueOverwrite(),如果使用xQueueOverwrite()会触发一个断言(已经正确定义configASSERT()的情况下)。*/ xQueue = xQueueCreate( 1, sizeof( unsigned long ) ); /*使用 xQueueOverwrite().向队列写入10*/ ulVarToSend = 10; xQueueOverwrite( xQueue, &ulVarToSend ); /*从队列读取值,但是不把这个值从队列中删除。*/ ulValReceived = 0; xQueuePeek( xQueue, &ulValReceived, 0 ); if( ulValReceived != 10 ) { /* 处理错误*/ } /*到这里队列仍是满的。使用xQueueOverwrite()覆写队列,写入值100 */ ulVarToSend = 100; xQueueOverwrite( xQueue, &ulVarToSend ); /* 从队列中读取值*/ xQueueReceive( xQueue, &ulValReceived, 0 ); if( ulValReceived != 100 ) { /*处理错误 */ } /* ... */ }
BaseType_t xQueueOverwrite (QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken);
其实是个宏,真正被调用的函数是xQueueGenericSendFromISR()。这个宏的功能与xQueueOverwrite()相同,用在中断服务程序中。
总是返回pdPASS。
FreeRTOS系列第18篇---FreeRTOS队列API函数
标签:
原文地址:http://blog.csdn.net/zhzht19861011/article/details/50800538