嵌入式技术william hill官网
直播中

laisvl

8年用户 1051经验值
私信 关注
[问答]

请问使用消息队列处理串口接收出现线程卡住的问题怎么解决?

代码如下,串口中断里面发送消息,在serial_thread_entry线程里面接收,发现数据量比较大的时候,中断uart_input里面报消息队列满了之后,result = rt_mq_recv(rx_mq, (void*)&msg, sizeof(msg), 5);会一直卡在这里面,设置了超时也没有任何作用,是不是系统的bug?

#include <rtthread.h>
//#include <board.h>
#include <rtdevice.h>
//#include "debug_pin.h"
#define SAMPLE_UART_NAME "uart2" /* 串口设备名称 /
#define BUF_SIZE (256)
/
串口接收消息结构*/
struct rx_msg
{
//rt_device_t dev;
//rt_size_t size;
char buffer[BUF_SIZE + 1];
rt_size_t size;
};
/* 串口设备句柄 /
static rt_device_t serial;
/
消息队列控制块 /
static struct rt_messagequeue
rx_mq;
/* 接收数据回调函数 /
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
struct rx_msg msg;
rt_err_t result;
//msg.dev = dev;
//msg.size = size;
msg.size = rt_device_read(dev, 0, msg.buffer, BUF_SIZE);
result = rt_mq_send(rx_mq, (void
)&msg, sizeof(msg));
rt_kprintf("mlen %d\n", size);
if ( result == -RT_EFULL)
{
/* 消息队列满 /
rt_kprintf("message queue full!\n");
}
return result;
}
static void serial_thread_entry(void parameter)
{
struct rx_msg msg;
rt_err_t result;
//rt_uint32_t rx_length;
//static char rx_buffer[BUF_SIZE + 1];
rt_kprintf("start serial thread\n");
while (1)
{
rt_memset(&msg, 0, sizeof(msg));
/
从消息队列中读取消息
/
result = rt_mq_recv(rx_mq, (void*)&msg, sizeof(msg), 5);//RT_WAITING_FOREVER);
if (result == RT_EOK)
{
/* 从串口读取数据*/
//rx_length = rt_device_read(msg.dev, 0, rx_buffer, msg.size);
//rx_buffer[rx_length] = '\0';
msg.buffer[msg.size] = '\0';
/* 通过串口设备 serial 输出读取到的消息 /
//debug_pin_on();
//rt_device_write(serial, 0, rx_buffer, rx_length);
rt_device_write(serial, 0, msg.buffer, msg.size);
//debug_pin_off();
/
打印数据 */
rt_kprintf("%s\n",msg.buffer);
}
}
}
static rt_err_t uart_tx_finish(rt_device_t dev, void buffer)
{
rt_kprintf("message tx finish!\n");
return RT_EOK;
}
int uart_dma_sample(void)
{
rt_err_t ret = RT_EOK;
char uart_name[RT_NAME_MAX];
char str[] = "hello RT-Thread!\r\n";
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX);
/
查找串口设备 /
serial = rt_device_find(uart_name);
if (!serial)
{
rt_kprintf("find %s failed!\n", uart_name);
return RT_ERROR;
}
/
初始化消息队列 /
rx_mq = rt_mq_create("rx_mq", sizeof(struct rx_msg), 3, RT_IPC_FLAG_PRIO);
config.baud_rate = BAUD_RATE_115200;
config.data_bits = DATA_BITS_8;
config.stop_bits = STOP_BITS_1;
config.bufsz = BUF_SIZE;
config.parity = PARITY_NONE;
rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);
/
以 DMA 接收及轮询发送方式打开串口设备 /
rt_device_open(serial, RT_DEVICE_FLAG_DMA_RX|RT_DEVICE_FLAG_INT_TX);//RT_DEVICE_FLAG_DMA_RX);
/
设置接收回调函数 /
rt_device_set_rx_indicate(serial, uart_input);
rt_device_set_tx_complete(serial, uart_tx_finish);
/
发送字符串 /
rt_device_write(serial, 0, str, (sizeof(str) - 1));
/
创建 serial 线程 /
rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10);
/
创建成功则启动线程 /
if (thread != RT_NULL)
{
rt_thread_startup(thread);
}
else
{
ret = RT_ERROR;
}
return ret;
}
/
导出到 msh 命令列表中 */
MSH_CMD_EXPORT(uart_dma_sample, uart device dma sample);
void uart_task(void)
{
uart_dma_sample();
}

回帖(3)

李波

2023-2-8 10:53:27
rx_mq = rt_mq_create("rx_mq", sizeof(struct rx_msg), 3, RT_IPC_FLAG_PRIO);
你这个消息队列池,只有一个消息体大小的内存容量,但是你还想用仨。绝对会内存溢出。
举报

王霞

2023-2-8 10:53:36
受到警告
提示: 作者被禁止或删除 内容自动屏蔽
举报

laisvl

2023-2-8 10:53:49
问题找到了,对比了教程的代码,我在串口初始化时,增加了RT_DEVICE_FLAG_INT_TX,只要加上,就会出现上面的问题。我直接用教程的代码,也加上RT_DEVICE_FLAG_INT_TX,也有这个问题。应该是一个系统层面的bug。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分