查看: 9444|回复: 16

[MQX] MQX的中断串口方式丢数据?

[复制链接]

该用户从未签到

3

主题

99

帖子

0

中级会员

Rank: 3Rank: 3

积分
322
最后登录
1970-1-1
发表于 2012-2-21 13:21:27 | 显示全部楼层 |阅读模式
原来的帖子丢了。再新开一个相同的帖子请教吧

我用MQX自带的中断串口驱动(itta)和函数实现一个Modbus数据接收过程:当监视到第一个字节出现后循环接收,如果等待3.5毫秒再等不来下一个数据,就认为已接受到完整的一桢数据。
 
  while(fstatus(Handle_Serial_A)==0)// 等第一个字节
  {
   RTCS_time_delay(5);   
   Timeout_Count++;
     
   if(Timeout_Count>200)//等1秒则设超时
   {
    Flag_Timeout=1;
    break;
   }
     
  }
  
  
  if(Flag_Timeout==0)//无超时
  {
  
   _task_stop_preemption();//禁止任务抢占
  
  
   _time_get(&time);
   
   End_Time=time.SECONDS*1000 + time.MILLISECONDS;;
   Start_Time=End_Time;
   
   
   
   while((End_Time-Start_Time)MB_Gap_Count_Max) MB_Gap_Count_Max=(End_Time-Start_Time);
    
    
     Received_Count=_io_read(Handle_Serial_A, &Read_Buffer[Received_Total], MAX_PDU_LENGTH-Received_Total);
     Received_Total += Received_Count;
     Start_Time=End_Time;
    }
    
    _time_get(&time);
    End_Time=time.SECONDS*1000 + time.MILLISECONDS;
    
    if(Received_Total>=MAX_PDU_LENGTH) break;
   }
   
      _task_start_preemption();//允许任务抢占
   。。。。。。
  }
现在发现如果等待时间设小了(现在是15毫秒),程序就过早判断数据接收完成而丢失数据。如果系统同时再运行其他任务15毫秒还丢数据。
不理解是MQX的中断式串口低层驱动丢数据还是_task_stop_preemption()不好使,照理禁止别的任务抢占接收程序就不应被打断。
而MQX的中断时间是默认的5毫秒,如果因此处理不了3.5毫秒的事件可以理解,但3x5毫秒还丢数据就奇怪了。
大家帮忙分析一下。谢谢
我知道答案 目前已有16人回答
回复

使用道具 举报

  • TA的每日心情
    难过
    2021-12-15 16:01
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    305

    主题

    4701

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    377
    最后登录
    2023-8-16
    发表于 2012-2-22 14:23:08 | 显示全部楼层

    RE:MQX的中断串口方式丢数据?

    while(fstatus(Handle_Serial_A)==0)// 等第一个字节
      {
       RTCS_time_delay(5);   
       Timeout_Count++;
         
       if(Timeout_Count>200)//等1秒则设超时
       {
        Flag_Timeout=1;
        break;
       }
         
      }
    上面的代码可以看出,根本就走不出while循环,我认为你这里应该改成下面的代码:
    char recsta=1;
    while(recsta)// 等第一个字节
      {
       if(fstatus(Handle_Serial_A)==0) recsta=1;
       RTCS_time_delay(5);   
       Timeout_Count++;
         
       if(Timeout_Count>200)//等1秒则设超时
       {
        Flag_Timeout=1;
        recsta=0;
       }     
      }
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    3

    主题

    99

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    322
    最后登录
    1970-1-1
     楼主| 发表于 2012-2-23 09:24:16 | 显示全部楼层

    回复:MQX的中断串口方式丢数据?

    谢谢安。
     
    while() 这段好象没问题。MQX的串口中断驱动在后台工作,当串口收到1个以上字节时,fstatus(Handle_Serial_A) 就返回非零数了。
    这段程序已经运行好几个月了,还没看到死循环的时候。倒是应接收到210字节,有时同时运行几个任务,会只收到180--206字节的情况。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    难过
    2021-12-15 16:01
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    305

    主题

    4701

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    377
    最后登录
    2023-8-16
    发表于 2012-2-23 15:41:50 | 显示全部楼层

    RE:MQX的中断串口方式丢数据?

    End_Time=time.SECONDS*1000 + time.MILLISECONDS;;
       Start_Time=End_Time;
    这里,Start_Time=End_Time,这句应该屏蔽掉。对于丢失数据的情况,如果单个任务不丢失,而多个任务会丢失。这个时候需要看看各个任务之间是否有缓冲区的共享矛盾?
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    3

    主题

    99

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    322
    最后登录
    1970-1-1
     楼主| 发表于 2012-2-23 22:42:53 | 显示全部楼层

    RE:MQX的中断串口方式丢数据?

    上边那段程序是监视从上次收到数据到当前时间的定时器,每次收到一段数据时要用Start_Time=End_Time把定时器清零。
    怪我没解释清楚,Modbus协议要求监视字节之间的接收时间,如果从上次收到数据时间计时,如果在3.5mS内没收到新的数据就认为通讯结束。所以当Modbus客户端(我的系统)向服务器发出请求后,要等待一段时间允许服务器准备并发回响应数据(我允许服务器的响应时间是1秒),但当服务器开始发响应数据时,数据必须是连续的,字节间不能有超过3.5毫秒的时间间隔。
    原来没有加_task_stop_preemption() 禁止任务抢占时,通讯往往不成功。因为当计时过程被别的高级别任务抢占后返回时,程序往往早就超时。
    从理论上说,应该也没有缓冲区共享矛盾的问题。我在整个串口程序加了Mutex,而且串口本身的缓冲区是由MQX驱动维护的。为了调试我另外开启的是个费时但不操作串口的任务。
    另外想请教一下,如何判断各个任务是否分到足够的缓冲区?我现在调试时调用_klog_get_task_stack_usage(),可看到每个任务最多使用的内存,但不知还有没有更好的办法。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    难过
    2021-12-15 16:01
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    305

    主题

    4701

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    377
    最后登录
    2023-8-16
    发表于 2012-2-25 10:02:58 | 显示全部楼层

    RE:MQX的中断串口方式丢数据?

    如果用MQX的没有问题,任务之间的切换,可以不用考虑任务抢占,只要程序处理得到,不用禁止任务抢占。你需要的是,在while这种循环下面,加一个延时处理,这个延时就是用来任务切换的。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    3

    主题

    99

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    322
    最后登录
    1970-1-1
     楼主| 发表于 2012-2-26 12:38:56 | 显示全部楼层

    RE:MQX的中断串口方式丢数据?

    while加延时处理只能让别的任务切换走,但不能保证何时切回来,除非把该任务优先级定的最高。如果不能保证任务切换走后能在需要的时间内返回控制权,使该任务的计时就不准而误判断,除非自己重写中断程序。而该任务仅在这段程序对时间要求较严,感觉MQX的禁止任务抢占就可以解决的问题,就不想提高这个任务的优先级。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    难过
    2021-12-15 16:01
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    305

    主题

    4701

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    377
    最后登录
    2023-8-16
    发表于 2012-2-27 10:53:39 | 显示全部楼层

    RE:MQX的中断串口方式丢数据?

    在抢占的同时,也要考虑到其他的任务是不是在使用串口。如果在使用,这个时候还是需要处理一下。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    3

    主题

    99

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    322
    最后登录
    1970-1-1
     楼主| 发表于 2012-2-28 01:08:49 | 显示全部楼层

    RE:MQX的中断串口方式丢数据?

    安考虑得很周全。

    因为系统要支持多至4个客户的同时连接,而这些客户也有可能同时申请与串口通讯,所以在进串口操作程序前我已作了处理。我用了MQX本身提供的互斥机制。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    难过
    2021-12-15 16:01
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    305

    主题

    4701

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    377
    最后登录
    2023-8-16
    发表于 2012-2-28 09:20:34 | 显示全部楼层

    RE:MQX的中断串口方式丢数据?

    如果按你说的这样,出现数据丢失,问题可能出现在程序处理上。建议只开启一个任务,不做时间判断,然后用串口接收数据,看看,数据是否存在丢失的问题。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-28 01:48 , Processed in 0.102115 second(s), 29 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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