硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2153|回复: 9
收起左侧

[FreeRTOS] 类似于TCP三次握手、超时检测以及自动重发机制的通信任务该如何设计

[复制链接]

13

主题

56

回帖

95

积分

初级会员

积分
95
发表于 2020-1-3 13:56:58 | 显示全部楼层 |阅读模式
我的设备的USART1和一个小模块进行通信,但是通信之前需要握手,过程如下:

       步骤1:
                 发送请求报文A,然后等待应答;
                 (1)、如果收到应答,跳转到步骤2.
                 (2)、如果没有收到应答,定时重发发送请求报文A。
      步骤2:
                 发送请求报文B,然后等待应答;
                 (1)、如果收到应答,跳转到步骤3.
                 (2)、如果超时未等到应答报文,重发发送请求报文B,如果连续3次超时,则跳转到步骤1。
      步骤3:
                 (1)、等待接收USART2的通信数据。
                 (2)、等待接收USART3的通信数据。
                 (3)、IF (先后收到USART2的通信数据和USART3的通信数据)
                       {
                             发送请求报文C
                         }

                 (4)、等待应答报文。
                 (5)、如果收到应答,继续步骤3等待USART2和USART3的通信数据,然后发送请求报文C。
                   (6)、如果连续1分钟没有收到应答报文,则跳转到步骤1




回复

使用道具 举报

13

主题

56

回帖

95

积分

初级会员

积分
95
 楼主| 发表于 2020-1-3 13:57:24 | 显示全部楼层
我的任务设计如下,是否可行,请指教! 如果有缺陷,请指出好的方法!            


void   my_task(void)
     {
            static int step = 0;   // 0=发送请求报文A,1=发送请求报文B,2=发送请求报文C
            static int count = 0;  //计数器,自动重发超过3次,跳转到step=0,转去发送请求报文A
            static int time = 0;   //计时,连续1分钟计时
            static int OK=0;       //是否收齐USART2和USART3的通信数据


//-------------------------定时发送USART1的请求报文部分
            switch (step)
            {
                   case 0:
                       调用子程序,发送发送请求报文A;
                       break;

                   case 1:
                         count++;
                         if (count > 3)   //自动重发超过3次,跳转到step=0
                        {
                             count =0;
                             step=0;
                         }
                         else
                         {
                              调用子程序,发送发送请求报文B;
                         }
                       break;   
                  
                    case 2:
                  
                       等待USART2的消息队列通信数据,如果收到OK|=0x01;
                       等待USART3的消息队列通信数据,如果收到OK|=0x02;
                       if (k==0x03) //收齐USART2和USART3的通信数据
                       {
                          OK=0;
                          调用子程序,发送发送请求报文C;
                       }

              }            


   
//-------------------------等待USART1的应答报文部分

             等待usart1的消息队列(最大等待时间=500ms)
             switch (step)
             {
                   case 0:
                        if (消息队列收到消息)
                        {
                           解析报文
                           if (报文ok)
                             step = 1;
                        }
                        break;
                   case 1:
                        if (消息队列收到消息)
                        {
                           解析报文
                           if (报文ok)
                           {
                               count =0;//自动重发次数清零
                               step = 2;
                            }
                        else
                        {
                            count++:   //自动重发次数+1
                        }
                        break;   
                   case 2:
                        if (消息队列收到消息)
                        {
                            解析报文
                            time = 0x00;//连续1分钟计时单元清零
                        }
                        else
                        {
                           time++;//连续1分钟计时单元+1
                           if (time >= 20) //如果1分钟到时
                           {
                               OK=0;
                               count=0;
                               time=0;
                           }
                         }
                         break;
            }      
      }
}
回复

使用道具 举报

13

主题

56

回帖

95

积分

初级会员

积分
95
 楼主| 发表于 2020-1-3 13:58:28 | 显示全部楼层
我的任务设计如下,是否可行,请指教!
       如果有缺陷,请指出好的方法!            


      void   my_task(void)
     {
            static int step = 0;   // 0=发送请求报文A,1=发送请求报文B,2=发送请求报文C
            static int count = 0;  //计数器,自动重发超过3次,跳转到step=0,转去发送请求报文A
            static int time = 0;   //计时,连续1分钟计时
            static int OK=0;       //是否收齐USART2和USART3的通信数据


//-------------------------定时发送USART1的请求报文部分
            switch (step)
            {
                   case 0:
                       调用子程序,发送发送请求报文A;
                       break;

                   case 1:
                         count++;
                         if (count > 3)   //自动重发超过3次,跳转到step=0
                        {
                             count =0;
                             step=0;
                         }
                         else
                         {
                              调用子程序,发送发送请求报文B;
                         }
                       break;   
                  
                    case 2:
                  
                       等待USART2的消息队列通信数据,如果收到OK|=0x01;
                       等待USART3的消息队列通信数据,如果收到OK|=0x02;
                       if (k==0x03) //收齐USART2和USART3的通信数据
                       {
                          OK=0;
                          调用子程序,发送发送请求报文C;
                       }

              }            


   
//-------------------------等待USART1的应答报文部分

             等待usart1的消息队列(最大等待时间=500ms)
             switch (step)
             {
                   case 0:
                        if (消息队列收到消息)
                        {
                           解析报文
                           if (报文ok)
                             step = 1;
                        }
                        break;
                   case 1:
                        if (消息队列收到消息)
                        {
                           解析报文
                           if (报文ok)
                           {
                               count =0;//自动重发次数清零
                               step = 2;
                            }
                        else
                        {
                            count++:   //自动重发次数+1
                        }
                        break;   
                   case 2:
                        if (消息队列收到消息)
                        {
                            解析报文
                            time = 0x00;//连续1分钟计时单元清零
                        }
                        else
                        {
                           time++;//连续1分钟计时单元+1
                           if (time >= 20) //如果1分钟到时
                           {
                               OK=0;
                               count=0;
                               time=0;
                           }
                         }
                         break;
            }      
      }
}
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106739
QQ
发表于 2020-1-3 14:18:30 | 显示全部楼层
我认为可以的,基本就是这种套路
回复

使用道具 举报

13

主题

56

回帖

95

积分

初级会员

积分
95
 楼主| 发表于 2020-1-3 14:39:59 | 显示全部楼层
还有一个问题:

   在步骤1、步骤2 时 也会先后收到USART2的通信数据和USART3的通信数据, 该怎么处理呀!
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106739
QQ
发表于 2020-1-3 18:03:45 | 显示全部楼层
ba_wang_mao 发表于 2020-1-3 14:39
还有一个问题:

   在步骤1、步骤2 时 也会先后收到USART2的通信数据和USART3的通信数据, 该怎么处理呀 ...

存到消息队列里面吧,是否满足
回复

使用道具 举报

3

主题

82

回帖

91

积分

初级会员

积分
91
发表于 2020-1-4 10:08:04 | 显示全部楼层
Ymodem协议上改改应该就可以了吧
回复

使用道具 举报

13

主题

56

回帖

95

积分

初级会员

积分
95
 楼主| 发表于 2020-1-6 13:42:46 | 显示全部楼层
更新如下:

事先创建2个消息队列,以下简称消息队列A和消息队列B
       消息队列A用来接收应答报文
       消息队列B用来接收USART2和USART3的通信数据


      void   my_task(void)
     {
            static int step = 0;   // 0=发送请求报文A,1=发送请求报文B,2=发送请求报文C
            static int count = 0;  //计数器,自动重发超过3次,跳转到step=0,转去发送请求报文A
            static int time = 0;   //计时,连续1分钟计时
            static int OK=0;       //是否收齐USART2和USART3的通信数据


//-------------------------定时发送USART1的请求报文部分
            switch (step)
            {
                   case 0:
                       调用子程序,发送发送请求报文A;
                       break;

                   case 1:
                         count++;
                         if (count > 3)   //自动重发超过3次,跳转到step=0
                        {
                             count =0;
                             step=0;
                         }
                         else
                         {
                              调用子程序,发送发送请求报文B;
                         }
                       break;   
                  
                    case 2:
                  
                       通过消息队列B,等待USART2的消息队列通信数据,如果收到OK|=0x01;
                       通过消息队列B,等待USART3的消息队列通信数据,如果收到OK|=0x02;
                       if (k==0x03) //收齐USART2和USART3的通信数据
                       {
                          OK=0;
                          调用子程序,发送发送请求报文C;
                       }

              }            


   
//-------------------------等待USART1的应答报文部分

             通过消息队列A,等待usart1的消息队列(最大等待时间=500ms)
             switch (step)
             {
                   case 0:
                        if (消息队列收到消息)
                        {
                           解析报文
                           if (报文ok)
                             step = 1;
                        }
                        break;
                   case 1:
                        if (消息队列收到消息)
                        {
                           解析报文
                           if (报文ok)
                           {
                               count =0;//自动重发次数清零
                               step = 2;
                            }
                        else
                        {
                            count++:   //自动重发次数+1
                        }
                        break;   
                   case 2:
                        if (消息队列收到消息)
                        {
                            解析报文
                            time = 0x00;//连续1分钟计时单元清零
                        }
                        else
                        {
                           time++;//连续1分钟计时单元+1
                           if (time >= 20) //如果1分钟到时
                           {
                               OK=0;
                               count=0;
                               time=0;
                           }
                         }
                         break;
            }      
      }
}
回复

使用道具 举报

13

主题

56

回帖

95

积分

初级会员

积分
95
 楼主| 发表于 2020-1-6 14:19:53 | 显示全部楼层
疑问:

       1、在上线握手过程中,USART2和USART3的通信数据导致消息队列B满该怎么办呢?(注:USART2和USART3的通信数据本机无法控制)。
       2、对系统有影响吗?
       3、该如何消除?
       4、是增加限制条件吗?(即:握手不成功时,USART2和USART3的通信任务不发送消息)
               这种增加限制条件,即条件不满足时不发送消息队列数据,是否太牵强了!
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106739
QQ
发表于 2020-1-9 12:28:51 | 显示全部楼层
ba_wang_mao 发表于 2020-1-6 14:19
疑问:

       1、在上线握手过程中,USART2和USART3的通信数据导致消息队列B满该怎么办呢?(注:USART ...

你楼主位不写的要等待应答的,那就不会有溢出问题。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-3 12:13 , Processed in 0.218107 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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