硬汉嵌入式论坛

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

[有问必答] 求助 : 关于MODBUS例程 从机部分的一个疑问

[复制链接]

1

主题

8

回帖

11

积分

新手上路

积分
11
发表于 2020-2-27 10:12:58 | 显示全部楼层 |阅读模式
void MODS_Poll(void)
{
uint16_t addr;
uint16_t crc1;
/* 超过3.5个字符时间后执行MODH_RxTimeOut()函数。全局变量 g_rtu_timeout = 1; 通知主程序开始解码 */
if (g_mods_timeout == 0)
{
  return;        /* 没有超时,继续接收。不要清零 g_tModS.RxCount */
}

g_mods_timeout = 0;       /* 清标志 */
if (g_tModS.RxCount < 4)    /* 接收到的数据小于4个字节就认为错误 */
{
  goto err_ret;
}
/* 计算CRC校验和 */
crc1 = CRC16_Modbus(g_tModS.RxBuf, g_tModS.RxCount);
if (crc1 != 0)
{
  goto err_ret;
}
/* 站地址 (1字节) */
addr = g_tModS.RxBuf[0];    /* 第1字节 站号 */
if (addr != SADDR485)      /* 判断主机发送的命令地址是否符合 */
{
  goto err_ret;
}
/* 分析应用层协议 */
MODS_AnalyzeApp();      

err_ret:
#if 1          /* 此部分为了串口打印结果,实际运用中可不要 */
g_tPrint.Rxlen = g_tModS.RxCount;
memcpy(g_tPrint.RxBuf, g_tModS.RxBuf, g_tModS.RxCount);
#endif

g_tModS.RxCount = 0;     /* 必须清零计数器,方便下次帧同步 */
}
如果从串口FIFO传过来的是一桢完整数据,则在Idle里面调用MODS_Poll()时 ,程序不会进入err_ret: 状态,那么
g_tModS.RxCount没有在别的地方被清零,此时怎么保证下一桢数据能被完整接收和解析;整个工程没有找到别的地方有对
g_tModS.RxCount = 0;的处理。 @


回复

使用道具 举报

1

主题

8

回帖

11

积分

新手上路

积分
11
 楼主| 发表于 2020-2-27 10:14:16 | 显示全部楼层
@eric2013   求助还是我理解错了。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2020-2-27 10:40:54 | 显示全部楼层
临渊丶 发表于 2020-2-27 10:14
@eric2013   求助还是我理解错了。

如果没有出错,这个函数会一直执行到g_tModS.RxCount = 0;  
回复

使用道具 举报

1

主题

8

回帖

11

积分

新手上路

积分
11
 楼主| 发表于 2020-2-27 13:34:30 | 显示全部楼层
err_ret:
#if 1          /* 此部分为了串口打印结果,实际运用中可不要 */
g_tPrint.Rxlen = g_tModS.RxCount;
memcpy(g_tPrint.RxBuf, g_tModS.RxBuf, g_tModS.RxCount);
#endif

g_tModS.RxCount = 0;     /* 必须清零计数器,方便下次帧同步 */

也就是说如果触发goto err_ret:状态,只执行#if 1          /* 此部分为了串口打印结果,实际运用中可不要 */
g_tPrint.Rxlen = g_tModS.RxCount;
memcpy(g_tPrint.RxBuf, g_tModS.RxBuf, g_tModS.RxCount);
#endif,而无论是否触发err_ret g_tModS.RxCount = 0; 都会执行。该语句不属于err_ret:分支。?
回复

使用道具 举报

1

主题

8

回帖

11

积分

新手上路

积分
11
 楼主| 发表于 2020-2-27 13:47:39 | 显示全部楼层
eric2013 发表于 2020-2-27 10:40
如果没有出错,这个函数会一直执行到g_tModS.RxCount = 0;

正常的数据帧,是运行到MODS_AnalyzeApp();  就跳转了阿,不会执行err_ret Label下面的内容把。为什么也会执行   这个函数会一直执行到g_tModS.RxCount = 0;  。这里还是想不明白。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2020-2-27 14:24:52 | 显示全部楼层
临渊丶 发表于 2020-2-27 13:47
正常的数据帧,是运行到MODS_AnalyzeApp();  就跳转了阿,不会执行err_ret Label下面的内容把。为什么也 ...

这个是个goto的用法,不管是goto过来的,还是程序正常执行过来的,都会执行完毕。

你可以写个简单的代码,熟悉下goto流程。
回复

使用道具 举报

1

主题

8

回帖

11

积分

新手上路

积分
11
 楼主| 发表于 2020-2-27 16:23:39 | 显示全部楼层
eric2013 发表于 2020-2-27 14:24
这个是个goto的用法,不管是goto过来的,还是程序正常执行过来的,都会执行完毕。

你可以写个简单的代 ...

嗯嗯,已测试OK  谢谢您。

#include <stdio.h>
int  g_MenuJumpStack[8][2]  =   {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
int main(void)
{
        int i,j;
        for(i = 0;i < 8;i++)
        {
            for(j = 0;j < 2;j++)
            {
                      printf("%d\n",g_MenuJumpStack[j]);  
            }
            if(i>3){goto Label;}
        }

        
            printf("%d\n",i);

Label:
                printf("enter err!\n");
#if 1        /* 此部分为了串口打印结果,实际运用中可不要 */
            printf("feedback\n");
#endif
                printf("direct return\n");
}
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-17 01:23 , Processed in 0.045828 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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