ba_wang_mao 发表于 2020-1-3 13:56:58

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

我的设备的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




ba_wang_mao 发表于 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;
            }      
      }
}

ba_wang_mao 发表于 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;
            }      
      }
}

eric2013 发表于 2020-1-3 14:18:30

我认为可以的,基本就是这种套路

ba_wang_mao 发表于 2020-1-3 14:39:59

还有一个问题:

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

eric2013 发表于 2020-1-3 18:03:45

ba_wang_mao 发表于 2020-1-3 14:39
还有一个问题:

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

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

Nesayx 发表于 2020-1-4 10:08:04

Ymodem协议上改改应该就可以了吧

ba_wang_mao 发表于 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;
            }      
      }
}

ba_wang_mao 发表于 2020-1-6 14:19:53

疑问:

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

eric2013 发表于 2020-1-9 12:28:51

ba_wang_mao 发表于 2020-1-6 14:19
疑问:

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

你楼主位不写的要等待应答的,那就不会有溢出问题。
页: [1]
查看完整版本: 类似于TCP三次握手、超时检测以及自动重发机制的通信任务该如何设计