Ethernet Devices(以太网设备)
The EtherCAT protocol is based on the Ethernet standard, so a master relies on standard Ethernet hardware to communicate with the bus.
EtherCAT协议基于以太网标准,因此主站依赖于标准以太网硬件与总线进行通信。
The term device is used as a synonym for Ethernet network interface hardware.
术语"设备" 用作以太网网络接口硬件的同义词。
Native Ethernet Device Drivers There are native device driver modules (see section 4.2) that handle Ethernet hardware, which a master can use to connect to an EtherCAT bus. They offer their Ethernet hardware to the master module via the device interface (see section 4.6) and must be capable to prepare Ethernet devices either for EtherCAT (realtime) operation or for “normal” operation using the kernel’s network stack. The advantage of this approach is that the master can operate nearly directly on the hardware, which allows a high performance. The disadvantage is, that there has to be an EtherCAT-capable version of the original Ethernet driver.
原生以太网设备驱动 有一些(网络)设备驱动模块来处理以太网硬件,主站通过这些驱动来连接到EtherCAT总线上。它们通过设备接口向主站模块提供以太网硬件(收发数据)并且必须能够为EtherCAT实时操作或者使用Linux内核网络协议栈进行一些常规操作。这种方法的优点是主站几乎可以直接在硬件上操作,从而实现高实时性。缺点是,得有一个支持EtherCAT的网卡驱动。
Generic Ethernet Device Driver From master version 1.5, there is a generic Ethernet device driver module (see section 4.3), that uses the lower layers of the network stack to connect to the hardware. The advantage is, that arbitrary Ethernet hardware can be used for EtherCAT operation, independently of the actual hardware driver (so all Linux Ethernet drivers are supported without modifications). The disadvantage is, that this approach does not support realtime extensions like RTAI, because the Linux network stack is addressed. Moreover the performance is a little worse than the native approach, because the Ethernet frame data have to traverse the network stack.
通用以太网网卡驱动 从主站1.5版本开始,有一个通用网络设备驱动模块,使用网络协议栈的较低层来连接硬件(网络设备)。优点是,任何以太网设备都能够操作EtherCAT, 独立于实际的硬件驱动(因此Linux网卡驱动不需要修改)。缺点是,这种方法不支持像RATI这样的实时扩展,因为使用的是Linux的网络协议栈。此外由于以太网帧数据经过了网络协议栈的每一层,因此性能比原生以太网驱动要差一些。
Network Driver Basics(网络设备驱动基础)
EtherCAT relies on Ethernet hardware and the master needs a physical Ethernet device to communicate with the bus. Therefore it is necessary to understand how Linux handles network devices and their drivers, respectively.
EtherCAT依赖于以太网硬件,主站需要物理以太网设备才能与总线通信。因此,有必要了解Linux如何处理以太网设备以及设备驱动。
Tasks of a Network Driver Network device drivers usually handle the lower two layers of the OSI model, that is the physical layer and the data-link layer. A network device itself natively handles the physical layer issues: It represents the hardware to connect to the medium and to send and receive data in the way, the physical layer protocol describes. The network device driver is responsible for getting data from the kernel’s networking stack and forwarding it to the hardware, that does the physical transmission. If data is received by the hardware respectively, the driver is notified (usually by means of an interrupt) and has to read the data from the hardware memory and forward it to the network stack. There are a few more tasks, a network device driver has to handle, including queue control, statistics and device dependent features.
网络设备驱动程序通常处理OSI模型的下两层,即物理层和数据链路层。网络设备本身原生处理物理层问题:它代表连接传输介质的硬件,并以物理层协议描述的方式发送和接收数据。网络设备驱动程序负责从内核网络协议栈获取数据并转发给执行物理传输的硬件。当硬件接收到数据时(通常通过中断通知),驱动程序需从硬件内存读取数据并转发至网络协议栈。此外,网络设备驱动程序还需处理队列控制、统计信息及设备相关功能等任务。
Driver Startup Usually, a driver searches for compatible devices on module loading. For PCI drivers, this is done by scanning the PCI bus and checking for known device IDs. If a device is found, data structures are allocated and the device is taken into operation.
驱动程序启动 通常,驱动程序在模块加载时会搜索兼容设备。对于PCI驱动程序,这一过程通过扫描PCI总线并检查已知设备ID来完成。若发现设备,则会分配数据结构并将该设备投入运行。
Interrupt Operation A network device usually provides a hardware interrupt that is used to notify the driver of received frames and success of transmission, or errors, respectively. The driver has to register an interrupt service routine (ISR), that is executed each time, the hardware signals such an event. If the interrupt was thrown by the own device (multiple devices can share one hardware interrupt), the reason for the interrupt has to be determined by reading the device’s interrupt register. For example, if the flag for received frames is set, frame data has to be copied from hardware to kernel memory and passed to the network stack.
中断操作 网络设备通常会提供一个硬件中断,用于分别通知驱动程序接收到的帧、传输成功或错误。驱动程序需注册一个中断服务例程(ISR),每当硬件触发此类事件时便会执行该例程。若中断由自身设备触发(多个设备可能共享同一硬件中断),则需通过读取设备的中断寄存器来确定中断原因。例如,若接收帧的标志位被置起,则需将帧数据从硬件复制到内核内存并传递给网络协议栈。
The net_device Structure The driver registers a net_device structure for each device to communicate with the network stack and to create a “network interface”. In case of an Ethernet driver, this interface appears as ethX, where X is a number assigned by the kernel on registration. The net_device structure receives events (either from userspace or from the network stack) via several callbacks, which have
to be set before registration. Not every callback is mandatory, but for reasonable operation the ones below are needed in any case:
open() This function is called when network communication has to be started, for example after a command ip link set ethX up from userspace. Frame reception has to be enabled by the driver.
stop() The purpose of this callback is to “close” the device, i. e. make the hardware stop receiving frames.
hard_start_xmit() This function is called for each frame that has to be transmitted. The network stack passes the frame as a pointer to an sk_buff structure (“socket buffer”, see below), which has to be freed after sending.
get_stats() This call has to return a pointer to the device’s net_device_stats structure, which permanently has to be filled with frame statistics. This means, that every time a frame is received, sent, or an error happened, the appropriate counter in this structure has to be increased.
net_device 结构体
驱动程序通过为每个设备注册一个net_device结构体来与网络栈通信,并创建一个“网络接口”。对于以太网驱动程序,该接口显示为ethX(其中X是内核在注册时分配的数字)。net_device结构体通过多个回调函数接收事件(来自用户空间或网络栈),这些回调必须在注册前设置。并非所有回调都是强制性的,但为实现基本功能,以下回调在任何情况下都必须实现:
open() 此函数在网络通信需要启动时被调用,例如当用户空间执行ip link set ethX up命令后。驱动程序需在此启用帧接收功能。
stop() 该回调函数的作用是"关闭"设备,即使硬件停止接收数据帧。
hard_start_xmit() 每个待发送的数据帧都会触发此函数调用。网络栈会以指向sk_buff结构体(“socket buffer”,见下文)的指针形式传递数据帧,发送完成后需释放该结构体。
get_stats() 此调用需返回指向设备net_device_stats结构体的指针,该结构体需持续更新帧统计信息。这意味着每当接收到数据帧、发送数据帧或发生错误时,都必须递增此结构体中相应的计数器。
The actual registration is done with the register_netdev() call, unregistering is done with unregister_netdev().
实际的注册是通过调用register_netdev()完成的,注销则是通过unregister_netdev()完成。
The netif Interface All other communication in the direction interface → network stack is done via the netif_*() calls. For example, on successful device opening, the network stack has to be notified, that it can now pass frames to the interface. This is done by calling netif_start_queue(). After this call, the hard_start_xmit() callback can be called by the network stack. Furthermore a network driver usually
manages a frame transmission queue. If this gets filled up, the network stack has to be told to stop passing further frames for a while. This happens with a call to netif_stop_queue(). If some frames have been sent, and there is enough space again to queue new frames, this can be notified with netif_wake_queue(). Another important call is netif_receive_skb()1 : It passes a frame to the network stack, that was just received by the device. Frame data has to be included in a so-called “socket buffer” for that (see below).
netif 接口 所有从接口到网络栈的其他通信均通过 netif_*() 调用完成。例如,设备成功打开时,需通知网络栈现在可以将帧传递至接口,这是通过调用 netif_start_queue() 实现的。此后,网络栈便可调用 hard_start_xmit() 回调函数。此外,网络驱动通常管理一个帧传输队列。若队列填满,需告知网络栈暂停传递帧,此时调用 netif_stop_queue()。当部分帧已发送且队列有足够空间容纳新帧时,可通过 netif_wake_queue() 通知恢复传输。另一个重要调用是 netif_receive_skb():它将设备刚接收的帧传递给网络栈,帧数据需封装在所谓的“套接字缓冲区”中(见下文)。
Socket Buffers Socket buffers are the basic data type for the whole network stack. They serve as containers for network data and are able to quickly add data headers and footers, or strip them off again. Therefore a socket buffer consists of an allocated buffer and several pointers that mark beginning of the buffer (head), beginning of data (data), end of data (tail) and end of buffer (end). In addition, a socket buffer holds network header information and (in case of received data) a pointer to the net_device, it was received on. There exist functions that create a socket buffer (dev_alloc_skb ()), add data either from front (skb_push()) or back (skb_put()), remove data from
front (skb_pull()) or back (skb_trim()), or delete the buffer (kfree_skb()). A socket buffer is passed from layer to layer, and is freed by the layer that uses it the last time. In case of sending, freeing has to be done by the network driver.
套接字缓冲区 套接字缓冲区是整个网络栈的基本数据类型。它们作为网络数据的容器,能够快速添加或移除数据头部和尾部。因此,一个套接字缓冲区由分配的缓冲区及多个指针组成:这些指针分别标记缓冲区的起始位置(head)、数据的起始位置(data)、数据的结束位置(tail)以及缓冲区的结束位置(end)。此外,套接字缓冲区还保存网络头部信息;对于接收到的数据,它还包含一个指向接收该数据的网络设备(net_device)的指针。相关功能函数包括:创建套接字缓冲区(dev_alloc_skb())、从头部(skb_push())或尾部(skb_put())添加数据、从头部(skb_pull())或尾部(skb_trim())移除数据,以及释放缓冲区(kfree_skb())。套接字缓冲区会在网络层之间传递,并由最后一次使用它的层负责释放。对于发送的数据,释放操作需由网络驱动程序完成。
Native EtherCAT Device Drivers(原生EtherCAT设备驱动程序)
There are a few requirements, that applies to Ethernet hardware when used with a native Ethernet driver with EtherCAT functionality.
当与具有EtherCAT功能的原生以太网驱动程序一起使用时,对以太网硬件有几点要求。
Dedicated Hardware For performance and realtime purposes, the EtherCAT master needs direct and exclusive access to the Ethernet hardware. This implies that the network device must not be connected to the kernel’s network stack as usual, because the kernel would try to use it as an ordinary Ethernet device.
专用硬件 出于性能和实时性考虑,EtherCAT主站需要直接且独占访问以太网硬件。这意味着网络设备不能像常规情况那样连接到内核网络栈,否则内核会将其视为普通以太网设备使用。
Interrupt-less Operation EtherCAT frames travel through the logical EtherCAT ring and are then sent back to the master. Communication is highly deterministic: A frame is sent and will be received again after a constant time, so there is no need to notify the driver about frame reception: The master can instead query the hardware for received frames, if it expects them to be already received.
Figure 4.1 shows two workflows for cyclic frame transmission and reception with and without interrupts.
In the left workflow “Interrupt Operation”, the data from the last cycle is first processed and a new frame is assembled with new datagrams, which is then sent. The cyclic work is done for now. Later, when the frame is received again by the hardware, an interrupt is triggered and the ISR is executed. The ISR will fetch the frame data from the hardware and initiate the frame dissection: The datagrams will be processed, so that the data is ready for processing in the next cycle.
In the right workflow “Interrupt-less Operation”, there is no hardware interrupt enabled. Instead, the hardware will be polled by the master by executing the ISR. If the frame has been received in the meantime, it will be dissected. The situation is now the same as at the beginning of the left workflow: The received data is processed and a new frame is assembled and sent. There is nothing to do for the rest of the cycle. The interrupt-less operation is desirable, because hardware interrupts are not conducive in improving the driver’s realtime behaviour: Their indeterministic incidences contribute to increasing the jitter. Besides, if a realtime extension (like RTAI) is used, some additional effort would have to be made to prioritize interrupts.
无中断操作 EtherCAT帧在逻辑EtherCAT环网中传输后返回主站。通信具有高度确定性:发送的帧会在恒定时间后被重新接收,因此无需通知驱动程序帧已接收。主站可直接查询硬件以获取预期已接收的帧。
图4.1展示了两种周期帧收发的工作流程:含中断与无中断模式。
左侧流程为“中断操作”:
- 先处理上一周期的数据并组装含新数据报的帧
- 发送完成后结束当前周期任务
- 当硬件再次接收到帧时触发中断,执行中断服务程序(ISR)
- ISR从硬件获取帧数据并启动解析流程
- 处理数据报,为下一周期准备就绪
右侧流程为“无中断操作”:
- 禁用硬件中断
- 主站通过主动执行ISR轮询硬件状态
- 若帧已接收则立即解析
- 此时状态与左侧流程起始点相同:处理接收数据→组装新帧→发送
- 周期剩余时段无任务
无中断模式更优,因为硬件中断会劣化驱动程序的实时性——其不确定性会增加时间抖动。此外,若使用实时扩展(如RTAI),还需额外处理中断优先级问题。
Ethernet and EtherCAT Devices Another issue lies in the way Linux handles devices of the same type. For example, a PCI driver scans the PCI bus for devices it can handle. Then it registers itself as the responsible driver for all of the devices found. The problem is, that an unmodified driver can not be told to ignore a device because it will be used for EtherCAT later. There must be a way to handle multiple devices of the same type, where one is reserved for EtherCAT, while the other is treated as an ordinary Ethernet device.
以太网与EtherCAT设备 另一个问题在于Linux处理同类设备的方式。例如,PCI驱动程序会扫描PCI总线以寻找其可处理的设备,随后将自己注册为所有找到设备的驱动。问题在于,无法直接要求未经修改的驱动程序忽略某个设备(因为该设备后续将用于EtherCAT)。必须存在一种机制来处理同类多设备场景:其中一部分设备保留给EtherCAT使用,另一部分则作为普通以太网设备处理。
For all this reasons, the author decided that the only acceptable solution is to modify standard Ethernet drivers in a way that they keep their normal functionality, but gain the ability to treat one or more of the devices as EtherCAT-capable.
Below are the advantages of this solution:
• No need to tell the standard drivers to ignore certain devices.
• One networking driver for EtherCAT and non-EtherCAT devices.
• No need to implement a network driver from scratch and running into issues, the former developers already solved.
The chosen approach has the following disadvantages:
• The modified driver gets more complicated, as it must handle EtherCAT and non-EtherCAT devices.
• Many additional case differentiations in the driver code.
• Changes and bug fixes on the standard drivers have to be ported to the EtherCAT-capable versions from time to time.
基于以上原因,作者认为唯一可行的解决方案是以保留常规功能的方式修改标准以太网驱动,同时使其具备将一台或多台设备识别为支持EtherCAT的能力。
该方案具有以下优势:
• 无需配置标准驱动忽略特定设备
• 单网卡驱动同时兼容EtherCAT与非EtherCAT设备
• 避免从零开发网卡驱动可能遇到的、前人已解决的问题
采用此方法也存在以下局限:
• 改造后的驱动程序复杂度提升,需同时处理EtherCAT与非EtherCAT设备
• 驱动代码中需增加大量条件判断
• 需定期将标准驱动的变更与缺陷修复移植至EtherCAT兼容版本
Generic EtherCAT Device Driver(通用EtherCAT设备驱动程序)
Since there are approaches to enable the complete Linux kernel for realtime operation [12], it is possible to operate without native implementations of EtherCAT-capable Ethernet device drivers and use the Linux network stack instead. Figure 2.1 shows the “Generic Ethernet Driver Module”, that connects to local Ethernet devices via the network stack. The kernel module is named ec_generic and can be loaded after the master module like a native EtherCAT-capable Ethernet driver.
由于已有方法可实现完整Linux内核的实时操作[12],因此无需原生支持EtherCAT的以太网设备驱动程序,转而使用Linux网络协议栈即可运行。图2.1展示了通过协议栈连接本地以太网设备的"通用以太网驱动模块"。该内核模块名为ec_generic,可像原生支持EtherCAT的以太网驱动一样在主模块之后加载。
The generic device driver scans the network stack for interfaces, that have been registered by Ethernet device drivers. It offers all possible devices to the EtherCAT master. If the master accepts a device, the generic driver creates a packet socket (see man 7 packet) with socket_type set to SOCK_RAW, bound to that device. All functions of the device interface (see section 4.6) will then operate on that socket.
通用设备驱动程序会扫描网络堆栈中已由以太网设备驱动程序注册的接口,并将所有可能的设备提供给EtherCAT主站。若主站接受某设备,该通用驱动程序会创建一个绑定到该设备的数据包套接字(参见man 7 packet),其socket_type设置为SOCK_RAW。此后,设备接口的所有功能(参见第4.6节)都将通过该套接字进行操作。
Below are the advantages of this solution:
• Any Ethernet hardware, that is covered by a Linux Ethernet driver can be used for EtherCAT.
• No modifications have to be made to the actual Ethernet drivers.
该解决方案的优势如下:
• 任何受Linux以太网驱动程序支持的以太网硬件均可用于EtherCAT。
• 无需对实际的以太网驱动程序进行任何修改。
The generic approach has the following disadvantages:
• The performance is a little worse than the native approach, because the frame data have to traverse the lower layers of the network stack.
• It is not possible to use in-kernel realtime extensions like RTAI with the generic driver, because the network stack code uses dynamic memory allocations and other things, that could cause the system to freeze in realtime context.
通用方法存在以下缺点:
• 性能略逊于原生方法,因为帧数据必须穿越网络协议栈的底层。
• 无法在通用驱动中使用像RTAI这样的内核实时扩展,因为网络协议栈代码会使用动态内存分配等操作,可能导致系统在实时上下文中冻结。
Device Activation In order to send and receive frames through a socket, the Ethernet device linked to that socket has to be activated, otherwise all frames will be rejected. Activation has to take place before the master module is loaded and can happen in several ways:
• Ad-hoc, using the command ip link set dev ethX up (or the older ifconfigethX up),
• Configured, depending on the distribution, for example using ifcfg files (/etc/sysconfig/network/ifcfg-ethX) in openSUSE and others. This is the better choice, if the EtherCAT master shall start at system boot time. Since the Ethernet device shall only be activated, but no IP address etc. shall be assigned, it is enough to use STARTMODE=auto as configuration.
设备激活 要通过套接字发送和接收帧,必须先激活与该套接字关联的以太网设备,否则所有帧将被拒绝。激活操作需在主模块加载前完成,可通过以下方式实现:
- 临时激活:使用命令 ip link set dev ethX up(或旧版 ifconfig ethX up);
- 配置激活:根据系统发行版配置(例如 openSUSE 等系统使用 /etc/sysconfig/network/ifcfg-ethX 文件)。若需在系统启动时运行 EtherCAT 主站,此方式更优。由于仅需激活以太网设备而无需分配 IP 地址等参数,配置文件中使用 STARTMODE=auto 即可。
Providing Ethernet Devices(提供以太网设备)
After loading the master module, additional module(s) have to be loaded to offerdevices to the master(s) (see section 4.6). The master module knows the devices to choose from the module parameters (see section 2.1). If the init script is used to start the master, the drivers and devices to use can be specified in the sysconfig file (see subsection 7.4.2).
加载主模块后,必须加载附加模块以向主模块提供设备(参见第4.6节)。主模块通过模块参数知晓待选设备(参见第2.1节)。若使用初始化脚本启动主模块,则可在系统配置文件中指定所需的驱动程序和设备(参见第7.4.2小节)
Modules offering Ethernet devices can be
• native EtherCAT-capable network driver modules (see section 4.2) or
• the generic EtherCAT device driver module (see section 4.3).
提供以太网设备的模块可以是: • 原生支持EtherCAT的网络驱动模块(参见第4.2节),或 • 通用EtherCAT设备驱动模块(参见第4.3节)。
Redundancy(冗余)
Redundant bus operation means, that there is more than one Ethernet connection from the master to the slaves. Process data exchange datagrams are sent out on every master link, so that the exchange is still complete, even if the bus is disconnected somewhere in between.
冗余总线运行意味着从主站到从站存在多个以太网连接。过程数据交换报文会在每个主站链路上发送,因此即使总线在中间某处断开,数据交换仍能完整进行
Prerequisite for fully redundant bus operation is, that every slave can be reached by at least one master link. In this case a single connection failure (i. e. cable break) will never lead to incomplete process data. Double-faults can not be handled with two Ethernet devices.
全冗余总线运行的前提条件是,每个从站至少可通过一条主站链路访问。在此情况下,单次连接故障(如电缆断裂)绝不会导致过程数据不完整。但双故障无法通过两个以太网设备处理。
Redundancy is configured with the --with-devices switch at configure time (see chapter 9) and using the backup_devices parameter of the ec_master kernel module (see section 2.1) or the appropriate variable MASTERx_BACKUP in the (sys-)config file (see subsection 7.4.2).
冗余配置可通过以下方式实现:在配置阶段使用–with-devices选项(参见第9章);通过ec_master内核模块的backup_devices参数(参考2.1节);或在(sys-)config文件中设置对应的MASTERx_BACKUP变量(详见7.4.2小节)。
Bus scanning is done after a topology change on any Ethernet link. The application interface (see chapter 3) and the command-line tool (see section 7.1) both have methods to query the status of the redundant operation.
总线扫描在任意以太网链路发生拓扑变化后执行。应用程序接口(参见第3章)和命令行工具(参见7.1节)均提供查询冗余运行状态的方法。
EtherCAT Device Interface(EtherCAT设备接口)
An anticipation to the section about the master module (section 2.1) has to be made in order to understand the way, a network device driver module can connect a device to a specific EtherCAT master.
为了理解网络设备驱动模块如何将设备连接到特定的EtherCAT主站,必须对主模块部分(第2.1节)进行前瞻性说明。
The master module provides a “device interface” for network device drivers. To use this interface, a network device driver module must include the header devices/ecdev.h, coming with the EtherCAT master code. This header offers a function interface for EtherCAT devices. All functions of the device interface are named with the prefix ecdev.
主模块为网络设备驱动程序提供了“设备接口”。要使用此接口,网络设备驱动模块必须包含随EtherCAT主站代码提供的头文件devices/ecdev.h。该头文件为EtherCAT设备提供了功能接口。设备接口的所有函数均以ecdev前缀命名。
The documentation of the device interface can be found in the header file or in the appropriate module of the interface documentation (see section 9.3 for generation instructions).
设备接口的文档可在头文件或接口文档的相应模块中找到(生成说明参见第9.3节)。
Patching Native Network Drivers(原生网络驱动程序打补丁)
This section will describe, how to make a standard Ethernet driver EtherCAT-capable,
using the native approach (see section 4.2). Unfortunately, there is no standard procedure to enable an Ethernet driver for use with the EtherCAT master, but there are a few common techniques.
- A first simple rule is, that netif_*() calls must be avoided for all EtherCAT devices. As mentioned before, EtherCAT devices have no connection to the network stack, and therefore must not call its interface functions.
- Another important thing is, that EtherCAT devices should be operated without interrupts. So any calls of registering interrupt handlers and enabling interrupts at hardware level must be avoided, too.
- The master does not use a new socket buffer for each send operation: Instead there is a fix one allocated on master initialization. This socket buffer is filled with an EtherCAT frame with every send operation and passed to the hard_start_xmit() callback. For that it is necessary, that the socket buffer is not be freed by the network driver as usual.
本节将描述如何使用原生方法(参见第4.2节)使标准以太网驱动程序支持EtherCAT功能。遗憾的是,目前没有标准流程能使以太网驱动程序与EtherCAT主站兼容,但存在几种常用技术方案:
- 首要基本原则是:必须避免对所有EtherCAT设备调用netif_*()系列函数。如前所述,EtherCAT设备与网络协议栈无关联,因此不得调用其接口函数。
- 另一关键要点是:EtherCAT设备应在无中断模式下运行。因此也必须避免任何中断处理程序注册操作及硬件层面的中断使能调用。
- 主站不会为每次发送操作分配新的套接字缓冲区:而是在主站初始化时固定分配一个。该缓冲区会在每次发送操作时填充EtherCAT帧并传递给hard_start_xmit()回调函数。因此网络驱动程序不得按常规方式释放此套接字缓冲区。
An Ethernet driver usually handles several Ethernet devices, each described by a net_device structure with a priv_data field to attach driver-dependent data to the structure. To distinguish between normal Ethernet devices and the ones used by EtherCAT masters, the private data structure used by the driver could be extended by a pointer, that points to an ec_device_t object returned by ecdev_offer() (seesection 4.6) if the device is used by a master and otherwise is zero.
以太网驱动程序通常处理多个以太网设备,每个设备由 net_device 结构描述,该结构具有 priv_data 字段用于附加驱动程序依赖的数据。为了区分普通以太网设备和 EtherCAT 主站使用的设备,驱动程序所使用的私有数据结构可以通过指针进行扩展——若设备被主站使用时,该指针指向由 ecdev_offer() 返回的 ec_device_t 对象(参见第4.6节);否则指针值为零。
The RealTek RTL-8139 Fast Ethernet driver is a “simple” Ethernet driver and can be taken as an example to patch new drivers. The interesting sections can be found by searching the string “ecdev” in the file devices/8139too-2.6.24-ethercat.c.
RealTek RTL-8139快速以太网驱动是一个“简易”以太网驱动,可作为新驱动补丁开发的参考范例。通过搜索文件devices/8139too-2.6.24-ethercat.c中的字符串"ecdev",即可定位到相关核心代码段。