首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >lwip板无法维护与另一个lwip板的连接

lwip板无法维护与另一个lwip板的连接
EN

Stack Overflow用户
提问于 2019-06-25 21:31:36
回答 1查看 648关注 0票数 0

我有个奇怪的问题。一段时间以来,我一直试图取代一个小的协议转换器(基本上是双向串行以太网.我得到的东西有更多的功能。

背景故事

经过大量的逆向工程之后,我发现这个设备是如何工作的,我一直在试图复制它,我成功地将我的电路板连接到了设备上……我试着把原版和主板连接起来,反之亦然,一切都很完美,因为在更高的速度下没有更多的数据包丢失(连接2个原始的就会导致分组丢失)。

然而,当我尝试将我的设备作为主设备连接时,我的另一个设备作为从设备连接。运行完全相同的代码,它工作在2或3个交换,然后它停止.最后,,有时是,过了几分钟,它会再试2到3次。

测试是如何进行的

  • 我连接了modbus主程序和从机(modbustools,两个不同的实例)。主机为串行RTU modbus,从机为串行RTU modbus;
  • 我将其中一个设备配置为主设备,并将其连接到串口,使其接收串行modbus,并将协议发送到与其连接的设备;
  • 我配置我的从机,使它通过串口连接到从modbus。基本上,它通过创建一个套接字并连接到主IP来工作,然后通过以太网等待主传输,通过串行发送到从modbus (modbustools),接收一个响应,发送它的主机,然后将它发送给modbus主(modbustools);

我有点困惑,但这就是它的工作原理.我的主人正在等待一个套接字连接,然后它们之间的通信就开始了,因为旧的连接就是这样工作的。

我现在已经编写了一个echo客户端来测试连接。基本上现在,我的代码连接到一个服务器(我的主机),它接收一个包,然后它回复它接收到的相同的数据包。当我试着把它连接到我的两个板上时,它们就不工作了。这是更多的相同,2或3交换,然后它停止,但当我连接到原来的设备,它继续运行,没有任何故障。

资料来源

下面是我的TCP主(实际上是服务器)初始化:

代码语言:javascript
运行
复制
void initClient() {
            if(tcp_modbus == NULL) {
                tcp_modbus = tcp_new();
                previousPort = port;
                tcp_bind(tcp_modbus, IP_ADDR_ANY, port);
                tcp_sent(tcp_modbus, sent);
                tcp_poll(tcp_modbus, poll, 2);
                tcp_setprio(tcp_modbus, 128);
                tcp_err(tcp_modbus, error);
                tcp_modbus = tcp_listen(tcp_modbus);
                tcp_modbus->so_options |= SOF_KEEPALIVE; // enable keep-alive
                tcp_modbus->keep_intvl = 1000; // sends keep-alive every second
                tcp_accept(tcp_modbus, acceptmodbus);
                isListening = true;
            }
}
static err_t acceptmodbus(void *arg, struct tcp_pcb *pcb, err_t err) {
    tcp_arg(pcb, pcb);
    /* Set up the various callback functions */
    tcp_recv(pcb, modbusrcv);
    tcp_err(pcb, error);

    tcp_accepted(pcb);

    gb_ClientHasConnected = true;
}

//receives the packet, puts it in an array "ptransparentmessage->data"
//states which PCB to use in order to reply and the length that was received
static err_t modbusrcv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) {
    if(p == NULL) {
        return ERR_OK;
    } else if(err != ERR_OK) {
        return err;
    }

    tcp_recved(pcb, p->len);

    memcpy(ptransparent.data, p->payload,p->len);
    ptransparent->pcb = pcb;
    ptransparent->len = p->len;
}

串行接收基本上如下:检测接收到的一个字节,启动超时,当超时结束时,发送通过已经连接到服务器的TCP套接字接收的任何信息。然后,它通过可接受总线功能接收数据包,并通过串口发送。

这是我客户(奴隶)的代码:

代码语言:javascript
运行
复制
void init_slave() {
    if(tcp_client == NULL) {
        tcp_client = tcp_new();

        tcp_bind(tcp_client, IP_ADDR_ANY, 0);
        tcp_arg(tcp_client, NULL);
        tcp_recv(tcp_client, modbusrcv);
        tcp_sent(tcp_client, sent);
        tcp_client->so_options |= SOF_KEEPALIVE; // enable keep-alive
        tcp_client->keep_intvl = 100; // sends keep-alive every 100 mili seconds
        tcp_err(tcp_client, error);


        err_t ret = tcp_connect(tcp_client, &addr, portCnt, connected);
    }
}

其余的代码是相同的。唯一改变的是操作流程。

  1. 连接到服务器
  2. 等待数据包
  3. 通过串行发送
  4. 等待响应超时(与服务器相同的超时时间,它只是以一种不同的方式开始计数.服务器在接收到一个字节后启动,客户端在通过串口发送东西后启动)
  5. 获取响应并将其发送到服务器

观测

在通信中没有检测到错误。经过一些测试后,似乎并不是交易所的数量造成了问题。一段时间后就会发生。在我看来,这听起来像是断开连接的问题或超时错误,但是不会发生断开连接,也不会收到更多的数据包。当我停止调试并检查套接字时,没有检测到任何异常。

EN

回答 1

Stack Overflow用户

发布于 2019-06-26 06:54:55

如果我正确地理解了您的问题,那么您有一台具有两个串行端口的计算机,每个端口运行一个Modbus客户端和一个服务器实例。然后,从这两个端口中的每一个连接到STM32板,在它们的串行端口上接收数据,然后在以太网网络上转发给TCP,将它们连接到彼此。

说起来不容易,但根据您所描述的症状,看起来您确实遇到了一个或几个超时问题,很可能是在序列中。我认为,在不测试代码的情况下,帮助您确定代码的确切错误是不容易的,如果您不能显示完整的功能片段,则肯定不会。

但是,您可以改进的是您在端侧调试的方式。你可以尝试用一些能给你更多细节的东西来代替调制解调器。

获得额外调试信息的最简单的解决方案是使用https://github.com/riptideio/pymodbus,您只需要安装带有pip的库,并使用示例提供的客户机和服务器。您所需要的唯一修改是将它们更改为串行接口注释和取消注释几行。这将为您提供非常有用的调试细节。

如果您的计算机上有一个C开发环境,最好选择https://github.com/stephane/libmodbus。这个库拥有一组非常棒的单元测试。同样,您只需编辑代码来设置串行端口的名称,并运行服务器和客户端。

最后,我不知道这在多大程度上对您有用,但是您可能想看看SerialPCAP。使用这个工具,您可以点击RS-485总线,查看运行在它上的所有查询和响应。我想你有RS-232,它是点对点的,不会与总线上的三个设备一起工作。如果是这样,您可以尝试端口转发

编辑:更仔细地阅读你的问题我觉得这个句子特别麻烦:

...detect接收到一个字节,启动超时,当超时结束时,发送通过已连接到服务器的TCP套接字接收的任何内容.

你为什么要引入这种人为的拖延呢?在Modbus中,您有非常好定义的包,您可以通过最小3.5帧间隔来识别这些包,这就是您所说的超时的意思吗?

不相关,但我还记得有一个带有pymodbus的串行转发器实例,它可能会对您有所帮助(也许您可以使用它来模拟您的一个板?)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56762288

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档