一、Ethercat的优势
Ethercat是标准的以太网帧,Ethercat修改了数据链路层的结构使其更加符合工业应用中的实时性和一致性。由Ethercat的数据帧结构可以看出,Ethercat的帧结构和Ethernet的帧结构完全兼容,通过在数据段即用户应用协议层增加了Ethercat的对应数据。
Ethercat和传统以太网的区别:
1:数据链路层不同。
2:Ethercat是实时性传输,传统以太网非实时。
Ethercat和Can总线的区别:
1:Ethercat完全兼容CanOpen协议。
2:Ethercat突破了Can总线中对SDO的包长 的限制。
3:Ethercat一次传输可以遍历多个节点。
Ethercat的优势:实时性与同步性;Ethercat可以保证数据传输的实时性,数据的传送仅仅收到两帧之间的安全时间限制。Ethercat所独有的同步性可以保证所有的节点同步触发,其抖动时间可以达到1us。
二、传输机制
ON The Fly(飞行中的数据帧),更形象的演示可以参考Ethercat的PPT中的介绍很好的解释了Ethercat的传输机制,每一帧数据包由主站发出后依次经过各个从站,在经过各个从站同时经行数据交换,几乎没有任何的延时即可遍历一个节点。这得益于Ethercat对数据链路层的改造。
注意:Ethercat是全双工的传输,所有的数据交互均发生在数据传输阶段,数据在返回主站时,不做任何操作,只是经过各个节点时进行单纯的转发操作。Ethercat的拓扑结构灵活,几乎支持任何一种的拓扑结构,数据帧的传输方向完全有拓扑结构来决定。
三、寻址方式(主站寻址从站)
顺序寻址:主站按照物理连接的先后顺序进行寻址,一般用在主机刚刚启动时。
设置寻址:主站按照设置给每个从站的地址进行寻址。
逻辑寻址:主站将每个从站的地址映射到一个虚拟的4G缓存区,进行寻址(这种寻址比较实用、方便)。逻辑寻址的管理有从站的FMMU进行管理,FMMU将本地内存映射到主机设置的4G内存中的一块区域中。主站可以通过逻辑地址方便的读取任一从站的内存。
四、运行模式
从站的运行模式可支持自由运行、DC同步模式、SM同步模式。
自由运行由从站自主控制运行周期,一般用于开机初始化过程中,主要完成一些初始化工作和状态机的切换。
DC同步模式受DC同步信号的控制,DC触发的周期由主站设置,DC的脉冲宽度可以再XML文件configdata中进行设置。DC模式可以保证从站设备节点的一致性,因为分布时钟是严格保持一致的。DC模式下可产生两个中断信号sync0、sync1,均可单独配置。DC中断可以用来传输周期性传输PDO数据或者周期性进行数据采集。
SM同步模式:SM中断etherca
tisr发生于有输入输出时间发生时,即当主站想从站发送数据或请求时会触发事件中断,可以保证及时响应主站的请求和命令。
五、数据传输方式
主站与从站进行数据交互的方式主要通过PDO和SDO,即过程数据和邮箱数据其概念与CANOpen中的概念相同。
PDO:过程数据用来传输周期性的数据,PDO由三个数据缓冲区组成,类似于一个FIFO,从站写入第一个缓冲区,主站从第三个缓冲区读走。注意第二个缓冲区不可操作。从站发送PDO和接受PDO各自采用两个独立的数据缓冲区。有同步管理器来控制缓冲区,每一个同步管理器只负责一种功能,例如同步管理器2负责发送PDO,同步管理器3负责接受PDO。
SDO:邮箱
通信用来发送非周期性的数据,邮箱通信只有一个数据缓冲区,通信方式采用握手的机制确保主从之间的数据交互不丢失,而PDO由于采用FIFO的机制,可能会出现新值覆盖旧值或旧值被多次读走的情况。SDO也由同步管理器来进行管理,发送和接受邮箱独立控制,例如同步管理器0控制发送邮箱,同步管理器1控制接受邮箱。
六、实时性的意义
在主从DC同步模式下,主站需要以非常精准的时间发送过程数据,如下图所示:
七、实时性的关键
如下图所示,影响实时性的关键因素是操作系统和网卡驱动,前者需要将过程数据准时送出,后者需要优化网卡驱动,即"准时出发,路上不能耽误"。
作系统的实时性体现在需要非常准时地调用EtherCAT主站协议栈的发送函数,例如SOEM的发送函数是ecx_send_processdata()
Etherlab的发送函数为ecrt_master_send()。
采用Linux系统时,需要打上实时补丁,如Xenomai、RTAI、OSADL等。
标准Linux下的网卡驱动是为通用的网络通信设计的,网络数据穿过TCP/IP协议栈是一个非常漫长的过程,其中包括各种安全性检查、路由、出入队列、分片和重组等等,这其中有很多的不确定性,所以在EtherCAT主站开发中需要优化网卡驱动,使EtherCAT数据
绕过TCP/IP协议栈。
八、移植网卡驱动
在Etherlab的说明文档中给出了改造标准网卡驱动的三个基本点,如下:
(1)禁用netif_*()
(2)禁用中断
(3)重复利用socket buffer
接下来以EtherLAB源码中移植好的网卡驱动RealTek RTL-8139为例进行说明。
1、禁用netif_*()
在网卡驱动程序中的接收函数rtl8139_rx()中,netif_receive_skb (skb)负责将数据包传递给TCP/IP协议栈,
将其改成由EtherCAT主站直接处理。
改造前:
- static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
- int budget)
- {
- ......
- netif_receive_skb (skb);//将数据包提交给TCP/IP协议栈处理
- ......
- }
- 改造后:
- static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
- int budget)
- {
- ......
- if (tp->ecdev) { //作为EtherCAT使用时直接交给EtherCAT协议栈处理,绕过TCP/IP协议栈
- ecdev_receive(tp->ecdev,
- &rx_ring[ring_offset + 4], pkt_size);
- dev->last_rx = jiffies;
- dev->stats.rx_bytes += pkt_size;
- dev->stats.rx_packets++;
- }
- else
- {
- ......
- netif_receive_skb (skb);
- ......
- }
- }
2. 禁用中断
Linux标准网卡驱动中,采用中断方式收发网络数据包,较新的网卡驱动中采用NAPI(中断和轮询相结合),而EtherCAT通信中,EtherCAT主站发出过程数据包后,主站非常清楚数据包什么时候返回主站,因此不需要采用中断的方式,而由主站直接查询和处理返回的过程数据包。
改造前:
- static int rtl8139_open (struct net_device *dev)
- {
- ......
- retval = request_irq (dev->irq, rtl8139_interrupt, IRQF_SHARED, dev->name, dev); //向内核注册中断
- ......
- }
- 改造后:
- static int rtl8139_open (struct net_device *dev)
- {
- ......
- if (!tp->ecdev) {
- retval = request_irq(dev->irq, rtl8139_interrupt, //作为普通网卡时才注册中断
- IRQF_SHARED, dev->name, dev);
- if (retval)
- return retval;
- }
- ......
- }
- void ec_poll(struct net_device *dev)
- {
- rtl8139_interrupt(0, dev);
- }
- 函数调用关系为:ec_poll()->rtl8139_interrupt()->rtl8139_rx()->ecdev_receive();
3. 重复利用Socket buffer
Linux标准网卡驱动中,将数据包发送后将释放数据包所占用的内存,或者放回预先分配的内存池中,
而EtherCAT通信中,只需重复使用其中的一两个缓存即可,这样可以节省为数据包分配和释放内存的时间。
改造前:
- static netdev_tx_t rtl8139_start_xmit (struct sk_buff *skb,
- struct net_device *dev)
- {
- ......
- dev_kfree_skb(skb);//释放Socket buffer所占内存或将其放回内存池
- ......
- }
- 改造后:
- static netdev_tx_t rtl8139_start_xmit (struct sk_buff *skb,
- struct net_device *dev)
- {
- ......
- if (!tp->ecdev) { //只有作为普通网卡时才释放Socket buffer
- dev_kfree_skb(skb);
- }
- ......
- }