FreeRTOS学习(三)

3 FreeRTOSB队列

  • 3.1 队列基本知识
    队列可以在任务与任务、任务与中断之间传递消息,但是在队列中存储有限的、大小固定的数据项目。任务与任务、任务与中断之间交流的数据保存在队列中,叫做队列项目。队列所能保存的最大数据项目数量叫做队列的长度,我们在创建队列的时候需要制定数据项目的类型和队列的长度。由于队列是用于传递消息的,也成为消息队列,队列是信号量实现的依据。

  • 3.2 队列结构体
    该结构体定义在queue.c中,具体的成员如下:

      typedef struct QueueDefinition
      {
          int8_t *pcHead;  	 //指向队列存储区开始地址。
          int8_t *pcTail;		 //指向队列存储区最后一个字节。
          int8_t *pcWriteTo;  //指向存储区中下一个空闲区域。
          
          union 
          {
      	    //当用作队列的时候指向最后一个出队的队列项首地址
      	    int8_t *pcReadFrom;
      	    //当用作递归互斥量的时候用来记录递归互斥量被调用的次数
      	    UBaseType_t uxRecursiveCallCount;
          } u;
          
          //等待发送任务列表,那些因为队列满导致入队
          //失败而进入阻塞态的任务就会挂到此列表上。
          List_t xTasksWaitingToSend; 
          
          //等待接收任务列表,那些因为队列空导致出队失败而进
          //入阻塞态的任务就会挂到此列表上。
          List_t xTasksWaitingToReceive; 
          
          //队列中当前队列项数量,也就是消息数
          volatile UBaseType_t uxMessagesWaiting; 
          
          //创建队列时指定的队列长度,也就是队列中最大允许的队列项(消息)数量
          UBaseType_t uxLength; 
          
          //创建队列时指定的每个队列项(消息)最大长度,单位字节
          UBaseType_t uxItemSize; 
          
          //当队列上锁以后用来统计从队列中接收到的队列项数量,也就是出队
          //的队列项数量,当队列没有上锁的话此字段为 queueUNLOCKED
          volatile int8_t cRxLock; 
          
          //当队列上锁以后用来统计发送到队列中的队列项数量,也就是入队
          //的队列项数量,当队列没有上锁的话此字段为 queueUNLOCKED
          volatile int8_t cTxLock;
          
          #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) &&  \
          ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
         		uint8_t ucStaticallyAllocated; //如果使用静态存储的话此字段设置为 pdTURE。
          #endif
          
          #if ( configUSE_QUEUE_SETS == 1 ) //队列集相关宏
          	struct QueueDefinition *pxQueueSetContainer;
          #endif
          
          #if ( configUSE_TRACE_FACILITY == 1 ) //跟踪调试相关宏
      	    UBaseType_t uxQueueNumber;
      	    uint8_t ucQueueType;
          #endif
      } xQUEUE;
      
      typedef xQUEUE Queue_t;
    
  • 3.3 队列相关API函数

  • 3.3.1 队列创建

      xQueueCreate( ) && xQueueCreateStatic( )
          
          QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize );
          参数:
          uxQueueLength:要创建队列的长度,队列的项目数
          uxItemSize:队列中每个项目的长度,单位为字节(说白了就是队列项目成员的类型,可以是结构体(信息量大时可用)、 数组或者某一地址)
          QueueHandle_t xQueueCreatStatic(UBaseType_t uxQueueLength, UBaseType_t uxItemSize, uint8_t* pucQueueStorageBuffer,  StaticQueue_t * pxQueueBuffer);
          参数:
          uxQueueLength:要创建的队列的队列长度,指的是队列的项目数;
          uxItemSize:队列中每个项目的长度,单位为字节;
          pucQueueStorage:指向队列项目的存储区,也就是消息的存储区,该存储区需用户自行分配。此参数必须指向一个uint8_t类型的数组,同时该数组的存储区必须要大于等于(uxQueueLength * uxItemSize)的字节数
          pxQueueBuffer:指向StaticQueue_t类型的变量,用以保存队列结构体。
          
          返回值:
          其他值:队列创建成功,返回队列的句柄(使用该队列时需要用到该句柄)
          NULL:队列创建失败
    
  • 3.3.2 向队列发送消息
    FreeRTOS学习(三)_第1张图片

任务级函数:

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

xQueue:将数据发送到队列的句柄;
pvItemToQueue:指向要发送的消息,发送时将此消息拷贝到队列中;
xTicksToWait:阻塞时间,有三种情况。
1)该值为0时,当队列满,则立即返回;
				2)portMAX_DELAY,死等,直到队列有空闲的队列项;
				3)其他值,等待的时间(心跳次数)
返回值:
pdPASS:向队列发送消息成功;
errQUEUE_FULL:队列已满,消息发送失败;

BaseType_t xQueueOverwrite(QueueHandle_t xQueue, const void * pvItemToQueue);
参数:同上;
返回值:
pdPASS:向队列发送成功,只有返回该值。因为其不管队列是否有空闲,都会将其内容填充到队列的尾部,必将成功。

中断级函数:

BaseType_t xQueueSendFromISR( QueueHandle_t xQueue,  const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken );

BaseType_t xQueueSendToBackFromISR( QueueHandle_t xQueue,  const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken );

BaseType_t xQueueSendToFrontFromISR( QueueHandle_t xQueue,  const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken);

pxHigherPriorityTaskWolen:标记退出该函数以后是否进行任务切换,该值无需用户设置,由函数自行设置,只需提供该变量用于保存该值即可。当该值为pdTRUE时,则在退出中断服务函数之前一定要进行一次任务切换。

BaseType_t xQueueOverwriteFromISR( QueueHandle_t xQueue,
const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken );
  • 3.3.3 从队列读取消息

FreeRTOS学习(三)_第2张图片

  BaseType_t xQueueReceive ( QueueHandle_t xQueue, 		//队列句柄
					        void *pvBuffer,				//保存数据的缓冲区
					        TickType_t xTicksToWait);	//阻塞时间
    
    BaseType_t xQueuePeek (	QueueHandle_t xQueue, 	//队列句柄
									        void *pvBuffer,				//保存数据的缓冲区
									        TickType_t xTicksToWait);	//阻塞时间
    
    BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue,
							        void* pvBuffer,
							        BaseType_t * pxTaskWoken);
    
    BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void *pvBuffer);

你可能感兴趣的:(FreeRTOS)