1.代码
//mq.c
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_gpio.h"
#define THREAD_PRIORITY 25
#define THREAD_TIMESLICE 10
#define TASK_STACK_MAX 500
/* 消 息 队 列 控 制 块 */
static struct rt_messagequeue mq;
/* 消 息 队 列 中 用 到 的 放 置 消 息 的 内 存 池 */
static rt_uint8_t msg_pool[32];
ALIGN(RT_ALIGN_SIZE)
static char thread51_stack[TASK_STACK_MAX];
static struct rt_thread thread51;
/* 线 程 1 入 口 函 数 */
static void thread51_entry(void *parameter)
{
char buf = 0;
rt_uint8_t cnt = 0;
while (1)
{
/* 从 消 息 队 列 中 接 收 消 息 */
if (rt_mq_recv(&mq, &buf, sizeof(buf), RT_WAITING_FOREVER) == RT_EOK)
{
rt_kprintf("thread51: recv msg from msg queue, the content:%c\n", buf);
// if (cnt == 19)
// {
// break;
// }
}
/* 延 时 50ms */
cnt++;
rt_thread_mdelay(1000);
}
// rt_kprintf("thread51: detach mq \n");
// rt_mq_detach(&mq);
}
void MqKeyScanCallBack(void)
{
int result;
static char buf = 'A';
static rt_uint8_t cnt = 0;
// while (1)
{
if (cnt == 8)
{
/* 发 送 紧 急 消 息 到 消 息 队 列 中 */
result = rt_mq_urgent(&mq, &buf, 1);
if (result == RT_EOK)
{
rt_kprintf("thread52: send urgent message - %c\n", buf);
rt_kprintf("the priority of thread52 is: %s %d\n", rt_thread_self()->name,rt_thread_self()->current_priority);
buf++;
cnt++;
}
else if(result == -RT_EFULL)
{
rt_kprintf("rt_mq_urgent Full\n");
}
else
{
rt_kprintf("rt_mq_urgent ERR,0x%x\n",result);
}
}
else if (cnt>= 20)/* 发 送 20 次 消 息 之 后 退 出 */
{
buf = 'A';
cnt = 0;
// rt_kprintf("message queue stop send, thread52 quit\n");
// break;
}
else
{
/* 发 送 消 息 到 消 息 队 列 中 */
result = rt_mq_send(&mq, &buf, 1);
if (result == RT_EOK)
{
rt_kprintf("thread52: send message - %c\n", buf);
buf++;
cnt++;
}
else if(result == -RT_EFULL)
{
rt_kprintf("rt_mq_urgent Full\n");
}
else
{
rt_kprintf("rt_mq_urgent ERR,0x%x\n",result);
}
}
/* 延 时 5ms */
// rt_thread_mdelay(5);
}
}
int MqTaskInit(void)
{
rt_err_t result;
/* 初 始 化 消 息 队 列 */
result = rt_mq_init(&mq,
"mqt",
&msg_pool[0], /* 内 存 池 指 向 msg_pool */
1, /* 每 个 消 息 的 大 小 是 1 字 节 */
sizeof(msg_pool), /* 内 存 池 的 大 小 是 msg_pool 的 大 小
*/
RT_IPC_FLAG_FIFO); /* 如 果 有 多 个 线 程 等 待, 按 照 先 来 先 得
到 的 方 法 分 配 消 息 */
if (result != RT_EOK)
{
rt_kprintf("init message queue failed.\n");
return -1;
}
rt_thread_init(&thread51,
"thread51",
thread51_entry,
RT_NULL,
&thread51_stack[0],
sizeof(thread51_stack), 25, 5);
rt_thread_startup(&thread51);
return 0;
}
2.分析
static rt_uint8_t msg_pool[32]; 消息池有32字节,每个消息大小为4字节,消息池能放4个消息。查看rt_mq_init()源码
/* get correct message size */
mq->msg_size = RT_ALIGN(msg_size, RT_ALIGN_SIZE);
mq->max_msgs = pool_size / (mq->msg_size + sizeof(struct rt_mq_message));
可以看出,实际的消息大小和消息数量需特别注意是否符合任务需求。
3.输出
list_thread
thread pri status sp stack size max used left tick error
-------- --- ------- ---------- ---------- ------ ---------- ---
usr1 6 suspend 0x00000078 0x0000012c 40% 0x00000014 000
thread51 25 suspend 0x000000a0 0x000001f4 32% 0x00000005 000
thread3 8 suspend 0x00000088 0x000001f4 27% 0x00000005 000
tshell 20 running 0x00000094 0x00001000 12% 0x00000006 000
tidle0 31 ready 0x00000060 0x00000100 37% 0x00000002 000
timer 4 suspend 0x00000064 0x00000200 19% 0x00000009 000
main 10 suspend 0x00000098 0x00000800 13% 0x00000014 000
msh >
msh >
key press val is 1
thread52: send message - A
thread51: recv msg from msg queue, the content:A
key press val is 1
thread52: send message - B
key press val is 1
thread52: send message - C
key press val is 1
thread52: send message - D
key press val is 1
thread52: send message - E
key press val is 1
rt_mq_urgent Full
thread51: recv msg from msg queue, the content:B
key press val is 1
thread52: send message - F
key press val is 1
rt_mq_urgent Full
key press val is 1
rt_mq_urgent Full
thread51: recv msg from msg queue, the content:C
thread51: recv msg from msg queue, the content:D
thread51: recv msg from msg queue, the content:E
thread51: recv msg from msg queue, the content:F
key press val is 1
thread52: send message - G
thread51: recv msg from msg queue, the content:G
key press val is 1
thread52: send message - H
thread51: recv msg from msg queue, the content:H
key press val is 1
thread52: send urgent message - I
the priority of thread52 is: tidle0 31
thread51: recv msg from msg queue, the content:I
key press val is 1
thread52: send message - J
thread51: recv msg from msg queue, the content:J