STM32MP157驱动开发——Linux 网络设备驱动
- 一、简介
- STM32MP1 GMAC 接口简介
- YT8511C 详解
- 二、驱动开发
- 1.网络外设的设备树
- 2.设备驱动
- 三、测试
- 网速测试
参考文章:【正点原子】I.MX6U嵌入式Linux驱动开发——Linux 网络驱动
一、简介
网络驱动是 linux 驱动三巨头之一,linux 下的网络功能非常强大,嵌入式 linux 中也常常用到网络功能。本节就学习一下最后一种驱动大类的开发。
随着技术的不断发展,现在只需要一个芯片就可以实现有线网卡功能。但也有一些 SoC 没有内部 MAC,那么也可以使用外置 MAC 芯片的方案。首先,嵌入式网络硬件分为两部分:MAC 和 PHY,MAC 是类似 I2C 控制器、SPI 控制器一样的外设,但是光有 MAC 还不能直接驱动网络,还需要另外一个芯片:PHY,因此对于内置 MAC 的 SoC,其外部必须搭配一个 PHY 芯片。
也有一些 SoC 没有内部 MAC,那么就由外置 MAC 对 SoC 提供了一个 SRAM 接口,SoC 会以 SRAM 的方式操作 MAC 芯片。有些外置的网络芯片更强大,内部甚至集成了硬件 TCP/IP 协议栈,对外提供一个 SPI 接口,比如 W5500。这个一般用于单片机领域,单片机通过 SPI 接口与 W5500 进行通信,直接通过 SPI来操作 W5500,简化了单片机联网方案。这种方案的缺点是网络效率不高,因为一般芯片内置的 MAC 会有网络加速引擎,比如网络专用 DMA,网络处理效率会很高。另外相比较PHY 芯片,这类芯片的成本较高。
常见的通用 SoC 都会集成网络 MAC 外设,比如 STM32F4/F7/H7 系列、NXP 的 I.MX系列以及 STM32MP1 系列,内部集成网络 MAC 的优点如下:
- 内部 MAC 外设会有专用的加速模块,比如专用的 DMA,加速网速数据的处理
- 网速快,可以支持 10/100/1000M 网速
- 外接 PHY 可选择性多,成本低
内部的 MAC 外设会通过相应的接口来连接外部 PHY 芯片,根据数据传输模式不同,大致可以分为以下两类:
- 1.MII/RMII 接口:支持 10Mbit/s 和 100Mbit/s 数据传输模式
- 2.GMII/RGMII 接口:支持 10Mbit/s、100Mbit/s 以及 1000Mbit/s 数据传输模式。
另外主控 SoC 需要配置或读取 PHY 芯片,也就是读写 PHY 的内部寄存器,所以还需要一个控制接口,叫做 MIDO,MDIO 很类似 IIC,也是两根线,一根数据线叫做 MDIO,一根时钟线叫做 MDC。
在做项目时,如果需要用到网络功能,强烈建议选择内部带有网络 MAC 外设的主控 SoC,综合成本、网络传输速率、以及接口开发的效率来看,这种方式更加便捷。
有关 MII/RMII、GMII/RGMII 接口的介绍,就参考原子哥教程或是其他教程进行了解,这里就先略过。
STM32MP1 GMAC 接口简介
STM32MP1 内核集成了一个 10M/100M/1000M 的网络 MAC,支持双工或者半双工模式下运行。MAC 可编程,有直接存储器接口的专用 DMA,介质访问控制器(MAC)和支持多种格式的 PHY 接口模块。主要特性如下:
① 支持全工和半双工操作。
② 全双工流控制操作(IEEE 802.3X 暂停包和优先级流控制)
③ 报头和帧起始数据(SFD)在发送模式下自动插入、在接收中自动删除
④ 可逐帧控制 CRC 和 pad 自动生成
⑤ 可编程数据包长度,支持标准以太网数据包或高达 16KB 的巨型以太网数据包
⑥ 可编程数据包间隙
⑦ 两组 FIFO:一个具有可编程阈值功能的 4096 字节发送 FIFO 和一个具有可配置阈值功能的 4096 字节接收 FIFO
YT8511C 详解
笔者所使用的开发板上,使用的是 YT8511C 这颗 PHY 芯片。YT8511 通过 PHYADDR[2:0] 这三个引脚来确定 PHY 芯片地址,其中 PHYADDR2~PHYADDR0 分别对应 LED_AC、RXD1 和 RXD0 这三个引脚:
开发板上 YT8511 的地址为 0X00。低功率模式是由 RXD3 引脚控制。RXD3 为低电平时 YT8511C 进入低功率模式,RXD3 为高电平时 YT8511C 芯片就为正常功率模式。板子上的 RXD3 引脚直接连接了高电平,所以为正常模式。
LED_1000 引脚用来控制工作模式。LED_1000 为低电平就进入测试模式,为高电平就是正常模式。默认正常模式。
网络工作的时候需要和 PHY 之间有一个 125MHz 的时钟,由 YT8511C 提供这个 125MHz 的时钟。但是默认情况下,YT8511C 这个 125MHz 时钟没有使能,所以需要配置寄存器。需要用到 YT8511C 的时钟控制寄存器,这是个扩展寄存器,地址为 0X0C,时钟控制寄存器的 bit2 和 bit1 用于设置时钟输入,当 bit2:1 为 11 的时候,输出 125M 时钟。
二、驱动开发
原理图:
1.网络外设的设备树
STM32MP1 系列 SoC 网络绑定文档为 Documentation/devicetree/bindings/net/stm32-dwmac.txt,描述了 STM32MP1 系列的 SoC 网络设备树节点的要求。此外,还有一个 Documentation/devicetree/bindings/net/ethernet.txt 文档,描述了网络设备节点的一些通用属性。
在 arch/arm/boot/dts/stm32mp152.dtsi 设备树文件中,定义了一个网络设备节点。根据其 compitable 属性值,就能找到 drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c 驱动文件。不过此驱动由 ST 官方编写,不能直接使用。在正点原子的设备树文件 stm32mp157d-atk.dtsi 中,追加了一个 ethernet0 节点:
①phy-mode:该属性值是一个字符串,表示网络所使用的 PHY 接口模式,是 MII、RMII、GMII 还是 RGMII 等,是一个标准的属性,支持的字符串值有‘mii’、‘gmii’、‘sgmii’、‘rmii’、‘rgmii’、‘rgmii-id’、‘rgmii-rxid’、‘rgmii-txid’、‘xgmii’等等。rgmii-id’表示使用的是 RGMII 接口模式。
②max-speed:PHY 支持的最高速度,比如 10、100 或 1000。
③phy-handle:连接到此网络设备的 PHY 芯片句柄。
④mdio:用于描述 MDIO 总线,其中的 reg 属性表示 PHY 芯片的地址。
2.设备驱动
YT8511 芯片为国产的网络芯片,在 Linux 内核没有对应的 PHY 驱动,但是厂家会提供 linux 下的 PHY 驱动。此外原厂驱动有点小问题,没有使能 YT8511 的 125M 时钟输出,导致驱动工作不正常(旧版本,新版是否修复尚未查证),所以就将原子哥提供的修改好的文件进行拷贝。将 motorcomm.c 和 motorcomm_phy.h 分别拷贝到 Linux 源码下的 drivers/net/phy 和 include/linux 目录下,然后在 drivers/net/phy/Makefile 文件中添加如下语句:
obj-$(CONFIG_MOTORCOMM_PHY) += motorcomm.o
此语句将驱动添加到内核进行编译,最后还要修改 Kconfig,在 drivers/net/phy/Kconfig 文件中添加如下语句:
这样就可以通过 menuconfig 图形化界面来使能或禁止驱动了。
然后就可以重新编译出内核镜像,启动开发板。
三、测试
开发板启动时终端会打印以上信息。由于笔者路由器限制,所以只显示是百兆以太网。
网速测试
首先使能 iperf3 命令,在 buildroot 的 menuconfig 中,选中以下选项:
修改后编译出根文件系统,启动开发板。
然后在 ubuntu 下安装 iperf3 工具:
sudo apt-get install iperf3
将 ubuntu 作为 iperf3 的服务器,开发板作为客户端,并进行测试。
ubuntu下执行:
iperf3 -s
开发板下执行:
iperf3 -c [server_ip]
就可以测试出带宽。(笔者受限于路由器的带宽速度,正常情况应该是千兆带宽。也可以通过直连ubuntu和开发板进行测试。)