五、调试过程

找到一个PLC(没有的话下载的codesys也可以,具体的下载及安装方案见第二章内的RT-THREAD的示例代码说明文档),将RT-THREAD提供的eds文件导入,并添加到Eip网口的主站中,连接PLC与板子,若板子demo能正常跑通,PLC是能连接到板子的,否则就是有问题。

这里需要注意,sampleapplication.c需要移植RT-THREAD版本的代码,因为TR-THREAD修改了源码的eds文件。

首先打开opener的log功能,否则根本不知道哪里出的问题,打开的方式也很简单粗暴,在trace.h中:

//#define OPENER_TRACE_ERR(...)                       
//#define OPENER_TRACE_WARN(...)                
//#define OPENER_TRACE_STATE(...)               
//#define OPENER_TRACE_INFO(...)                

#define OPENER_TRACE_ERR                 printf
#define OPENER_TRACE_WARN                printf
#define OPENER_TRACE_STATE               printf
#define OPENER_TRACE_INFO                printf

5.1、SOCKET打开失败

编译,运行,输出的log报错:

networkhandler tcp_listener: error setting socket option SO_REUSEADDR

需要打开lwip对应的功能:

5.2、ForwardOpen失败问题

紧接着出现了forwardopen失败的情况。换上了EtherKit板子,forwardopen成功。

抓取两者的forwardopen的Response报文,确实是移植的板子报了失败

从forwardopen报文能看到,O->T为7Byte,T->O为3Byte。而eds中配置的分明两者都是1Byte。

问题出在这段代码:

int data_size = ConnectionObjectGetOToTConnectionSize(io_connection_object);
    int diff_size = 0;

    /* an assembly object should always have a data attribute. */
    CipAttributeStruct *attribute = GetCipAttribute(instance,
                                                    kAssemblyObjectInstanceAttributeIdData);
    OPENER_ASSERT(attribute != NULL);
    bool is_heartbeat = ( ( (CipByteArray *) attribute->data )->length == 0 );
    if( kConnectionObjectTransportClassTriggerTransportClass1 ==
        ConnectionObjectGetTransportClassTriggerTransportClass(
          io_connection_object) )
    {
      /* class 1 connection */
      data_size -= 2; /* remove 16-bit sequence count length */
      diff_size += 2;
    }

    if( s_consume_run_idle && (data_size > 0) && (!is_heartbeat) ) {
      /* we only have an run idle header if it is not an heartbeat connection */
      data_size -= 4; /* remove the 4 bytes needed for run/idle header */
      diff_size += 4;
    }

    if( ( (CipByteArray *) attribute->data )->length != data_size ) {
      /*wrong connection size */
      connection_object->correct_originator_to_target_size =
        ( (CipByteArray *) attribute->data )->length + diff_size;
      return kConnectionManagerExtendedStatusCodeErrorInvalidOToTConnectionSize;
    }

于是通过单步调试,对比两者的差异看到,最开始收到的确实是7个字节

出问题的:7-2=5

正常运行的7-2-4=1

出现问题是因为s_consume_run_idle=0,导致-4的逻辑进不去,进一步排查发现:

/**** Local variables, set by API, with build-time defaults ****/
#ifdef OPENER_CONSUMED_DATA_HAS_RUN_IDLE_HEADER
static EipUint8 s_consume_run_idle = 1;
#else
static EipUint8 s_consume_run_idle = 0;
#endif

未定义OPENER_CONSUMED_DATA_HAS_RUN_IDLE_HEADER导致,找打地方定义就好了。

5.3、UDP创建失败

紧接着出现了udp创建失败问题,对比两者的log发现:

问题原因为#105,内存不够,于是进行了多种尝试与排查:

#define MEM_SIZE                       10240//增加lwip的内存,默认为1600
#define RECV_BUFSIZE_DEFAULT            4096//减小pbuf的内存,默认2000000000 
#define MEMP_NUM_UDP_PCB                10//增加共同存在的DUP数量,默认6

最终在调整了MEMP_NUM_NETCONN为8后解决,增加了netconns的数量

正常运行输出log如下:

creating class 'message router' with code: 0x2
adding 1 instances to class message router
>>> Allocate memory for meta-message router 1 bytes times 3 for masks
>>> Allocate memory for message router 1 bytes times 3 for masks
meta-message router, number of services:2, service number:1
meta-message router, number of services:2, service number:14
message router, number of services:1, service number:14
creating class 'identity' with code: 0x1
adding 1 instances to class identity
>>> Allocate memory for meta-identity 1 bytes times 3 for masks
>>> Allocate memory for identity 1 bytes times 3 for masks
meta-identity, number of services:2, service number:1
meta-identity, number of services:2, service number:14
identity, number of services:5, service number:14
identity, number of services:5, service number:1
identity, number of ser
[2025-07-10 14:33:28.728]# RECV ASCII>
vices:5, service number:5
identity, number of services:5, service number:3
identity, number of services:5, service number:4
creating class 'TCP/IP interface' with code: 0xF5
adding 1 instances to class TCP/IP interface
>>> Allocate memory for meta-TCP/IP interface 1 bytes times 3 for masks
>>> Allocate memory for TCP/IP interface 2 bytes times 3 for masks
meta-TCP/IP interface, number of services:2, service number:1
meta-TCP/IP interface, number of services:2, service number:14
TCP/IP interface, number of services:3, service number:14
TCP/IP interface, number of services:3, service number:1
TCP/IP interface, number of services:3, service number:16
creating class 'Ethernet Link' with code: 0xF6
adding 1 instances to class Ethernet Link
>>> Allocate memory for meta-Ethernet Link 1 bytes times 3 for masks
>>> Allocate memory for Ethernet Link 2 bytes times 3 for masks
meta-Ethernet Link, number of services:2, service number:1
meta-Ethernet Link, number of services:2, service number:14
Ethernet 
[2025-07-10 14:33:28.821]# RECV ASCII>
Link, number of services:2, service number:14
Ethernet Link, number of services:2, service number:1
creating class 'connection manager' with code: 0x6
adding 1 instances to class connection manager
>>> Allocate memory for meta-connection manager 1 bytes times 3 for masks
>>> Allocate memory for connection manager 2 bytes times 3 for masks
meta-connection manager, number of services:2, service number:1
meta-connection manager, number of services:2, service number:14
connection manager, number of services:8, service number:14
connection manager, number of services:8, service number:1
connection manager, number of services:8, service number:84
connection manager, number of services:8, service number:91
connection manager, number of services:8, service number:78
connection manager, number of services:8, service number:90
connection manager, number of services:8, service number:86
connection manager, number of services:8, service number:87
creating class 'assembly' with code: 0x4
>>> Allocate memo
[2025-07-10 14:33:28.915]# RECV ASCII>
ry for meta-assembly 1 bytes times 3 for masks
>>> Allocate memory for assembly 1 bytes times 3 for masks
meta-assembly, number of services:1, service number:14
assembly, number of services:2, service number:14
assembly, number of services:2, service number:16
creating class 'Quality of Service' with code: 0x48
adding 1 instances to class Quality of Service
>>> Allocate memory for meta-Quality of Service 1 bytes times 3 for masks
>>> Allocate memory for Quality of Service 2 bytes times 3 for masks
meta-Quality of Service, number of services:2, service number:1
meta-Quality of Service, number of services:2, service number:14
Quality of Service, number of services:2, service number:14
Quality of Service, number of services:2, service number:16
adding 1 instances to class assembly
adding 1 instances to class assembly
adding 1 instances to class assembly
adding 1 instances to class assembly
adding 1 instances to class assembly
adding 1 instances to class assembly
adding 1 instances to class ass
[2025-07-10 14:33:28.975]# RECV ASCII>
embly
OpENer: opener_thread started
 
[2025-07-10 14:33:29.068]# RECV ASCII>
networkhandler: new TCP connection
>>> network handler: accepting new TCP socket: 7 
New highest socket: 7
networkhandler: opened new TCP connection on fd 7
 
[2025-07-10 14:33:29.164]# RECV ASCII>
Entering HandleDataOnTcpSocket for socket: 7
Data received on TCP: 28
Handles data for TCP socket: 7
Register session
Adds socket 7 to socket timers
Sets time stamp for socket 7
TCP reply: send 28 bytes on 7

文内示例见咸鱼ID:tb764914262

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐