环形队列
a.采用第一个环形队列有如下结构:
typedef struct ringq{
int head; /* 头部,出队列方向*/
int tail; /* 尾部,入队列方向*/
int tag ;
int size ; /* 队列总尺寸 */
int space[RINGQ_MAX]; /* 队列空间 */
}RINGQ;
q->head = q->tail = q->tag = 0;
队列为空:
( q->head == q->tail) && (q->tag == 0)
队列为满 :
((q->head == q->tail) && (q->tag == 1))
入队操作,如队列不满,则写入:
q->tail = (q->tail + 1) % q->size ;
q->head = (q->head + 1) % q->size
头文件ringq.h:
extern "C" {
typedef struct ringq{
int head; /* 头部,出队列方向*/
int tail; /* 尾部,入队列方向*/
int tag ; /* 为空还是为满的标志位*/
int size ; /* 队列总尺寸 */
int space[QUEUE_MAX]; /* 队列空间 */
}RINGQ;
/*
第一种设计方法:
当head == tail 时,tag = 0 为空,等于 = 1 为满。
*/
extern int ringq_init(RINGQ * p_queue);
extern int ringq_free(RINGQ * p_queue);
/* 加入数据到队列 */
extern int ringq_push(RINGQ * p_queue,int data);
/* 从队列取数据 */
extern int ringq_poll(RINGQ * p_queue,int *p_data);
}
源代码 ringq.c:
#include
#include "ringq.h"
int ringq_init(RINGQ * p_queue)
{
p_queue->size = QUEUE_MAX ;
p_queue->head = 0;
p_queue->tail = 0;
p_queue->tag = 0;
return 0;
}
int ringq_free(RINGQ * p_queue)
{
return 0;
}
int ringq_push(RINGQ * p_queue,int data)
{
print_ringq(p_queue);
if(ringq_is_full(p_queue))
{
printf("ringq is full\n");
return -1;
}
p_queue->space[p_queue->tail] = data;
p_queue->tail = (p_queue->tail + 1) % p_queue->size ;
/* 这个时候一定队列满了*/
if(p_queue->tail == p_queue->head)
{
p_queue->tag = 1;
}
return p_queue->tag ;
}
int ringq_poll(RINGQ * p_queue,int * p_data)
{
print_ringq(p_queue);
if(ringq_is_empty(p_queue))
{
printf("ringq is empty\n");
return -1;
}
*p_data = p_queue->space[p_queue->head];
p_queue->head = (p_queue->head + 1) % p_queue->size ;
/* 这个时候一定队列空了*/
if(p_queue->tail == p_queue->head)
{
p_queue->tag = 0;
}
return p_queue->tag ;
}
消息队列
xQueue = xQueueCreate(QUEUE_LEN, QUEUE_SIZE);
任务或者中断服务程序都可以给消息队列发送消息,当发送消息时,如果队列未满或者允许覆盖入队,FreeRTOS 会将消息拷贝到消息队列队尾,否则,会根据用户指定的阻塞超时时间进行阻塞,在这段时间中,如果队列一直不允许入队,该任务将保持阻塞状态以等待队列允许入队。当其它任务从其等待的队列中读取入了数据(队列未满),该任务将自动由阻塞态转移为就绪态。当等待的时间超过了指定的阻塞时间,即使队列中还不允许入队,任务也会自动从阻塞态转移为就绪态,此时发送消息的任务或者中断程序会收到一个错误码 errQUEUE_FULL。
“环形队列”和“消息队列”的异同
END
来源:嵌入式专栏
→点关注,不迷路←