第四章:队列管理(转)

https://blog.csdn.net/zhzht19861011/article/details/51510384

FreeRTOS为操作队列提供了非常丰富的API函数,包括队列的创建、删除,灵活的入队和出队方式、带中断保护的入队和出队等等。下面就来详细讲述这些API函数。

1.获取队列入队信息数目

1.1函数描述

      UBaseType_t uxQueueMessagesWaiting( QueueHandle_t xQueue );

      返回队列中存储的信息数目。具有中断保护的版本为uxQueueMessagesWaitingFromISR(),原型为:UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue )。

1.2参数描述

  •  xQueue:队列句柄

2.获取队列的空闲数目

2.1函数描述

      UBaseType_t uxQueueSpacesAvailable( QueueHandle_t xQueue );

      返回队列的空闲数目。

2.2参数描述

  •  xQueue:队列句柄

3.删除队列

3.1函数描述

      void vQueueDelete( QueueHandle_t xQueue );

      删除队列并释放所有分配给队列的内存。

3.2参数描述

  •  xQueue:队列句柄

4.复位队列

4.1函数描述

      BaseType_t xQueueReset( QueueHandle_t xQueue );

      将队列复位到初始状态。

4.2参数描述

  •  xQueue:队列句柄

4.3返回值

      FreeRTOSV7.2.0以及以后的版本总是返回pdPASS。

5.创建队列

5.1函数描述

     QueueHandle_t xQueueCreate (UBaseType_t uxQueueLength, UBaseType_t uxItemSize);

     创建新队列。为新队列分配指定的存储空间并返回队列句柄。

5.2参数描述

  •  usQueueLength:队列项数目
  •  uxItemSize:每个队列项大小,单位是字节。队列项通过拷贝入队而不是通过引用入队,因此需要队列项的大小。每个队列项的大小必须相同。

5.3返回值

      成功创建队列返回队列句柄,否自返回0。

5.4用法举例
[objc]  view plain  copy
 print ?
  1. struct AMessage  
  2. {  
  3.     portCHAR ucMessageID;  
  4.     portCHAR ucData[ 20 ];  
  5. };  
  6. void vATask( void*pvParameters )  
  7. {  
  8.     xQueueHandle xQueue1, xQueue2;  
  9.     // 创建一个队列,队列能包含10个unsigned long类型的值。  
  10.     xQueue1 = xQueueCreate( 10sizeof( unsigned portLONG ));  
  11.     if( xQueue1 ==0 )  
  12.     {  
  13.         // 队列创建失败,不可以使用  
  14.     }  
  15.     // 创建一个队列,队列能包含10个 Amessage结构体指针类型的值。  
  16.     // 这样可以通过传递指针变量来包含大量数据。  
  17.     xQueue2 =xQueueCreate( 10sizeofstruct AMessage * ) );  
  18.     if( xQueue2 ==0 )  
  19.     {  
  20.         // 队列创建失败,不可以使用  
  21.     }  
  22.     // ... 任务的其它代码.  
  23. }  

6.向队列投递队列项

6.1 函数描述

      BaseType_t xQueueSend(QueueHandle_t xQueue,  const void * pvItemToQueue,  TickType_t xTicksToWait );

      其实是一个宏,真正被调用的函数是xQueueGenericSend()。定义这个宏是为了向后兼容那些不包含函数xQueueSendToFront()和xQueueSendToBack()宏的FreeRTOS版本。它与xQueueSendToBack()等同。

      这个宏向队列尾部投递一个队列项。项目以拷贝的形式入队,而不是引用形式入队。绝不可以在中断服务例程中调用这个宏,使用带有中断保护的版本xQueueSendFromISR()来完成相同的功能。

6.2参数描述

  • xQueue:队列句柄。
  • pvItemToQueue:指针,指向要入队的项目。要保存到队列中的项目字节数在队列创建时就已确定。因此要从指针pvItemToQueue指向的区域拷贝到队列存储区域的字节数,也已确定。
  • xTicksToWait:如果队列满,任务等待队列空闲的最大时间。如果队列满并且xTicksToWait被设置成0,函数立刻返回。时间单位为系统节拍时钟周期,因此宏portTICK_PERIOD_MS可以用来辅助计算真实延时值。如果INCLUDE_vTaskSuspend设置成1,并且指定延时为portMAX_DELAY将引起任务无限阻塞(没有超时)。

6.3返回值

      队列项入队成功返回pdTRUE,否则返回errQUEUE_FULL。

6.4用法举例

[objc]  view plain  copy
 print ?
  1. struct AMessage  
  2.  {  
  3.       portCHAR ucMessageID;  
  4.       portCHAR ucData[ 20 ];  
  5.  }xMessage;  
  6.  unsigned portLONG ulVar = 10UL;  
  7.  void vATask( voidvoid *pvParameters )  
  8.  {  
  9.      xQueueHandle xQueue1, xQueue2;  
  10.      struct AMessage *pxMessage;  
  11.      /*创建一个队列,队列能包含10个unsigned long类型的值。*/  
  12.      xQueue1 = xQueueCreate( 10sizeof( unsigned portLONG ) );  
  13.      /* 创建一个队列,队列能包含10个 Amessage结构体指针类型的值。 
  14.        这样可以通过传递指针变量来包含大量数据。*/  
  15.      xQueue2 = xQueueCreate( 10sizeofstruct AMessage * ) );  
  16.      // ...  
  17.      if( xQueue1 != 0 )  
  18.      {  
  19.           /*1个unsigned long型数据入队.如果需要等待队列空间变的有效, 
  20.          会最多等待10个系统节拍周期*/  
  21.           if( xQueueSend( xQueue1, ( voidvoid * ) &ulVar, ( portTickType ) 10 ) !=pdPASS )  
  22.           {  
  23.                /*消息入队失败*/  
  24.           }  
  25.     }  
  26.     if( xQueue2 != 0 )  
  27.     {  
  28.          /* 发送一个指向结构体Amessage的对象,如果队列满也不等待 */  
  29.          pxMessage = & xMessage;  
  30.          xQueueSend( xQueue2, ( voidvoid * ) &pxMessage, ( portTickType ) 0 );  
  31.     }  
  32.          //... 任务其余代码.  
  33.  }  

7.向队列投递队列项(带中断保护)

7.1函数描述

[objc]  view plain  copy
 print ?
  1. BaseType_t xQueueSendFromISR (QueueHandle_t xQueue,  
  2.           const voidvoid *pvItemToQueue,  BaseType_t *pxHigherPriorityTaskWoken);  

      其实是一个宏,真正被调用的函数是xQueueGenericSendFromISR()。这个宏是xQueueSend()的中断保护版本,用于中断服务程序,等价于xQueueSendToBackFromISR()。

    在中断服务例程中向队列尾部投递一个队列项。

7.2参数描述

  • xQueue:队列句柄。
  • pvItemToQueue:指针,指向要入队的项目。要保存到队列中的项目字节数在队列创建时就已确定。因此要从指针pvItemToQueue指向的区域拷贝到队列存储区域的字节数,也已确定。
  • pxHigherPriorityTaskWoken:如果入队导致一个任务解锁,并且解锁的任务优先级高于当前运行的任务,则该函数将*pxHigherPriorityTaskWoken设置成pdTRUE。如果xQueueSendFromISR()设置这个值为pdTRUE,则中断退出前需要一次上下文切换。从FreeRTOS V7.3.0起,pxHigherPriorityTaskWoken称为一个可选参数,并可以设置为NULL。

7.3返回值

      列项入队成功返回pdTRUE,否则返回errQUEUE_FULL。

7.4用法举例

[objc]  view plain  copy
 print ?
  1. void vBufferISR( void )  
  2. {  
  3.     portCHARcIn;  
  4.     portBASE_TYPE xHigherPriorityTaskWoken;  
  5.    
  6.     /* 初始化,没有唤醒任务*/  
  7.     xHigherPriorityTaskWoken = pdFALSE;  
  8.    
  9.     /* 直到缓冲区为空 */  
  10.     do  
  11.     {  
  12.         /* 从缓冲区获得一个字节数据 */  
  13.         cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );                                                        
  14.    
  15.         /* 投递这个数据 */  
  16.         xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );  
  17.     }while( portINPUT_BYTE( BUFFER_COUNT ) );  
  18.    
  19.     /* 这里缓冲区已空,如果需要进行一个上下文切换*/  
  20.     /*根据不同移植平台,这个函数也不同*/  
  21.     portYIELD_FROM_ISR(xHigherPriorityTaskWoken);  
  22. }  

8.向队列尾部投递队列项

8.1函数描述

[objc]  view plain  copy
 print ?
  1. BaseType_t xQueueSendToBack(QueueHandle_t xQueue,  
  2.                    const voidvoid * pvItemToQueue, TickType_t xTicksToWait );  

      其实是一个宏,真正被调用的函数是xQueueGenericSend()。这个宏等价于xQueueSend()。

      向队列尾投递一个队列项。绝不可以在中断中调用这个宏,可以使用带有中断保护的版本xQueueSendToBackFromISR ()来完成相同功能。

8.2参数描述

      同xQueueSend()。

8.3返回值

      同xQueueSend()。

8.4用法举例

      同xQueueSend()。

9.向队列尾部投递队列项(带中断保护)

9.1函数描述

[objc]  view plain  copy
 print ?
  1. BaseType_t xQueueSendToBackFromISR (QueueHandle_t xQueue,  
  2.       const voidvoid *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken );  

      其实是一个宏,真正被调用的函数是xQueueGenericSendFromISR()。这个宏是xQueueSendToBack()的中断保护版本,用于中断服务程序,等价于xQueueSendFromISR()。

    在中断服务例程中向队列尾部投递一个队列项。

9.2参数描述

      同QueueSendFromISR()。

9.3返回值

      同QueueSendFromISR()。

9.4用法举例

      同QueueSendFromISR()。

10.向队列首部投递队列项

10.1函数描述

[objc]  view plain  copy
 print ?
  1. BaseType_t xQueueSendToFront(QueueHandle_t xQueue,  
  2.          const voidvoid * pvItemToQueue,TickType_t xTicksToWait);  

      其实是一个宏,真正被调用的函数是xQueueGenericSend()。

      这个宏向队列首部投递一个队列项。绝不可以在中断服务例程中调用这个宏,可以使用带有中断保护的版本xQueueSendToFrontFromISR ()来完成相同功能。

10.2参数描述

  • xQueue:队列句柄。
  • pvItemToQueue:指针,指向要入队的项目。要保存到队列中的项目字节数在队列创建时就已确定。因此要从指针pvItemToQueue指向的区域拷贝到队列存储区域的字节数,也已确定。
  • xTicksToWait:如果队列满,任务等待队列空闲的最大时间。如果队列满并且xTicksToWait被设置成0,函数立刻返回。时间单位为系统节拍时钟周期,因此宏portTICK_PERIOD_MS可以用来辅助计算真实延时值。如果INCLUDE_vTaskSuspend设置成1,并且指定延时为portMAX_DELAY将引起任务无限阻塞(没有超时)。

10.3返回值

      队列项入队成功返回pdTRUE,否则返回errQUEUE_FULL。

11.向队列首部投递队列项(带中断保护)

11.1函数描述

[objc]  view plain  copy
 print ?
  1. BaseType_t xQueueSendToFrontFromISR (QueueHandle_t xQueue,  
  2.         const voidvoid *pvItemToQueue,BaseType_t *pxHigherPriorityTaskWoken);  

      其实是一个宏,真正被调用的函数是xQueueGenericSendFromISR()。这个宏是xQueueSendToFront ()的中断保护版本,用于中断服务程序。

11.2参数描述

  • xQueue:队列句柄。
  • pvItemToQueue:指针,指向要入队的项目。要保存到队列中的项目字节数在队列创建时就已确定。因此要从指针pvItemToQueue指向的区域拷贝到队列存储区域的字节数,也已确定。
  • pxHigherPriorityTaskWoken:如果入队导致一个任务解锁,并且解锁的任务优先级高于当前运行的任务,则该函数将*pxHigherPriorityTaskWoken设置成pdTRUE。如果xQueueSendFromISR()设置这个值为pdTRUE,则中断退出前需要一次上下文切换。从FreeRTOS V7.3.0起,pxHigherPriorityTaskWoken称为一个可选参数,并可以设置为NULL。

11.3返回值

      列项入队成功返回pdTRUE,否则返回errQUEUE_FULL。

12.读取并移除队列项

12.1函数描述

[objc]  view plain  copy
 print ?
  1. BaseType_t xQueueReceive(QueueHandle_t xQueue,  
  2.                      voidvoid *pvBuffer,TickType_t xTicksToWait);  

      其实是一个宏,真正被调用的函数是xQueueGenericReceive()。

      这个宏从队列中读取一个队列项并把该队列项从队列中删除。读取队列项是以拷贝的形式完成,而不是以引用的形式,因此必须提供足够大的缓冲区以便容纳队列项。参数pvBuffer指向这个缓冲区。

      绝不可以在中断服务例程中调用这个宏,可以使用使用带有中断保护的版本xQueueReceiveFromISR来完成相同功能。

12.2参数描述

  • pxQueue:队列句柄。
  • pvBuffer:指向一个缓冲区,用于拷贝接收到的列表项。
  • xTicksToWait:要接收的项目队列为空时,允许任务最大阻塞时间。如果设置该参数为0,则表示即队列为空也立即返回。阻塞时间的单位是系统节拍周期,宏portTICK_RATE_MS可辅助计算真实阻塞时间。如果INCLUDE_vTaskSuspend设置成1,并且阻塞时间设置成portMAX_DELAY,将会引起任务无限阻塞(不会有超时)。

12.3返回值

      成功接收到列表项返回pdTRUE,否则返回pdFALSE。

12.4用法举例

[objc]  view plain  copy
 print ?
  1. struct AMessage  
  2. {  
  3.     portCHAR ucMessageID;  
  4.     portCHAR ucData[ 20 ];  
  5. } xMessage;  
  6.    
  7. xQueueHandle xQueue;  
  8.    
  9. // 创建一个队列并投递一个值  
  10. void vATask( voidvoid *pvParameters )  
  11. {  
  12.      struct AMessage *pxMessage;  
  13.    
  14.      // 创建一个队列,队列能包含10个 Amessage结构体指针类型的值。  
  15.      // 这样可以通过传递指针变量来包含大量数据。  
  16.      xQueue =xQueueCreate( 10sizeofstruct AMessage * ) );  
  17.      if( xQueue == 0)  
  18.      {  
  19.           // 创建队列失败  
  20.     }  
  21.     // ...  
  22.     // 向队列发送一个指向结构体对象Amessage的指针,如果队列满不等待  
  23.     pxMessage = & xMessage;  
  24.     xQueueSend(xQueue, ( voidvoid * ) &pxMessage, ( portTickType ) 0 );  
  25.     // ... 其它代码  
  26. }  
  27.    
  28. // 该任务从队列中接收一个队列项  
  29. voidvADifferentTask( voidvoid *pvParameters )  
  30. {  
  31.     struct AMessage *pxRxedMessage;  
  32.    
  33.     if( xQueue != 0)  
  34.     {  
  35.         // 从创建的队列中接收一个消息,如果消息无效,最多阻塞10个系统节拍周期  
  36.         if(xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )  
  37.         {  
  38.             // 现在pcRxedMessage 指向由vATask任务投递进来的结构体Amessage变量  
  39.         }  
  40.     }  
  41.    // ... 其它代码  
  42.  }  

13读取并移除队列项(带中断保护)

13.1函数描述

[objc]  view plain  copy
 print ?
  1. BaseType_t xQueueReceiveFromISR (QueueHandle_t xQueue,  
  2.         voidvoid *pvBuffer, BaseType_t *pxHigherPriorityTaskWoken);  

      从队列中读取一个队列项并把该队列项从队列中删除。功能与xQueueReceive()相同,用于中断服务函数。

13.2参数描述

  • pxQueue:队列句柄。
  • pvBuffer:指向一个缓冲区,用于拷贝接收到的列表项。
  • pxHigherPriorityTaskWoken:如果入队导致一个任务解锁,并且解锁的任务优先级高于当前运行的任务,则该函数将*pxHigherPriorityTaskWoken设置成pdTRUE。如果xQueueSendFromISR()设置这个值为pdTRUE,则中断退出前需要一次上下文切换。从FreeRTOS V7.3.0起,pxHigherPriorityTaskWoken称为一个可选参数,并可以设置为NULL。

13.3返回值

      成功接收到列表项返回pdTRUE,否则返回pdFALSE。

13.4用法举例

[objc]  view plain  copy
 print ?
  1. xQueueHandle xQueue;  
  2.    
  3. /* 该函数创建一个队列并投递一些值 */  
  4. voidvAFunction( voidvoid *pvParameters )  
  5. {  
  6.      portCHAR cValueToPost;  
  7.      const portTickType xBlockTime = (portTickType )0xff;  
  8.    
  9.      /*创建一个队列,可以容纳10个portCHAR型变量 */  
  10.      xQueue = xQueueCreate( 10sizeof( portCHAR ) );  
  11.      if( xQueue == 0 )  
  12.      {  
  13.           /* 队列创建失败 */  
  14.      }  
  15.     /*…... */  
  16.     /* 投递一些字符,在ISR中使用。如果队列满,任务将会阻塞xBlockTime 个系统节拍周期 */  
  17.     cValueToPost = 'a';  
  18.     xQueueSend( xQueue, ( voidvoid * ) &cValueToPost, xBlockTime );  
  19.     cValueToPost = 'b';  
  20.     xQueueSend( xQueue, ( voidvoid * ) &cValueToPost, xBlockTime );  
  21.     /*... 继续投递字符 ... 当队列满时,这个任务会阻塞*/  
  22.     cValueToPost = 'c';  
  23.     xQueueSend( xQueue, ( voidvoid * ) &cValueToPost, xBlockTime );  
  24. }  
  25.    
  26. /* ISR:输出从队列接收到的所有字符 */  
  27. voidvISR_Routine( void )  
  28. {  
  29.      portBASE_TYPE xTaskWokenByReceive = pdFALSE;  
  30.      portCHAR cRxedChar;  
  31.    
  32.      while( xQueueReceiveFromISR( xQueue, ( voidvoid *) &cRxedChar, &xTaskWokenByReceive) )  
  33.     {  
  34.        /* 接收到一个字符串,输出.*/  
  35.        vOutputCharacter( cRxedChar );  
  36.        /* 如果从队列移除一个字符串后唤醒了向此队列投递字符的任务,那么参数xTaskWokenByReceive将会设置成pdTRUE,这个循环无论重复多少次,仅会 
  37.           有一个任务被唤醒。*/  
  38.     }  
  39.     /*这里缓冲区已空,如果需要进行一个上下文切换根据不同移植平台,这个函数也不同 */  
  40.     portYIELD_FROM_ISR(xTaskWokenByReceive);  
  41. }  

14.读取但不移除队列项

14.1函数描述

[objc]  view plain  copy
 print ?
  1. BaseType_t xQueuePeek(QueueHandle_t xQueue,  
  2.         voidvoid *pvBuffer, TickType_t xTicksToWait);  

      其实是一个宏,真正被调用的函数是xQueueGenericReceive()。

      这个宏从队列中读取一个队列项,但不会把该队列项从队列中移除。这个宏绝不可以用在中断服务例程中,可以使用使用带有中断保护的版本xQueuePeekFromIS()来完成相同功能。

14.2参数描述

      同xQueueReceive()。

14.3返回值

      同xQueueReceive()。

14.4用法举例

      同xQueueReceive()。

15.读取但不移除队列项(带中断保护)

15.1函数描述

      BaseType_t xQueuePeekFromISR(QueueHandle_t xQueue, void *pvBuffer,);

      功能与xQueuePeek()相同,用于中断服务程序。

15.2参数描述

  • pxQueue:队列句柄。
  • pvBuffer:指向一个缓冲区,用于拷贝接收到的列表项。

15.3返回值

      成功接收到列表项返回pdTRUE,否则返回pdFALSE。

16.队列注册

16.1函数描述

      void vQueueAddToRegistry(QueueHandle_t xQueue, char *pcQueueName,);

      为队列分配名字并进行注册。

16.2参数描述

  • l  xQueue:队列句柄
  • l  pcQueueName:分配给队列的名字。这仅是一个有助于调试的字符串。队列注册仅存储指向队列名字符串的指针,因此这个字符串必须是静态的(全局变量活着存储在ROM/Flash中),不可以定义到堆栈中。

      队列注册有两个目的,这两个目的都是为了调试RTOS内核:

  1. 它允许队列具有一个相关的文本名字,在GUI调试中可以容易的标识队列;
  2. 包含调试器用于定位每一个已经注册的队列和信号量时所需的信息。

       队列注册仅用于调试器。

       宏configQUEUE_REGISTRY_SIZE定义了可以注册的队列和信号量的最大数量。仅当你想使用可视化调试内核时,才进行队列和信号量注册。

16.3用法举例

[objc]  view plain  copy
 print ?
  1. void vAFunction( void )  
  2. {  
  3.     xQueueHandle xQueue;  
  4.    
  5.    /*创建一个队列,可以容纳10个char类型数值 */  
  6.    xQueue = xQueueCreate( 10sizeof( portCHAR ) );  
  7.    
  8.    /* 我们想可视化调试,所以注册它*/  
  9.    vQueueAddToRegistry( xQueue, "AMeaningfulName" );  
  10. }  

17.解除注册

17.1函数描述

      void vQueueUnregisterQueue(QueueHandle_t xQueue);

      从队列注册表中移除指定的队列。

17.2参数描述

  • xQueue:队列句柄

18.查询队列是否为空(仅用于中断服务程序)

18.1函数描述

      BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue );

      查询队列是否为空。这个函数仅用于ISR。

18.2参数描述

  • xQueue:队列句柄

18.3返回值

      队列非空返回pdFALSE,其它值表示队列为空。

19.查询队列是否满(仅用于中断服务程序)

19.1函数描述

      BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue );

      查询队列是否满,仅用于ISR。

19.2参数描述

  • xQueue:队列句柄

19.3返回值

      队列没有满返回pdFALSE,其它值表示队列满。

20.向队列尾部覆盖式投递队列项

20.1函数描述

      BaseType_t xQueueOverwrite(QueueHandle_t xQueue, const void * pvItemToQueue);

      其实是个宏,真正被调用的函数是xQueueGenericSend()。这个宏是xQueueSendToBack()的另一个版本,向队列尾投递一个队列项,如果队列已满,则覆盖之前的队列项。一般用于只有一个队列项的队列中,如果队列的队列项超过1个,使用这个宏会触发一个断言(已经正确定义configASSERT()的情况下)。这个宏绝不可以在中断服务程序中调用,可以使用使用带有中断保护的版本xQueueOverwriteFromISR()来完成相同功能。

20.2参数描述

  • xQueue:队列句柄。
  • pvItemToQueue:指针,指向要入队的项目。要保存到队列中的项目字节数在队列创建时就已确定。因此要从指针pvItemToQueue指向的区域拷贝到队列存储区域的字节数,也已确定。

20.3返回值

      总是返回pdPASS。

20.4用法举例

[objc]  view plain  copy
 print ?
  1. void vFunction( voidvoid *pvParameters )  
  2. {  
  3.     QueueHandle_t xQueue;  
  4.     unsigned long ulVarToSend, ulValReceived;  
  5.    
  6.     /*创建队列,保存一个unsignedlong值。如果一个队列的队列项超过1个,强烈建议不要使用xQueueOverwrite(),如果使用xQueueOverwrite()会触发一个断言(已经正确定义configASSERT()的情况下)。*/
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值