阅读ethercat官方文档关于ethercat网卡驱动程序的一些内容

学习交流加

  • 个人qq:
    1126137994
  • 个人微信:
    liu1126137994
  • 学习交流资源分享qq群:
    962535112

改造iMX6(fec)网卡驱动程序前期工作之:阅读ethercat-1.5.2.pdf文档的第四章内容。

ethercat-1.5.2.pdf文档链接:
前期我已经将iMX6网卡驱动程序整体分析了一遍(点击链接查看之前分析的网卡驱动程序),今天来阅读ethercat官方文档,看应该如何修改iMX6网卡驱动程序,从而保证数据传输的实时性。

分析网络设备驱动程序的基本功能阅读ethercat官方文档:点击下载文档

第四章:
Tasks of a Network Driver:
网络设备驱动程序通常处理OSI模型(下面有搜索的介绍什么是OSI模型)的较低两层,即物理层和数据链路层。一个网络设备(网口,phy芯片)就是处理物理层的数据的。它代表连接到介质的硬件,以物理层协议描述的方式发送和接收数据。而网络驱动程序是从内核的网络堆栈中获取数据,将数据传送到硬件(物理传输)。然后如果硬件接收到数据,它就会反馈给驱动程序(通过中断的方式),然后驱动程序通过读取硬件的存储器获取到反馈回来的数据,并将数据传送给内核的网络堆栈空间。还有就是一个网络设备驱动程序必须处理包括队列控制,统计和设备相关功能的功能。

4.1网络设备驱动程序的基础:
1.Interrupt Operation:
网络设备通常提供一个硬件中断,用于通知接收数据的驱动程序,是否数据传输成功或者失败。驱动程序必须注册一个中断服务例程(ISR),每次执行时,硬件都会发出这样的事件。如果中断是由自己的设备抛出(多个设备可以共享一个硬件中断),那么中断的原因必须通过读取设备的中断寄存器来确定。

2.The net_device Structure:
驱动程序为每个设备注册一个net_device结构,以与网络堆栈通信,并创建一个网络接口,在以太网驱动程序中,这个接口显示为ethX,其中X是在注册时由内核分配的数字。驱动程序为每个设备注册一个net_device结构,以与网络堆栈通信,并创建一个\网络接口。在以太网驱动程序中,这个接口显示为ethX,其中X是在注册时由内核分配的数字。net_device结构体通过几个回调接收事件(来自用户空间或来自网络堆栈),必须在注册之前设置。然而并非每个回调都是强制性的,但对于合理的操作,以下的回调是必要的:

open():当需要启动网络通信时,就会调用此函数,例如在用户空间设置了ethX之后,数据帧接收
必须被驱动程序开启。stop():这个函数是关闭关闭“设备”,即是数据帧的接收停止hard_start_xmit():这个函数将每一个要传送的数据帧的指针给一个sk_buffer结构体,传送完数据之后再释放get_stats():这个函数返回一个指向设备的net_device_stats的结构体指针,每当收到一个帧,发
送或发生错误时,该结构中的相应计数器就必须增加。

重要内容相关解释:
The netif Interface:
网络堆栈中的所有其他通信都是通过netif_*()函数调用完成的。例如:当成功打开一个设备,必须通知网络堆栈,现在可以将数据帧传递给接口Interface,这是通过netif_start_queue()这个函数的调用完成的。接着调用hard_start_xmit()函数。 此外,网络驱动程序通常管理帧传输队列,如果这个传输队列被议案满了(fill up),调用:netif_stop_queue()告诉网络堆栈必须停止一段时间的数据帧的传输,当一些数据帧被发送了之后,通过调用netif_wake_queue()函数告知更多的数据过来排队等待被传送。还有一个重要的函数netif_receive_skb(),它将设备传来的数据传送到网络堆栈。其中数据帧是放在一个叫做套接字的缓冲区中(socket buffer)。

Socket Buffers:
套接字缓冲区是整个网络堆栈的基本数据类型。它们充当网络数据的容器,并且能够快速添加数据页眉和页脚,或者再次剥离它们。因此,套接字缓冲区由一个分配的缓冲区和几个标记缓冲区(头)以及数据开始,以数据尾和缓冲区结束的指针组成。此外,Socket Buffer由一个网络头和(在接收到数据的前提下)一个指向net_device的指针组成。存在创建套接字缓冲区(dev_alloc_skb())的函数,front(skb_push())或back(skb_put())用于添加数据
front(skb_pull()) 或(skb_trim())用于移除数据,
或者 删除缓冲区(kfree_skb())。
一个套接字缓冲区从一个层传递到另一个层,并被上一次使用它的层释放。 在发送的情况下,释放必须由网络驱动程序完成。

4.2Native EtherCAT Device Drivers(本地EtherCAT 设备驱动程序):
这种网卡驱动程序的话,是需要经过修改的非标准以太网驱动程序。那么它有什么特点呢?下面我们来讲解:

1)Dedicated Hardware(专用硬件)
为了实现高性能和实时性,EtherCAT主站需要直接访问以太网硬件。这意味着网络设备一定不能像往常一样连接到内核的网络堆栈,因为内核会尝试把它用作普通的以太网设备。
2)Interrupt-less Operation(无中断操作)
EtherCAT数据帧是通过逻辑EtherCAT环进行传送与接收的。通信是高度确定性的:一个帧被发送,并在一段时间后再次被接收,不需要告诉驱动程序帧接收。用mster(主机)代替硬件驱动程序去查询接收的帧。

下图显示了有和没有中断的循环帧传送和接收的两个工作流程:
有无中断的区别

在左边的工作流程“中断操作”中,首先处理来自上一个周期的数据,并且用新的数据报组装一个新的帧,这个数据帧是一会要被发送的。当循环工作完成后,又从硬件传来了一个数据帧,此时硬件中断被触发,并执行中断服务程序(ISR)。ISR将从硬件中取出帧数据并启动帧解析:数据报将被处理,以便数据在下一个周期中准备好处理。

在右边的工作流程“无中断操作”中,没有硬件中断使能,而是由主站通过执行ISR轮询硬件,如果在此期间收到数据帧,则该数据帧将被解析。然后剩下的就跟左边的操作一样:接收到的数据被处理,一个新的帧被包装和发送,剩余的周期没有任何事情要做。

无中断操作是可取的,因为硬件中断不利于驱动程序的实时性。因为硬件中断不确定的发生率,会导致增加抖动。此外,如果使用实时扩展(如RTAI),则需要做一些额外的工作来优先化中断。

3)Ethernet and EtherCAT Devices(以太网和Ethercat设备)
另一个问题在于Linux处理相同类型的设备的方式。例如:PCI驱动程序扫描PCI总线以查找可处理的设备。然后它将自己注册成为所有找到的设备的驱动程序。问题是:一个没有被修改的驱动程序不能忽略一个有可能即将被使用的设备(即我们的Ethercat设备),这样驱动程序就得等待Ethercat设备,那么我们的普通的网络设备就无法被驱动了。必须有一种方法来处理同一类型的多个设备,其中一个为EtherCAT保留,而另一个则视为普通的以太网设备。

出于所有这些原因,作者认为唯一可接受的解决方案是修改标准以太网驱动程序,使其保持正常的功能,但能够将一个或多个设备视为支持EtherCAT的设备。

下面是这个解决方案的有点:
•无需告诉标准驱动程序忽略某些设备。
•一个用于EtherCAT和非EtherCAT设备的网络驱动程序。
•无需从头开始实施网络驱动程序,前开发者已经解决了。

该解决方案的缺点:
•修改后的驱动程序变得更加复杂,因为它必须处理EtherCAT和非EtherCAT设备。
•驱动程序代码中还有许多额外的个案区分。
•标准驱动程序的更改和 须不时地移植到支持EtherCAT的版本

4.3Generic EtherCAT Device Driver(通用的Ethercat设备驱动程序)
该方案的话,使用的是标准的以太网网卡驱动程序,不要修改。但是我们还是过来分析一下,为什么这样做性能会差一些。
下图是通用以太网驱动模块:
通用以太网驱动模块

这张图非常的经典。它通过网络堆栈连接到本地以太网设备,内核模块被命名为ec_generic,它在主模块之后加载,例如具有本地EtherCAT功能的以太网驱动程序。通用设备驱动程序扫描网络堆栈接口,一旦有设备驱动程序被注册了,它就将其提给Ethercat主站。如果主站接受了一个设备,那么通用驱动程序就会创建一个 packet socket (包套接字),socket_type设置为SOCK_RAW绑定到该设备上,设备接口的所有功能(见4.6节)将在该套接字上运行。

该方案的优点:
•可以使用Linux以太网驱动程序覆盖的任何以太网硬件
用于EtherCAT。
•不必对实际的以太网驱动程序进行修改。通用

该方案的缺点:
•性能比本地方法稍差,因为该框架数据必须遍历网络堆栈的较低层。
•不能像RTAI一样使用内核实时扩展驱动程序,因为网络堆栈代码使用动态内存分配和其他的事情,这可能会导致系统在实时的情况下冻结。

设备激活:
为了通过套接字发送和接收帧,链接到该套接字的以太网设备必须被激活,否则所有的帧都将被拒绝。激活必须在主模块被加载之前发生并且可以有多种方式操作:
•Ad-hoc,使用命令ip link set dev ethX up(或使用常用的命令:ifconfig ethX up)
•根据分布情况进行配置,例如使用ifcfg文件(/ etc/ sysconfig / network / ifcfg-ethX)在openSUSE和其他。这是更好的方式如果EtherCAT主站在系统启动时启动。但是以太网设备只能被激活,不能分配IP地址,使用STARTMODE = auto作为配置就足够了。
(我之前直接使用:ifconfig eth0 up)

4.4Providing Ethernet Devices(提供以太网设备)
加载主模块后,必须加载其他模块设备连接到主设备(参见4.6节),主模块要可以从模块参数判断要接收的设备。 如果使用init脚本来启动master,则可以在sysconfig文件中指定要使用的驱动程序和设备(请参阅第7.4.2小节)。

提供以太网设备的模块可以是:
•具有本地EtherCAT功能的网络驱动程序模块(请参阅第4.2节)或
•通用EtherCAT设备驱动程序模块(请参阅第4.3节)。

4.5Redundancy(冗余)

Redundancy的意思是主站与从站之间有读个网络链接。并且数据的传输是在每一个主链路上发出去。这样的话,即使某一个主站与从站链接断开了,仍然可以保证数据的完整传送。
完全冗余总线操作的先决条件是每个从设备至少可以通过一个主设备连接。在这种情况下,单个连接失败(即电缆中断)将永远不会导致不完整的过程数据。两个以太网设备无法处理双重故障。
在配置时使用–with-devices开关配置冗余(参见第9章),并使用ec_master内核模块的backup_devices参数(参见2.1节)或(sys-)配置文件中的相应变量MASTERx_BACKUP(参见第7.4.2)。
总线扫描是在任何以太网链路上进行拓扑更改后完成的。应用程序接口(请参阅第3章)和命令行工具(请参阅第7.1节)都有查询冗余操作状态的方法。

4.6 EtherCAT Device Interface(EtherCAT )
为了理解网络设备驱动程序模块可以将设备连接到特定的EtherCAT主站的方式,需要对主站模块(2.1节)进行预测。
主模块为网络设备驱动程序提供了一个“设备接口”,要使用该接口,网络设备驱动程序模块必须包含带有EtherCAT主代码的头文件devices / ecdev.h,该头文件为EtherCAT设备提供了一个功能接口 。设备接口的所有功能都以前缀ecdev命名。
设备接口的文档可以在头文件或接口文档的相应模块中找到(请参见第9.3节的生成说明)

4.7 Patching Native Network Drivers(修改本地网卡驱动程序)
好了,上面分析了那么多,这里终于给出了如何修改网卡驱动程序让它支持Ethercat协议了。
参4.2节的内容,下面给出需要修改的地方:

1.第一条简单的规则是,所有EtherCAT都必须避免netif _ *()调用设备。如前所述,EtherCAT设备没有连接到
网络协议栈,因此不能调用其接口函数。
2.禁用中断:EtherCAT设备应该在没有运行的情况下运行中断。所以任何调用中断处理程序和启用中断的调用
在硬件层面也必须避免。
3.标准网卡驱动程序中,将数据包发送后将释放数据包所占用的内存,或者放回预先分配的内存池中。而EtherCAT通信中主站不会为每个发送操作使用的套接字缓冲区,而是在主站初始化时分配一个缓冲区重复使用。这个套接字缓冲区在每次发送操作时都填入一个EtherCAT数据帧并传递给EtherCAT的hard_start_xmit()函数回调。为此,套接字缓冲区是必要的不像平常那​​样被网络驱动程序释放。

注:一个以太网驱动程序通常处理几个以太网设备,每个设备被一个带有私有数据priv_data字段的net_device结构体描述,将依赖于该驱动程序的数据附加到该net_device结构体,为了区分正常的以太网设备和EtherCAT主设备使用的设备,驱动程序使用的私有数据结构可以通过一个指针扩展,该指针指向一个由ecdev_offer()返回的ec_device_t对象(参见4.6节)。 RealTek RTL-8139快速以太网驱动程序是一个“简单的”以太网驱动程序,可以作为修补新驱动程序的一个例子,后面我就会参考这个例子,来修改我的网卡驱动程序。

补充:什么是OSI模型:点击查看OSI七层模型详解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/423314.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jz2440开发板移植U-boot之修改代码支持DM9000网卡

今天我们来移植U-boot到jz2440开发板,修改代码支持DM9000网卡。查看之前写的移植记录请点击链接:点击查看之前的移植记录 现在大多数开发板都支持DM9000网卡。我们的U-boot源码里面也是有DM9000网卡的驱动程序的。文件为Dm9000x.c(drivers\n…

移植U-BOOT之裁剪和修改默认参数(易用性)启动内核,以及对uboot进行分区

今天我们来裁剪U-BOOT,使其更加易用,修改默认参数,以及制作最终修改好得补丁文件方便以后的快速移植。 那么如果想看之前的关于网卡以及flash等的移植,请点击链接查看:点击链接查看 在裁剪修改之前呢,我们…

移植U-BOOT之支持烧写YAFFS文件系统以及制作U-BOOT补丁

今天,我们来移植U-BOOT让其支持YAFFS文件系统映像的烧写,以及最后的终极目标,制作Uboot补丁,因为我们信心苦苦移植好了Uboot,如果换一个地方的或者换一台电脑之类的,我们也不想再浪费时间从头开始移植&…

【数据结构学习之完全从零实现所有数据结构的代码编写之一】泛型编程简介

学习交流加 个人qq: 1126137994个人微信: liu1126137994学习交流资源分享qq群: 962535112 今天开始系统性学习数据结构内容,之前也看过大话数据结构这本书,对大多数概念以及数据结构都有一定的了解,但是就是…

zookeeper 安装和使用

1.Windows安装和使用zookeeper 之前整理过一篇文章《zookeeper 分布式锁服务》,本文介绍的 Zookeeper 是以 3.4.5 这个稳定版本为基础,最新的版本可以通过官网 http://hadoop.apache.org/zookeeper/来获取,Zookeeper 的安装非常简单&#xf…

【移植Linux 3.4.2内核第一步】之简单修改

前一阵子已经将U-boot移植好了,从今天开始,我们开始移植linux内核。移植的内核为3.4.2,移植的开发板为:jz2440开发板。 想看之前移植U-boot的记录,可以查看我的博客专栏,点击链接:点击查看U-bo…

前端学习(77):css中常见margin塌陷问题之解决办法

塌陷问题 当两个盒子在垂直方向上设置margin值时&#xff0c;会出现一个有趣的塌陷现象。 ①垂直并列 首先设置两个DIV,并为其制定宽高 1 1 /*HTML部分*/2 <body>3 <div class"box1">box1</div>4 <div class"box2">box2…

HBase2.0 vs HBase1.x 延时比较

hbase2.0已经正式发布&#xff0c;对比之前1.x版本&#xff0c;2.0在读写链路上做了完善的优化&#xff0c;offheap、netty rpc等&#xff0c;这里做个小测试实验对比1.x和2.0在读写上的延时情况。本测试基于特定测试环境与软件版本得到的结果&#xff0c;仅供参考。 测试介绍 …

【数据结构学习之完全从零实现所有数据结构的代码编写之二】智能指针

今天我们依然暂时不讲解数据结构里面的内容&#xff0c;我们来复习一下昨天学的模板技术用于数据结构编程的思想&#xff0c;给出一个模板技术的实例&#xff1a;智能指针的应用。喜欢看我分享的加我q:1126137994 加我共同学习交流各种技术。 为什么会引入智能指针呢&#xff…

职责链模式(Chain of Responsibility)

重要概念 1. 使多个对象都有机会处理请求&#xff0c;从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链&#xff0c;并沿着这条链传递该请求&#xff0c;直到有一个对象处理它为止。 2.请求是沿着链条传递到有一个处理点对象负责处理这个请求为止。请求者无需…

mootools

$();// 选择ID为”body_wrap“的元素$(body_wrap);.getElement();// 选择ID为”body_wrap“的元素下面的第一个链接$(body_wrap).getElement(a); or #xxx or .xxx.getElements();// 选择ID为”body_wrap“的元素下面的所有链接$(body_wrap).getElements(a); $(body_wrap).getE…

图形化界面客户端连接phoenix操作hbase

下载客户端软件 DBeaver https://dbeaver.io/download/ 选择对应系统的版本&#xff0c;我这里选择解压版windows64位 创建连接 注意&#xff1a;URL模板就不要一般是默认 选择合适的版本&#xff08;跟你服务器的版本一致&#xff09;&#xff0c;下载jar包 点击测试或完成即…

【C++深度剖析教程12】数组操作符的重载

之前写的C学习记录忘记打编号了&#xff0c;从今天开始&#xff0c;所有内容&#xff0c;记录编号&#xff0c;方便以后的查阅复习。今天学习的是C中&#xff0c;数组操作符的重载。 上一篇博文写的是介绍C中的字符串类&#xff0c;我们知道&#xff0c;C标准库中通过string类…

前端学习(80):按类型划分标签(inline)

解决font-size中间有间隙 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"X-UA-Compat…

HBase shell 命令介绍

HBase shell是HBase的一套命令行工具&#xff0c;类似传统数据中的sql概念&#xff0c;可以使用shell命令来查询HBase中数据的详细情况。安装完HBase之后&#xff0c;如果配置了HBase的环境变量&#xff0c;只要在shell中执行hbase shell就可以进入命令行界面&#xff0c;HBase…

【C++深度剖析教程13】函数对象的分析

今天来学习函数对象。什么是函数对象呢&#xff1f;下面我们以一个例子来引出函数对象的概念。 假设我们需要编写一个函数&#xff0c;实现下面这些功能&#xff1a; -函数可以获得斐波那契数列每一项的值 -每调用一次返回一个值 -函数可根据需要重复用使用 实现上面的几个…

IE图标消失 HTML文件图标变为未知图标的解决方法

有时候保存在硬盘里的HTM和HTML文件图标会突然变为未知的图标&#xff0c;而且它们往往还是与IE关联&#xff0c;也没有发现病毒。原因我怎么也弄不明白&#xff0c;但可以通过对注册表做些修改来恢复&#xff0c;详细步骤如下: 1.首先打开注册表编辑器&#xff0c;定位到HKEY_…

(SQuirreL SQL Client 客户端 )使用Apache Phoenix 实现 SQL 操作HBase

Apache Phoenix 相信大家并不陌生&#xff0c;它是HBase的SQL驱动&#xff0c;Phoenix 使得Hbase 支持通过JDBC的方式进行访问&#xff0c;并将你的SQL查询转换成Hbase的扫描和相应的动作。 兼容性&#xff1a; Phoenix 2.x - HBase 0.94.x Phoenix 3.x - HBase 0.94.x Phoen…

【C++深度剖析教程14】经典问题解析三之关于赋值的疑问

今天我们来总结一下&#xff0c;之前所学C中所遇到的一些经典的问题。 第一个疑问是&#xff1a; -什么时候需要重载赋值操作符 -编译器是否提供默认的赋值操作&#xff1f; 解答&#xff1a; *编译器为每个类默认重载了赋值操作符 *默认的赋值操作符仅完成了浅拷贝 *当…