我有个奇怪的问题。一段时间以来,我一直试图取代一个小的协议转换器(基本上是双向串行以太网.我得到的东西有更多的功能。
背景故事
经过大量的逆向工程之后,我发现这个设备是如何工作的,我一直在试图复制它,我成功地将我的电路板连接到了设备上……我试着把原版和主板连接起来,反之亦然,一切都很完美,因为在更高的速度下没有更多的数据包丢失(连接2个原始的就会导致分组丢失)。
然而,当我尝试将我的设备作为主设备连接时,我的另一个设备作为从设备连接。运行完全相同的代码,它工作在2或3个交换,然后它停止.最后,,有时是,过了几分钟,它会再试2到3次。
测试是如何进行的
我有点困惑,但这就是它的工作原理.我的主人正在等待一个套接字连接,然后它们之间的通信就开始了,因为旧的连接就是这样工作的。
我现在已经编写了一个echo客户端来测试连接。基本上现在,我的代码连接到一个服务器(我的主机),它接收一个包,然后它回复它接收到的相同的数据包。当我试着把它连接到我的两个板上时,它们就不工作了。这是更多的相同,2或3交换,然后它停止,但当我连接到原来的设备,它继续运行,没有任何故障。
资料来源
下面是我的TCP主(实际上是服务器)初始化:
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套接字接收的任何信息。然后,它通过可接受总线功能接收数据包,并通过串口发送。
这是我客户(奴隶)的代码:
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);
}
}
其余的代码是相同的。唯一改变的是操作流程。
观测
在通信中没有检测到错误。经过一些测试后,似乎并不是交易所的数量造成了问题。一段时间后就会发生。在我看来,这听起来像是断开连接的问题或超时错误,但是不会发生断开连接,也不会收到更多的数据包。当我停止调试并检查套接字时,没有检测到任何异常。
发布于 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的串行转发器实例,它可能会对您有所帮助(也许您可以使用它来模拟您的一个板?)
https://stackoverflow.com/questions/56762288
复制相似问题