数据存储
队列可以存储有限大小,且数据类型固定的数据。队列所能存储的最大数据量称为队列的长度。队列的长度与队列里元素的大小在队列创建时就已固定。队列经常别用作为先进先出存储。
实现队列的功能可通过两种方法。
通过复制的方法:将要进入队列的数据复制到队列中。
通过指针的方式:将需要进入队列的数据的指针放到队列中。
FREERTOS采用复制的方式进行队列数据的存储。
任务的入口
队列可以被知道队列存在的任一任务和中断读写。任一任务可以向同一个队列读写数据,一般情况下,一个队列具有较多写者,但不会有太多读者。
队列读者的阻塞
当一个任务尝试从一个队列中读数据时,可以可选的采用进入阻塞的方式,直到可以从该队列中读到数据。当任务处于读数据的阻塞状态时,一旦队列中有了数据,此时任务会自动从阻塞态转到就绪态。如果设定了超时时间,则在时间超时后任务依旧会自动从阻塞态转到就绪态。
队列一般有多个读者,则当有多个读者任务处于阻塞状态时,一旦有数据来临,则优先级最高的读者任务会先读数据,若读者任务优先级相同,则等待时间最长的任务会先读数据。
队列写者的阻塞
与读队列类似,写者也可以采用指定一个阻塞时间方式进入阻塞状态等待可以写数据或阻塞时间超时。
队列的使用
xQueueCreate()
创建队列,该函数用于创建一个队列并返回队列的句柄,当执行该函数时,该系统会从系统堆栈中分配一部分内存给该队列。其函数原型如下:
QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize );
相关参数:
uxQueueLength:用于表示该队列的长度。
uxItemSize :表示队列中每个数据的大小。
return value :表明创建的队列的句柄,若为NULL则表示空间不足导致创建失败。
xQueueReset() :当队列创建后,可用该函数将队列复位成原来的刚生成时状态。
xQueueSendToBack() 与 xQueueSendToFront()
前者用于将数据送到队列尾部,后者用于将数据送到队列头部。xQueueSend()与前者完全相同。
注意:永远不要在中断中使用上述两种写队列的方法。在中断中有专门的写队列函数:xQueueSendToFrontFromISR() 与xQueueSendToBackFromISR()。后面会有相关讲解。
函数原型如下所示:
BaseType_t xQueueSendToFront( QueueHandle_t xQueue,
const void * pvItemToQueue,
TickType_t xTicksToWait );
BaseType_t xQueueSendToBack( QueueHandle_t xQueue,
const void * pvItemToQueue,
TickType_t xTicksToWait );
参数讲解:
xQueue:表明了队列的句柄。
pvItemToQueue:将要复制到队列中的数据的地址。
xTicksToWait :表示进入阻塞状态所等待的最大时间。当FreeRTOSConfig.h中的INCLUDE_vTaskSuspend设置为1时,若该参数输入为portMAX_DELAY,则该函数会无限期等待,并不会超时。
返回值(return value):1,pdPASS表示成功将数据写入队列。2,errQUEUE_FULL:表示在设置的时间内并没有将数据写进去。
xQueueReceive()
该函数用于从队列中读取一个数据,一旦读取之后,该值就会从队列中清除掉。通写数据,在中断中不可调用该函数,中断中有相应函数。
函数原型如下:
BaseType_t xQueueReceive