Queue概述
Queue即消息队列是通过RTOS内核提供的一种服务。它是一种线程间同步数据的安全方法。
队列(Queue)是与栈对应的概念;栈是FILO结构,而队列是FIFO结构。FreeRTOS原生的队列支持从高位添加新数据,但CMSIS简化删去了这一功能,即只能从队列底部推入数据并且对数据类型有限制,这一简化一般不影响使用。
- RTOS中Queue的工作原理:
- API Description:
1.使用**osMessageQueueNew() 创建队列
该函数会涉及osMessageQueueAttr_t **配置结构体;主要用于配置Control Block和名称;一旦使用该结构体将导致只能使用静态方式创建队列;一般传入NULL即可
osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr);/*
创建新的Queue队列
@retval -队列地址(Queue Identifier)
@param msg_count -队列可容纳的消息(变量)数量
@param msg_size -消息(变量)占用的空间[通常用sizeof()填入]
@param *attr -配置结构体对象,一般为NULL。 当传入NULL时,仅使用xQueueCreate()动态创建对应大小、数量的队列;
*/
2.使用**osMessageQueueDelete() **删除队列
该函数能释放队列占用的空间并清除其中内容和任务规划。队列删除后可通过**osMessageQueueNew() **重新创建。
osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id);/*删除队列
@retval -osOK: the message queue object has been deleted.
-osErrorParameter: parameter mq_id is NULL or invalid.
-osErrorResource: the message queue is in an invalid state.
-osErrorISR: osMessageQueueDelete cannot be called from interrupt service routines.
*/
3.获取队列配置信息
uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id );
/*获取队列可容纳的消息(变量)数量; []
*/
uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id );
/* 获取消息(变量)占用的空间 [单位byte]
*/
uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id );/*
查询队列中空位(未填入变量)的数量
*/
uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id );/*
查询队列中已写入的消息(变量)数量
*/
4.※ 读取(取出)/写入队列
关于阻塞超时时间:
①读取(取出)阻塞超时:当任务读一个消息队列时,可通过osMessageQueueGet()设置阻塞超时时间。在这段时间中,如果队列为空(无变量),该任务将保持BLOCK状态以等待队列数据有效。在此期间当任务检测到其等待的队列中写入了数据时,将自动由BLOCK态转移为READY态。当等待的时间超过了指定的阻塞时间,即使队列中尚无数据,任务也会自动从阻塞态转移为READY态。此时程序会返回osErrorTimeout错误。若没有设置阻塞超时且参数正确,返回osErrorResource错误**。**
由于队列可以被多个任务读取,所以对单个队列而言,也可能有多个任务处于BLOCK
状态以等待队列数据有效。这种情况下,一旦队列数据有效,所有等待任务中优先级最高的任务被执行。而如果所有等待任务的优先级相同,那么被解除阻塞的任务将是等待最久的任务。
②写入阻塞超时: 同读队列一样,任务也可以在写队列时指定一个阻塞超时时间。这个时间是当被写队列已满时,任务进入BLOCK态以等待队列空间有效的最长时间。当等待的时间超过了指定的阻塞时间,即使队列中尚无数据,任务也会自动从BLOCK态转移为READY态。此时程序会返回osErrorTimeout错误。若没有设置阻塞超时且参数正确,返回osErrorResource错误。由于队列可以被多个任务写入,所以对单个队列而言,也可能有多个任务处于BLOCK
状态以等待队列空间有效。这种情况下,一旦队列空间有效,所有等待任务中优先级最高的任务被执行。而如果所有等待任务的优先级相同,那么被解除阻塞的任务将是等待最久的任务。
阻塞超时时间(timeout 变量)有三种配置:
== 0U //不设置阻塞超时时间,若出现上述队列异常函数将直接报错返回
== osWaitForever //任务将一直阻塞直到空队列被写入/满队列被取出数据
== Ticks //设置具体等待时间,单位为RTOS心跳数(Ticks)
①用 osMessageQueueGet() 取出数据**【※可在中断中使用】**
osStatus_t osMessageQueueGet ( osMessageQueueId_t mq_id,
void * msg_ptr, //储存读取结果的变量地址
uint8_t * msg_prio, // ==NULL
uint32_t timeout //阻塞超时时间
);
①用 osMessageQueuePut() 写入**【※可在中断中使用】**
osStatus_t osMessageQueuePut ( osMessageQueueId_t mq_id,
const void * msg_ptr, //储存写入内容的变量地址
uint8_t msg_prio, //==0U
uint32_t timeout //阻塞超时时间
);
读出/写入的返回状态值:
-osOK: 取出/写入成功
-osErrorTimeout: the message could not be retrieved from/put into the queue in the given time (timed-wait semantics).
-osErrorResource: nothing to get from the queue or no space to push.
-osErrorParameter: parameter mq_id is NULL or invalid, non-zero timeout specified in an ISR.
5.清空队列
osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id);/*
@retval: -osOK: the message queue has been rest.
-osErrorParameter: parameter mq_id is NULL or invalid.
-osErrorResource: the message queue is in an invalid state.
-osErrorISR: osMessageQueueReset cannot be called from interrupt service routines.
*/
-
CMSIS
+关注
关注
0文章
40浏览量
11902 -
RTOS
+关注
关注
22文章
813浏览量
119633 -
FreeRTOS
+关注
关注
12文章
484浏览量
62172 -
Queue
+关注
关注
0文章
16浏览量
7261 -
FIFO存储
+关注
关注
0文章
103浏览量
5973
发布评论请先 登录
相关推荐
评论