OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6357|回复: 3

类似于TCP三次握手、超时检测、自动重发机制以及主从应答方式的通信任务以及一个任务和多个任务通信时应该如何设计

[复制链接]

19

主题

334

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1108
金钱
1108
注册时间
2018-11-6
在线时间
240 小时
发表于 2020-2-20 14:15:31 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 霸王猫 于 2020-2-20 14:23 编辑

   设备有4个串口
   1、USART1串口会每隔100毫秒接收到【某个外部设备A】发送的一串电压数据。
   2、USART2串口会每隔100毫秒接收到【某个外部设备B】发送的一串电流数据。
   3、USART3串口和移动终端通信(主从通信模式),移动终端为主站,本设备为从站。
        移动终端每隔250毫秒会向本设备发送请求报文,本设备收到移动终端的请求报文后,会将USART1串口采集的电压数据和USART2串口采集的电流数据上传给移动终端。
        注:移动终端和本设备通信特点如下, 如果移动终端如果不给本设备发送请求报文,本设备不会给移动终端发送数据。
   4、USART4串口和服务器通信。
      USART4串口实际上是一个4G转串口模块,该4G转串口模块分为命令模式通信和透传模式通信。当4G转串口模块刚刚上电时为[命令]模式,需要先按照一定的顺序发送握手命令,
握手成功后,即可进入[透传]模式,给服务器传输USART1串口采集的电压数据和USART2串口采集的电流数据。

     (4.1)、命令模式
              命令模式时,给服务器传输握手信号步骤如下:
              第一步:定时200毫秒(时间不需要非常准确)给4G网络发送握手请求报文A。
                    如果收到4G的应答报文,跳转到第二步;否则重复发送请求报文A
              第二步:定时200毫秒(时间不需要非常准确)给4G网络发送握手请求报文B
                    如果收到4G网络的应答报文,跳转到第三步;
                    否则重复发送请求报文B,如果自动重发次数超过3,则跳转到第一步,重新发送握手请求报文A。
              第三步:给4G网络发送握手请求报文C,然后设备开始等待
                    如果在10秒内收到4G网络的应答报文,进入【透传模式】;
                    否则10秒后跳转到第一步,重新发送握手请求报文A。
     (4.2)、透传模式
              第一步:透传模式时定时每隔1秒给服务器传输USART1串口采集的电压数据和USART2串口采集的电流数据。
              第二步:然后等待服务器的应答报文。
              第三步:如果连续1分钟没有收到服务器的应答报文,则该4G转串口模块【断电重启】,然后跳转到命令模式第一步重新握手。

    5、需要检测USART1通信是否出现通信中断(如果连续1秒钟USART1没有收到数据则认为USART1通信中断)
       需要检测USART2通信是否出现通信中断(如果连续1秒钟USART2没有收到数据则认为USART2通信中断)
       需要检测USART3通信是否出现通信中断  


     请问: (1)、这涉及到一个任务和多个任务进行通信,我该如何规划任务?  
              (2)、一个任务和多个任务通信是使用消息队列好呢?还是使用全局变量+互斥信号量锁定方式呢?
              (3)、假设可以使用消息队列进行一个任务和多个任务通信,那么是不是只能编写成下述代码
                          
                        void  USART1_Task ()
                       {
                              while (1)
                              {
                                     等待USART1的信号量;
                                     解析USART1报文,得到电压数据;
                                     发送电压数据到消息队列A;   // ---> 消息队列A用于USART1和服务器通信
                                     发送电压数据到消息队列B;  // ---> 消息队列B用于USART1和移动终端通信

                              }
                         }






最佳答案

查看完整内容[请看2#楼]

经过一段时间的学习,本人亲自在STM32F103VC的主板上测试通过,示意代码如下: 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; //是否收齐U ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

19

主题

334

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1108
金钱
1108
注册时间
2018-11-6
在线时间
240 小时
 楼主| 发表于 2020-2-20 14:15:32 | 显示全部楼层
经过一段时间的学习,本人亲自在STM32F103VC的主板上测试通过,示意代码如下:

     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的通信数据

            switch (step)
            {
                   case 0:
                       延时节拍100毫秒;
                       调用子程序,发送发送请求报文A;
                       限时等待串口中断释放的信号量;
                       解析报文
                        if (报文ok)
                            step = 1;

                       break;

                   case 1:
                        延时节拍100毫秒;

                         count++;
                         if (count > 3)   //自动重发超过3次,跳转到step=0
                        {
                             count =0;
                             step=0;
                         }
                         else
                         {
                              调用子程序,发送发送请求报文B;
                              限时等待串口中断释放的信号量;

                              
解析报文

                             if (报文ok)

                                 step = 2;



                         }
                       break;   
                  
                    case 2:           
                       延时节拍100毫秒;      

                       通过消息队列B,等待USART2的消息队列通信数据,如果收到OK|=0x01;
                       通过消息队列B,等待USART3的消息队列通信数据,如果收到OK|=0x02;
                       if (k==0x03) //收齐USART2和USART3的通信数据
                       {
                          OK=0;
                          调用子程序,发送发送请求报文C;
                          限时等待串口中断释放的信号量;

                          if (等到信号量)

                          {

                              解析报文

                              if (报文ok)

                                  time = 0;  //计时归零

                          }

                          else

                          {

                                 time++;

                                 if (time >= 60)

                                 {

                                       time = 0x00;

                                       step = 0;

                                 }

                          }



                       }

              }
回复

使用道具 举报

19

主题

334

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1108
金钱
1108
注册时间
2018-11-6
在线时间
240 小时
 楼主| 发表于 2020-5-5 21:50:46 | 显示全部楼层
经过一段时间的学习,本人亲自在STM32F103VC的主板上测试通过,示意代码如下:

     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的通信数据

            switch (step)
            {
                   case 0:
                       延时节拍100毫秒;
                       调用子程序,发送发送请求报文A;
                       限时等待串口中断释放的信号量;
                       解析报文
                        if (报文ok)
                            step = 1;

                       break;

                   case 1:
                        延时节拍100毫秒;

                         count++;
                         if (count > 3)   //自动重发超过3次,跳转到step=0
                        {
                             count =0;
                             step=0;
                         }
                         else
                         {
                              调用子程序,发送发送请求报文B;
                              限时等待串口中断释放的信号量;

                              
解析报文

                             if (报文ok)

                                 step = 2;



                         }
                       break;   
                  
                    case 2:           
                       延时节拍100毫秒;      

                       通过消息队列B,等待USART2的消息队列通信数据,如果收到OK|=0x01;
                       通过消息队列B,等待USART3的消息队列通信数据,如果收到OK|=0x02;
                       if (k==0x03) //收齐USART2和USART3的通信数据
                       {
                          OK=0;
                          调用子程序,发送发送请求报文C;
                          限时等待串口中断释放的信号量;

                          if (等到信号量)

                          {

                              解析报文

                              if (报文ok)

                                  time = 0;  //计时归零

                          }

                          else

                          {

                                 time++;

                                 if (time >= 60)

                                 {

                                       time = 0x00;

                                       step = 0;

                                 }

                          }



                       }

              }
回复

使用道具 举报

19

主题

334

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1108
金钱
1108
注册时间
2018-11-6
在线时间
240 小时
 楼主| 发表于 2020-5-5 21:51:52 | 显示全部楼层
经过一段时间的学习,本人亲自在STM32F103VC的主板上测试通过,示意代码如下:

     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的通信数据

            switch (step)
            {
                   case 0:
                       延时节拍100毫秒;
                       调用子程序,发送发送请求报文A;
                       限时等待串口中断释放的信号量;
                       解析报文
                        if (报文ok)
                            step = 1;

                       break;

                   case 1:
                        延时节拍100毫秒;

                         count++;
                         if (count > 3)   //自动重发超过3次,跳转到step=0
                        {
                             count =0;
                             step=0;
                         }
                         else
                         {
                              调用子程序,发送发送请求报文B;
                              限时等待串口中断释放的信号量;

                              
解析报文

                             if (报文ok)

                                 step = 2;



                         }
                       break;   
                  
                    case 2:           
                       延时节拍100毫秒;      

                       通过消息队列B,等待USART2的消息队列通信数据,如果收到OK|=0x01;
                       通过消息队列B,等待USART3的消息队列通信数据,如果收到OK|=0x02;
                       if (k==0x03) //收齐USART2和USART3的通信数据
                       {
                          OK=0;
                          调用子程序,发送发送请求报文C;
                          限时等待串口中断释放的信号量;

                          if (等到信号量)

                          {

                              解析报文

                              if (报文ok)

                                  time = 0;  //计时归零

                          }

                          else

                          {

                                 time++;

                                 if (time >= 60)

                                 {

                                       time = 0x00;

                                       step = 0;

                                 }

                          }



                       }

              }
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 18:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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