搜索
bottom↓
回复: 24

求助:rt-thread频繁接收串口数据后挂了

[复制链接]
(85413316)

出0入0汤圆

发表于 2018-7-30 08:31:01 | 显示全部楼层 |阅读模式
用stm32f103跑的操作系统,开机的时候本机会不停的收到上位机发送的指令,此时容易系统就会挂掉,但是重新启动本机就能正常通信。请教大神们问题可能出现在哪些地方?
(85412570)

出0入0汤圆

发表于 2018-7-30 08:43:27 | 显示全部楼层
堆栈溢出?
(85412515)

出0入0汤圆

发表于 2018-7-30 08:44:22 | 显示全部楼层
还是在自己代码上找问题吧,十有八九堆栈开的太小
(85412243)

出80入10汤圆

发表于 2018-7-30 08:48:54 | 显示全部楼层
可能是数据的生产和消费关系没有协调好。通信要多关注这一点
(85410471)

出0入0汤圆

发表于 2018-7-30 09:18:26 | 显示全部楼层
要等 任务创建完毕,串口都初始化好了在打开接收中断,

楼主目前的做法有堆栈溢出的问题,
(85402752)

出0入20汤圆

发表于 2018-7-30 11:27:05 | 显示全部楼层
xiaomu 发表于 2018-7-30 09:18
要等 任务创建完毕,串口都初始化好了在打开接收中断,

楼主目前的做法有堆栈溢出的问题,  ...

肯定是溢出了。我怀疑LZ就是在中断里一气跑到底的。
(85398550)

出0入0汤圆

发表于 2018-7-30 12:37:07 来自手机 | 显示全部楼层
楼上的都是猜测,你描述太简单,无法分析问题,串口怎么用的,系统挂掉是什么状态,程序运行到哪里了?
(85379732)

出0入0汤圆

发表于 2018-7-30 17:50:45 | 显示全部楼层
上代码吧


(85367070)

出0入0汤圆

发表于 2018-7-30 21:21:47 来自手机 | 显示全部楼层
对,楼主问题给的不详细啊
(85283720)

出0入0汤圆

 楼主| 发表于 2018-7-31 20:30:57 | 显示全部楼层
我的流程是:
1.线程创建前初始化串口:
rt_hw_usart_init();//串口初始化
    rt_uart_device_init();
void rt_uart_device_init(void)
{
        uart1_device_disboard = rt_device_find("uart1");//初始化串口1,显示板
        if (uart1_device_disboard != RT_NULL)
        {
            rt_device_open(uart1_device_disboard,  RT_DEVICE_OFLAG_RDWR|RT_DEVICE_FLAG_INT_RX);
        }
        uart2_device_inverter = rt_device_find("uart2");//初始化串口2,
        if (uart2_device_inverter != RT_NULL)
        {
            rt_device_open(uart2_device_inverter, RT_DEVICE_OFLAG_RDWR|RT_DEVICE_FLAG_DMA_RX);
        }      
        uart3_device_host = rt_device_find("uart3");//初始化串口3,上位机
        if (uart3_device_host != RT_NULL)
        {
            rt_device_open(uart3_device_host,  RT_DEVICE_OFLAG_RDWR|RT_DEVICE_FLAG_INT_RX);
        }
}
2.void sys_cmmu_entry(void* parameter)
{
    while(1)
    {            
        commu_task_host();
        rt_thread_delay( RT_TICK_PER_SECOND/200 );//0.1s检查一次
    }
}
3.线程创建
    init_thread = rt_thread_create("sys_cmmu_task",
            sys_cmmu_entry,RT_NULL,
        1000,1,10);
    if (init_thread != RT_NULL)
    {        
        rt_thread_startup(init_thread);//启动主机通讯
    }
原本commu_task_host()里面有一个while进行接收处理超时就跳出,我把这个去掉后就正常了
uint8_t commu_task_host(void)
{
        uint8_t tmp_buf[32], i, tmp_len;
        uint16_t tmp_cmd_index;
//    while(1)
//    {
        if (rt_device_read(uart3_device_host,0,tmp_buf, 1))
        {
            if (0 == cmmu_host_rx.rx_data_index)
            {
                if (RS485_DATA_SYN == tmp_buf[0])
                {
                    cmmu_host_rx.all_buf.dat.syn = RS485_DATA_SYN;
                    cmmu_host_rx.rx_data_index = 1;
                }
            }
            else
            {
                cmmu_host_rx.all_buf.buf[cmmu_host_rx.rx_data_index++] = tmp_buf[0];
                if (cmmu_host_rx.rx_data_index > 30)
                {
                    cmmu_host_rx.rx_data_index = 0;
初始化的时候上位机会给本机和其它下位机大量通讯,此处的while对数据中断读取有影响吗?还是数据量过大没处理导致溢出?
(85280886)

出0入0汤圆

发表于 2018-7-31 21:18:11 来自手机 | 显示全部楼层
自带例程跑的有问题,现在不知道改进没有?
(85277798)

出0入50汤圆

发表于 2018-7-31 22:09:39 | 显示全部楼层
检测下有没有可能串口接收溢出错误(不是内存缓存溢出)
(85274372)

出0入4汤圆

发表于 2018-7-31 23:06:45 来自手机 | 显示全部楼层
RTT串口用中断和DMA,切记
(85240799)

出0入0汤圆

 楼主| 发表于 2018-8-1 08:26:18 | 显示全部楼层
Excellence 发表于 2018-7-31 21:18
自带例程跑的有问题,现在不知道改进没有?

例程是有问题,上次发现用设置串口用中断接收数据老是进不去,最后发现串口初始化在硬件初始化程序里面,而硬件初始化又在堆栈初始化前面,串口初始化的时候分配缓存空间,而总剩余空间大小为0导致分配失败(总空间大小在heap初始化后才会被赋值),后面把串口初始化放到堆栈初始化侯后面就好了。
(85240774)

出0入0汤圆

 楼主| 发表于 2018-8-1 08:26:43 | 显示全部楼层
icoyool 发表于 2018-7-31 23:06
RTT串口用中断和DMA,切记

我现在用的是中断接收
(85240656)

出0入198汤圆

发表于 2018-8-1 08:28:41 | 显示全部楼层
你在 uint8_t commu_task_host(void) 里用 while(1) 去 read device ,并且没有加入任何让出 CPU 的操作,肯定会卡死的呀。
(85240300)

出0入198汤圆

发表于 2018-8-1 08:34:37 | 显示全部楼层


给你提供个思路。参考 RT-Thread 的 AT 组件部分代码,使用设备接收回调,来通知你的接收线程。

里面的 client_rx_fifo 在你的场景上可能用不上,视情况做下修改。

https://github.com/RT-Thread/rt- ... /at_cli.c#L173-L211

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
(85239837)

出0入0汤圆

 楼主| 发表于 2018-8-1 08:42:20 | 显示全部楼层
yyts 发表于 2018-7-31 22:09
检测下有没有可能串口接收溢出错误(不是内存缓存溢出)

    if (USART_GetFlagStatus(uart->uart_device, USART_FLAG_ORE) == SET)
    {
        stm32_getc(serial);
        USART_ClearFlag(uart->uart_device,USART_FLAG_ORE);//若出现数据未读被覆盖则先清除再覆盖
    }
昨天有看到过进串口溢出,后面加了处理,但是好像不是这个的影响,这是另外一个串口出现溢出。
(85236818)

出0入0汤圆

发表于 2018-8-1 09:32:39 | 显示全部楼层
懒成狗的猫 发表于 2018-8-1 08:26
例程是有问题,上次发现用设置串口用中断接收数据老是进不去,最后发现串口初始化在硬件初始化程序里面, ...

我发现好几个人都说串口,还有ADC。。。。
(85229409)

出0入0汤圆

发表于 2018-8-1 11:36:08 | 显示全部楼层
sunnydragon 发表于 2018-8-1 08:34
给你提供个思路。参考 RT-Thread 的 AT 组件部分代码,使用设备接收回调,来通知你的接收线程。

里面的  ...

这个处理方法跟我的如出一辙 本质上也是rthread中finsh的处理方式
(85221278)

出0入4汤圆

发表于 2018-8-1 13:51:39 | 显示全部楼层
懒成狗的猫 发表于 2018-8-1 08:26
我现在用的是中断接收

我意思是不要用RTT的原装驱动,
要自己写, DMA或者中断,
如果你用了串口FINSH, 对应的串口可以用原装驱动.
我发现RTT为了通用性,串口的效率不是很高

(85149303)

出0入50汤圆

发表于 2018-8-2 09:51:14 | 显示全部楼层
懒成狗的猫 发表于 2018-8-1 08:42
if (USART_GetFlagStatus(uart->uart_device, USART_FLAG_ORE) == SET)
    {
        stm32_getc(se ...

调试一下,看挂了之后,程序卡在哪里,如果是串口接收溢出错误,而没有清除标志的话,会不断进入串口中断函数.
(77898857)

出0入0汤圆

发表于 2018-10-25 07:52:00 | 显示全部楼层
楼主的问题解决了吗?

现在我也碰到了这个问题。

这个是我的处理方式

rt_uint8_t gps_stack[1024];
struct rt_thread gps_thread;

rt_uint8_t GPS_timeflag=0;
rt_uint8_t GPS_stateflag=0;
rt_uint16_t GPS_timeCnt=0;


struct gps_rx_msg  
{  
    rt_device_t dev;  
    rt_size_t   size;  
};

static struct rt_messagequeue gps_rx_mq;

static unsigned char gps_rx_buffer[1024];
static unsigned char gps_msg_pool[1024];


rt_err_t gps_input(rt_device_t dev, rt_size_t size)
{
        struct gps_rx_msg msg;
        msg.dev = dev;
        msg.size = size;

        rt_mq_send(&gps_rx_mq, &msg, sizeof(struct gps_rx_msg));
        return RT_EOK;
}

void gps_thread_entry(void* parameter)
{
        uint8_t gpspow_openstate=0;               
        struct gps_rx_msg msg;
        rt_device_t device;
        rt_err_t result = RT_EOK;
        
        
        device = rt_device_find(GPS_USE_UART);
        if (device!= RT_NULL)
        {

                rt_device_set_rx_indicate(device, gps_input);

                if(rt_device_open(device, RT_DEVICE_OFLAG_RDWR|RT_DEVICE_FLAG_INT_RX)== RT_EOK)
                        ;
                else
                        rt_kprintf("Open GPS %s false!\r\n",GPS_USE_UART);
        }
        else
                rt_kprintf("Find GPS %s false!\r\n",GPS_USE_UART);
        
        while(1)
        {
               
                result = rt_mq_recv(&gps_rx_mq, &msg, sizeof(struct gps_rx_msg), 10);                        
                if (result == -RT_ETIMEOUT)
                {
                }
                if (result == RT_EOK)
                {
                        rt_uint32_t rx_length;
                        rx_length = (sizeof(gps_rx_buffer) - 1) > msg.size ? msg.size : sizeof(gps_rx_buffer) - 1;
                        
                        rx_length = rt_device_read(msg.dev, 0, &gps_rx_buffer[0],rx_length);
            gps_rx_buffer[rx_length] = '\0';
                        rt_kprintf("%s",gps_rx_buffer);
                }               
        }        
}
void gps_app_init(void)
{
                rt_thread_t thread ;  
                        
                rt_err_t result;   

                result = rt_mq_init(&gps_rx_mq, "mqt", &gps_msg_pool[0], 128 - sizeof(void*), sizeof(gps_msg_pool), RT_IPC_FLAG_FIFO);  
                 
                if (result != RT_EOK)   
                {   
                                rt_kprintf("init message queue failed.\n");   
                                return;   
                }   
    thread = rt_thread_create("gps",  
        gps_thread_entry, RT_NULL,  
        4096, 25, 100);  

    if (thread != RT_NULL)  
        rt_thread_startup(thread);         
}

原来在103库函数正常使用的,现在使用L476 HAL库就不行了。

大家一起探讨一下。
(71658803)

出0入0汤圆

 楼主| 发表于 2019-1-5 13:12:54 | 显示全部楼层
jeasey 发表于 2018-10-25 07:52
楼主的问题解决了吗?

现在我也碰到了这个问题。

还没找到原因,只能自己写串口接收处理函数了!
(11744026)

出0入0汤圆

发表于 2020-11-29 00:12:31 | 显示全部楼层
rtt 驱动框架 完全按照 linux 的来套 , 没有针对 mcu 的常用用途   来 确定 各种 api 。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子论坛 ( 公安交互式论坛备案:44190002001997 粤ICP备09047143号 )

GMT+8, 2021-4-13 22:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表