rt-thread 消息队列初始化时的msg_size参数含义
rt_err_t rt_mq_init(rt_mq_t mq, const char* name,
void *msgpool, rt_size_t msg_size,
rt_size_t pool_size, rt_uint8_t flag);
我的例子中(代码见最后)的消息结构体是这样的,每次传递一个消息send_data[]大于2个字节,为什么消息还能发送并接收成功?
typedef struct {
ID_t eDataID;
rt_uint32_t lDataValue;
}Data_t;
/* 定义 2 个结构体 */
static const Data_t send_data[2] =
{
{eMotorSpeed, 10}, // CAN 线程发送的数据
{eSpeedSetPoint, 500} // HMI 线程
};
#关于线程接收问题
文档中接收线程是一个,若两个线程分别接收CAN数据和HMI数据,假如CAN接收数据线程的优先级高于HMI线程的话,那么CAN线程会有限读取消息队列中的数据,若读到的HMI的数据,那么这一个HMI的数据是不是就被丢掉了,因为读取消息队列中的数据时,它的head指针会变化。
#代码如下
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-08-15 RT-Thread first version
*/
#include <rtthread.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#define THREAD_PRIORITY 25
#define THREAD_STACK_SIZE 512
#define THREAD_TIMESLICE 5
static rt_thread_t thread1;
static rt_thread_t thread2;
static rt_thread_t thread3;
//static rt_thread_t thread4;
/* 消息队列控制块 */
static struct rt_messagequeue mq;
/* 消息队列中用到的放置消息的内存池 */
static rt_uint8_t msg_pool[2048];
/* 定义 2 种数据来源 (ID) */
typedef enum
{
eMotorSpeed,
eSpeedSetPoint
} ID_t;
/* 定义在消息队列中传输的数据的格式 */
typedef struct {
ID_t eDataID;
rt_uint32_t lDataValue;
}Data_t;
/* 定义 2 个结构体 */
static const Data_t send_data[2] =
{
{eMotorSpeed, 10}, // CAN 线程发送的数据
{eSpeedSetPoint, 500} // HMI 线程
};
/* 线程 1 的入口函数 */
static void thread1_entry(void *parameter)
{
int result;
Data_t *buf = parameter;
while(1)
{
/* 发送消息 */
result = rt_mq_send(&mq, buf, sizeof(buf));
if (result == RT_EFULL)
{
rt_kprintf("rt_mq_send FULL\n");
}
else if(result ==RT_ERROR)
{
rt_kprintf("rt_mq_send ERR\n");
}
rt_thread_mdelay(20);
}
}
/* 线程 3 的入口函数 */
static void thread3_entry(void *parameter)
{
Data_t buf;
while(1)
{
/* 接收消息 */
if (rt_mq_recv(&mq, &buf, sizeof(buf), RT_WAITING_FOREVER) == RT_EOK)
{
if(buf.eDataID == eSpeedSetPoint)
{
rt_kprintf("From HMI = %d\r\n", buf.lDataValue);
}
////若只用一个接收线程这里打开,若开启thread4,这里屏蔽
else if(buf.eDataID == eMotorSpeed)
{
rt_kprintf("From CAN =%d\r\n", buf.lDataValue);
}
}
rt_thread_mdelay(10);
}
}
///* 线程 4 的入口函数 */
//static void thread4_entry(void *parameter)
//{
// Data_t buf;
//
// while(1)
// {
// /* 接收消息 */
// if (rt_mq_recv(&mq, &buf, sizeof(buf), RT_WAITING_FOREVER) == RT_EOK)
// {
// if(buf.eDataID == eMotorSpeed)
// {
// rt_kprintf("From CAN =%d\r\n", buf.lDataValue);
// }
//
// }
// rt_thread_mdelay(10);
// }
//}
int main(void)
{
rt_err_t result;
/* 初始化消息队列 */
result = rt_mq_init(&mq, // 消息队列对象的句柄
"mqt", // 消息队列的名字
&msg_pool[0], // 内存池指向 msg_pool
2, // 每个消息的大小是 1 字节
sizeof(msg_pool), // 内存池的大小是 msg_pool 的大小
RT_IPC_FLAG_FIFO); // 如果有多个线程等待,按照先来先得到的方法分配消息
if (result != RT_EOK)
{
rt_kprintf("rt_mq_init ERR\n");
return -1;
}
/* 创建动态线程 thread1 ,优先级为 THREAD_PRIORIT = 15 */
thread1 = rt_thread_create("thread1", // 线程名字
thread1_entry, // 入口函数
(void *)&send_data[0], // 入口 函数参数
THREAD_STACK_SIZE, // 栈大小
THREAD_PRIORITY, // 线程优先级
THREAD_TIMESLICE); // 线程时间片大小
/* 判断创建结果 , 再启动线程 1 */
if (thread1 != RT_NULL)
rt_thread_startup(thread1);
/* 创建动态线程 thread2 ,优先级为 THREAD_PRIORIT = 15 */
thread2 = rt_thread_create("thread2", // 线程名字
thread1_entry, // 入口函数
(void *)&send_data[1], // 入口函数参数
THREAD_STACK_SIZE, // 栈大小
THREAD_PRIORITY, // 线程优先级
THREAD_TIMESLICE); // 线程时间片大小
/* 判断创建结果 , 再启动线程 2 */
if (thread2 != RT_NULL)
rt_thread_startup(thread2);
/* 创建动态线程 thread3 ,优先级为 THREAD_PRIORIT+1 = 16 */
thread3 = rt_thread_create("thread3", // 线程名字
thread3_entry, // 入口函数
RT_NULL, // 入口函数参数
THREAD_STACK_SIZE, // 栈大小
THREAD_PRIORITY + 1, // 线程优先级
THREAD_TIMESLICE); // 线程时间片大小
/* 判断创建结果 , 再启动线程 3 */
if (thread3 != RT_NULL)
rt_thread_startup(thread3);
// /* 创建动态线程 thread3 ,优先级为 THREAD_PRIORIT+1 = 16 */
// thread4 = rt_thread_create("thread4", // 线程名字
// thread4_entry, // 入口函数
// RT_NULL, // 入口函数参数
// THREAD_STACK_SIZE, // 栈大小
// THREAD_PRIORITY - 2, // 线程优先级
// THREAD_TIMESLICE); // 线程时间片大小
// /* 判断创建结果 , 再启动线程 4 */
// if (thread4 != RT_NULL)
// rt_thread_startup(thread4);
return 0;
}