优化EtherCAT实时网卡驱动(创龙A40i板的千兆网卡)

优化EtherCAT实时网卡驱动(创龙A40i板的千兆网卡)

目录

优化EtherCAT实时网卡(创龙A40i板的千兆网卡)

一.generic通用模式的网卡驱动

优点:

缺点:

二.修改本地网卡驱动

优点:

缺点:

优化原则:

技巧

1. 获取网卡驱动源码

2. 参考igh ethercat修改的网卡驱动

3. 参考igh ethercat官方文档

4. 屏蔽自动加载网卡驱动

5. 了解Linux网卡驱动框架及DMA

修改详细说明

1)修改或添加的全部文件

2)获取1000兆网卡驱动源码

3)修改ethercat/devices/Kbuild.in

4)修改ethercat/devices/Makefile.am

5)修改网卡驱动sunxi-gmac-3.10-ethercat.c

(1)添加头文件

(2)struct geth_priv私有结构体添加ec_device_t

(3)屏蔽netif_*和napi_*接口

(4)屏蔽中断

(5)发送不释放skb_buff

(6)添加接收处理函数

编译

优化后对比

1.关闭中断

2.扫描总线时间

3.执行时间

三.总结


一.generic通用模式的网卡驱动

优点

- Linux以太网驱动程序涵盖的任何以太网硬件都可以用于EtherCAT。

- 无需修改实际的以太网驱动程序。

缺点

- 性能比本地方法差一点,因为帧数据必须遍历网络堆栈的较低层。

二.修改本地网卡驱动

  • 优点

- 实时性比较好。

  • 缺点

- 需要修改以太网驱动程序。

  • 优化原则

  1. 跳过TCP/IP协议,即屏蔽netif_*接口
  2. 发送接收使用轮询,屏蔽中断
  3. 重复利用套接字缓冲区,原协议栈每发送接收一个包都要分配和释放套接字缓冲区
  • 技巧

1. 获取网卡驱动源码

可以在linux源码中找到网卡驱动源码,比如我用的是创龙A40i核心板,全志A40i芯片,所以在linux-3.10/drivers/net/ethernet/allwinner目录下看到sunxi-gmac.c(1000兆网卡)和sun4i-emac.c(100兆网卡)。

2. 参考igh ethercat修改的网卡驱动

在ethercat/devices目录下,*-ethercat.c就是基于*-orig.c修改后的代码,比如r8169-3.10-ethercat.c就是基于r8169-3.10-orig.c修改后的代码,所以比较这两个文件,就知道修改了啥。

3. 参考igh ethercat官方文档

《igh-ethercat-1.5.2.pdf》的Ethernet Devices章节,4.7 Patching Native Network Drivers小节。

4. 屏蔽自动加载网卡驱动

修改内核编译选项,屏蔽自动加载网卡驱动

5. 了解Linux网卡驱动框架及DMA

可以自己查阅了解一下Linux网卡驱动,随便找一篇,大概了解框架就好,DMA也是。

我也是因为优化EtherCAT网卡驱动,第一次接触网卡驱动。

网卡驱动参考:http://t.csdnimg.cn/ML7id

DMA参考:https://blog.csdn.net/qq_41683305/article/details/124926572

修改详细说明

1)修改或添加的全部文件

2)获取1000兆网卡驱动源码

把linux-3.10/drivers/net/ethernet/allwinner目录的sunxi_gmac_ops.c,sunxi-gmac.c,sunxi-gmac.h复制到ethercat/devices目录下。

sunxi_gmac_ops.c文件名改为sunxi_gmac_ops-3.10.c;

sunxi-gmac.c复制两份,分别改为sunxi-gmac-3.10-ethercat.c和sunxi-gmac-3.10-orig.c;

sunxi-gmac.h复制两份,分别改为sunxi-gmac-3.10-ethercat.h和sunxi-gmac-3.10-orig.h;

说明:3.10为linux内核版本号

  1. 修改编译脚本
  • 修改ethercat/configure.ac

添加编译sunxi-gmac选项,在./configure时可以使用 --enable-sunxi-gmac=yes编译sunxi-gmac,在676行添加以下代码:

#------------------------------------------------------------------------------
# ec-sunxi-gmac driver
#------------------------------------------------------------------------------

AC_ARG_ENABLE([sunxi-gmac],
    AS_HELP_STRING([--enable-sunxi-gmac],
                   [Enable sunxi-gmac driver]),
    [
        case "${enableval}" in
            yes) enable_sunxi_gmac=1
                ;;
            no) enable_sunxi_gmac=0
                ;;
            *) AC_MSG_ERROR([Invalid value for --enable-sunxi-gmac])
                ;;
        esac
    ],
    [enable_sunxi_gmac=0] # disabled by default
)

AM_CONDITIONAL(ENABLE_SUNXI_GMAC, test "x$enable_sunxi_gmac" = "x1")
AC_SUBST(ENABLE_SUNXI_GMAC,[$enable_sunxi_gmac])

AC_ARG_WITH([sunxi-gmac-kernel],
    AC_HELP_STRING(
        [--with-sunxi-gmac-kernel=<X.Y.Z>],
        [sunxi-gmac kernel (only if differing)]
    ),
    [
        kernel_sunxi_gmac=[$withval]
    ],
    [
        kernel_sunxi_gmac=$linuxversion
    ]
)

if test "x${enable_sunxi_gmac}" = "x1"; then
    AC_MSG_CHECKING([for kernel for sunxi-gmac driver])

    kernels=`ls -1 ${srcdir}/devices/ | grep -oE "^sunxi-gmac-.*-" | cut -d "-" -f 3 | uniq`
    found=0
    for k in $kernels; do
        if test "$kernel_sunxi_gmac" = "$k"; then
            found=1
        fi
    done
    if test $found -ne 1; then
        AC_MSG_ERROR([kernel $kernel_sunxi_gmac not available for sunxi-gmac driver!])
    fi

    AC_MSG_RESULT([$kernel_sunxi_gmac])
fi

AC_SUBST(KERNEL_SUNXI_GMAC,[$kernel_sunxi_gmac])

比较如下:

3)修改ethercat/devices/Kbuild.in

添加编译的模块

比较如下:

4)修改ethercat/devices/Makefile.am

比较如下:

5)修改网卡驱动sunxi-gmac-3.10-ethercat.c
  1. 跳过TCP/IP协议,即屏蔽netif_*接口
  2. 发送接收使用轮询,屏蔽中断
  3. 重复利用套接字缓冲区,原协议栈每发送接收一个包都要分配和释放套接字缓冲区

(1)添加头文件

#include "../globals.h"

#include "ecdev.h"

(2)struct geth_priv私有结构体添加ec_device_t

(3)屏蔽netif_*和napi_*接口

netif_*是TCP/IP协议栈相关接口。

在代码中查找netif_,根据场景,屏蔽掉大部分的调用

NPAPI是一种硬中断触发+ Polling轮询收包机制。

屏蔽napi_enable,napi_disable,napi_gro_receive接口。

在geth_rx函数中,通过napi_gro_receive将 sk_buff 交付上层网络栈,但是我们不需要,所以屏蔽掉,调用igh提供的ecdev_receive接口。

重点说明:如果需要使用单缓存映射dma_map_single来访问DMA传输之间的数据,则必须以适当的方式在每次传输之间同步缓冲区,如果CPU需要访问缓冲区,可以通过dma_sync_sg_for_cpu()进行同步,如果设备需要,则调用dma_sync_sg_for_device()进行同步。

(4)屏蔽中断

在geth_probe函数中,把请求中断request_irq移到ecdev_open之后。

删除请求中断request_irq

调用ecdev_open函数,并屏蔽中断

(5)发送不释放skb_buff

因为发送由ethercat主站分配固定的skb_buff,循环利用,减少buff申请和释放时间。

geth_tx_complete函数:发送完成后不用释放skb_buff。

geth_xmit函数:发送失败不释放skb_buff,由ecrt_master_send函数最终调用。

(6)添加接收处理函数

ec_poll函数由ecrt_master_receive函数最终调用。

编译

编译成功后,在ethercat/devices目录下看到ec_sunxi_gmac.ko,拷贝到目标板上,执行以下命令加载ko:

insmod /lib/modules/ec_master.ko main_devices=00:00:00:00:00:00

insmod /lib/modules/ec_sunxi_gmac.ko

加载后通过lsmod查看:

  • 优化后对比

1.关闭中断

可以通过cat /proc/interrupts命令才看前后中断号

优化前截图

优化后截图

2.扫描总线时间

优化前扫描时间大概为130ms

优化后扫描时间大概为80ms

优化前截图

优化后截图

3.执行时间

优化前

开始最大执行时间为143us,半个小时后,最大执行时间为200us,平均为100us

优化后

开始最大执行时间为105us,半个小时后,最大执行时间为113us,平均为75us

优化前截图

开始截图

半小时后截图

优化后截图

开始截图

半小时后截图

三.总结

跟通用模式的网卡驱动相对,优化后的网卡驱动实时性比较好,系统占用资源也少,因为跳过TCP/IP协议,屏蔽网卡中断,减少套接字缓冲区的分配和释放。

重点说明:如果需要使用单缓存映射dma_map_single来访问DMA传输之间的数据,则必须以适当的方式在每次传输之间同步缓冲区,如果CPU需要访问缓冲区,可以通过dma_sync_sg_for_cpu()进行同步,如果设备需要,则调用dma_sync_sg_for_device()进行同步。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
支持EtherCAT网卡是一种专门用于工业领域的网络适配器。EtherCAT是一种高性能实时以太网通信协议,广泛应用于工业自动化控制系统中。 支持EtherCAT网卡具有以下特点和优势: 1.高实时性:EtherCAT网卡能够实时传输大量的数据,并且具有低延迟和高精度的特点。这使得它适用于对实时性要求较高的工业应用场景,如工业控制、机器人控制等。 2.高性能:EtherCAT网卡采用了高效的数据传输机制,能够实现对多个从站设备的同时控制和监控。它能够在一个EtherCAT网络中连接多种不同类型的设备,并且能够支持大规模的设备数量。 3.灵活性:EtherCAT网卡采用分布式控制的方式,可以通过简单的网络拓扑结构来连接并控制多个从站设备。这种结构可以大大降低系统的复杂性,并且方便进行系统扩展和设备的添加。 4.易于集成:支持EtherCAT网卡通常具备标准的以太网接口,可以与现有的以太网设备进行兼容。它还能够通过EtherCAT主站与其他设备进行通信,并且能够充分利用以太网的通信协议和设备驱动程序。 总而言之,支持EtherCAT网卡在工业领域有着广泛的应用前景。它的高实时性、高性能、灵活性和易于集成等特点,使得它成为工业自动化系统中不可或缺的重要组成部分。它不仅可以提高工业控制系统的精度和效率,还能够降低系统的成本和复杂性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值