如何学习zynq以太网控制器及协议栈
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何学习zynq以太网控制器及协议栈相关的知识,希望对你有一定的参考价值。
参考技术A说到学习ZYNQ+SOC+Linux开发,我认为主要应该细分为lian两大点:zynq,soc合为一个点,linux为一个点。下面我就给大家介绍学习的流程和路线。
一,学习zynq+soc的FPGA开发部分和片上ARM核的寄存器,裸奔应用开发,我推荐大家收阅读文档《ZYNQ+SOC修炼秘籍-最全面的pdf》,下面我给大家贴上下载地址。
CSDN下载链接:https://pan.baidu.com/s/1wjUXx5_l6EPE58UZwcnRZw
二,如果各位能按部就班的阅读并自己动手编写测试《ZYNQ+SOC修炼秘籍-最全面的pdf》里面的内容,我相信大家对于zynq的硬件部分已经足够了解,并且能够写出基于FPGA+ARM构架的裸奔程序应用了。
那么接下来,我们就应该学习管如何在zynq平台上搭建Linux操作系统了。
(1)u-boot的编译
我相信大家已经肯定在网上搜索理解了很多关于u-boot编译的资料,所以在此我给大家提供的shi是如何解决编译过程中遇到的一些问题,将自己在项目实践中的记录分享给大家,具体请参考《zynq-u-boot编译说明书》这个资料,下面为下载链接地址。
CSDN下载链接:https://pan.baidu.com/s/1Gqs3V3U6N6kW2AeJkMn-dA
(2)kernel的编译
众所周知,kernel为Linux的内核,这个是最最核心的部分,在此不做过多的赘述,给大家分享项目中的记录吧。具体参考《zynq-kernel编译说明书》这个资料。
CSDN下载链接:https://pan.baidu.com/s/1p1o_3dLZMxWubc-rXGLelw
(3)设备树的编译
不知道大家是否知道,Linux上的驱动是怎么和硬件挂钩的吗?没错,就是使用的设备树,话不多说,请参照《zynq设备树配置说明》这个资料,下面为下载链接地址。
CSDN下载链接:https://pan.baidu.com/s/102qqfR0OAhJvGW8h2PO1eg
(4)文件系统的搭载
在完成上述三步的操作之后,需要一个完整的Linux系统我们就还需要搭载上文件系统,国外很多人喜欢利用buildroot自己及定制文件系统,但是对于初学者我的建议是先使用已经完善的文件系统,具体的做法请参照《zynq文件系统挂载》这个资料,下面为下载链接地址。
CSDN下载链接:https://pan.baidu.com/s/1O10BNKid73fguDs4ZZDrXg
三,在完成了u-boot的编译,kernel的编译,设备树的编译,文件系统的编译挂载后,一个完整的Linux系统就搭建成功了。不过我相信在过程中肯定会遇到或多或少的各种各样的问题,在此本人为大家分享一些在过程中遇到的问题以及解决方法,水平有限望大神勿喷。
(1)在运行挂载文件系统的时候本人就曾经遇到,系统默认挂载的是ramdisk,所以无法挂载我搭建在SD卡上的ext4的文件系统,请参考《zynq不加载ramdisk的方法》资料里的解决方法,下面为资料xixi下载链接。
CSDN下载链接:https://pan.baidu.com/s/1ESMO4FtbykTzN-7nqZqvTg
(2)如何解决板子每次上电都动态分配ip,导致用户无法准确知道板子的ip呢?那就请参考《zynq_linux配置静态和动态ip的方法》这个资料里的内容,下面为下载链接。
CSDN下载链接:https://pan.baidu.com/s/1s4RduCWI2cVCrZqfxvJ9oA
(3)配置好静态ip后,那么肯定是kai'开始用用SSH连接板子,现在就让我们来解决SSH连接的问题,请参考《zynq上的SSH无法链接问题》这个资料里的内容,下面为下载链接。
CSDN下载链接:https://pan.baidu.com/s/1bzMbyBzbIG74ot9EymaAHw
(4)以上问题都解决了后,自然是想自己动手编写Linux下的驱动咯。只有有了驱动才能使得FPGA为Linux所用,那么接下来给大家分享几个编写Linux下的axi dma驱动的资料供大家参考。
《zynq字符设备驱动代码》
CSDN下载链接:https://pan.baidu.com/s/11kTG3LMHKdVyAOY_WzRBhA
《zynq_linux字符驱动之自动创建设备节点》
CSDN下载链接:https://pan.baidu.com/s/1TVDDxkk1KdDxcunXbfTdmg
《zynq上axi-dma作为字符设备的驱动代码》
CSDN下载链接:https://pan.baidu.com/s/1ZViLZ1EHWGcshYiaIcHTgw
《zynq_dma_device_tree说明文件》
CSDN下载链接:https://pan.baidu.com/s/14ulkwrGJjqk6IrU010qEsw
四,以上介绍大部分均为本人在学习,做项目时的总结,在此分享给大家,希望对广大的学习群体有所帮助,本人水平有限,在此希望各路大神们勿喷。接下来就靠大家自己努力加油了!
ZYNQ 系统的IEEE1588 实现方法
IEEE1588/PTP 协议是实时工业软件的一个重要的协议,本博文讨论该协议在Xilinx Zynq 系统·上如何实现IEEE1588 协议。
ZYNQ 系统的以太网
Zynq 系统中有两类Ethernet 接口,一种是PS 端的硬件千兆以太网,另一种是PL 实现的以太网接口。
PS 端以太网
zynq 中带有两个硬核千兆以太网MAC,ENET0,ENET1。与普通SOC 芯片不同,zynq PS 断地外设可以通过MIO连接到芯片的引脚上,也可以通过EMIO 接口连接到PL 端。连接到PL端后,带来了灵活性,可以转换成各种接口。比如设计一个交换机。定义端其它的引脚。
PS 端MIO 引出的以太网接口是RGMII接口,可以连接具有RGMII 的Phy 芯片。
PS 端的Ethernet 透过EMIO 连接各种接口(通过1000BASE-X/SGMII PCS/PMA IP)
PL 端以太网
PL 端的以太网是通过IP核实现的。vivado 中有下列几种以太网IP。
- tri mode Ethernet MAC
- AXI 1G/2.5G Ethernet Subsystem
- 100M/1G TSN Subsystem
其中
AXI 1G/2.5G Ethernet Subsystem 支持IEEE1588 ,但是只有在使用SGMII和SFP(small form factor pluggable)接口。并且带有GTX 功能的Zynq 芯片才支持IEEE1588。如此看来只能在光纤接口,或者SGMII接口上实现。网络上资料也不多。
小贴士
-----------------------------------------------------------------
GTX
GTX是一种就是G级速率以上的SERDES串行/解串器。Xilinx芯片里内嵌的串行/解串器GTX,GTH,GTP等模块。
7系列中,按支持的最高线速排序,GTP<GTX<GTH<GTZ。GTP被用于A7系列,GTZ被用于少数V7系列。从K7到V7,最常见的是GTX和GTH,GTH的最高线速比GTX稍微高一点点。
100M/1G TSN Subsystem 也支持IEEE1588 但是看上去也是比较复杂的样子。
SGMII
SGMII协议是CISCO公司提出来的,可以减少芯片间互联的管脚。传统的GMII前面说了是8bits数据线,此外还需要时钟,和一些控制线,双向加起来要20根线左右。而SGMII接口是1根数据线加1根时钟线,双向共4根。如果去掉时钟线(采用CDR),那么2根线就可以实现互联了。
SGMII本质上并没有对以太网协议的分层做改动,还是MAC层,PCS层和PMA层。原来GMII模式下,MAC层一般做在SOC侧,PHY层包括PCS+PMA做在另一个单独的芯片上。而SGMII的实施是将PCS层也同时放在了原来的MAC侧。这样SOC芯片和PHY芯片各有一个PCS层。
对于SOC发送来说,数据包有MAC层过来,经过tx 的pcs,从SGMII接口发送出去。在PHY芯片上,有一个rx的pcs先将SGMII的信号解出GMII信号,然后再经过传统的PHY层处理发送到介质上。对于SOC接收来说,则反过来。
-----------------------------------------------------------------
tri mode Ethernet MAC在100Mbps 时可以使用MAC 接口,可以通过一个MAC to RMII 的IP 转换成为RMII 接口。
IEEE1588/PTP实现方案
IEEE1588 的硬件实现的方法有两种:
- 在MAC控制器中实现
- 在Phy 芯片中实现,比较常见的有TI 公司的DP83640 芯片
ZYNQ 中实现IEEE1588 协议的方式
使用DP83640
使用DP83640 实现IEEE1588 协议相对比较简单。主要的问题是要通过RMII接口与DP83640 相连接。
Linux 下访问mdio 的方法。
测试程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/mii.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/sockios.h>
#include <linux/types.h>
#include <netinet/in.h>
#include <unistd.h>
//#include <QDebug>
int main(int argc, char *argv[])
int sockfd;
struct mii_ioctl_data *mii = NULL;
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, "eth0", IFNAMSIZ - 1);
sockfd = socket(PF_LOCAL, SOCK_DGRAM, 0);
ioctl(sockfd, SIOCGMIIPHY, &ifr);
mii = (struct mii_ioctl_data*)&ifr.ifr_data;
if(argc == 4)
strncpy(ifr.ifr_name, argv[1], IFNAMSIZ - 1);
sockfd = socket(PF_LOCAL, SOCK_DGRAM, 0);
ioctl(sockfd, SIOCGMIIPHY, &ifr);
mii = (struct mii_ioctl_data*)&ifr.ifr_data;
mii->phy_id = (uint16_t)strtoul(argv[2], NULL, 0);
mii->reg_num = (uint16_t)strtoul(argv[3], NULL, 0);
ioctl(sockfd, SIOCGMIIREG, &ifr);
printf("read --- value : 0x%x\\n", mii->val_out);
else if(argc == 5)
strncpy(ifr.ifr_name, argv[1], IFNAMSIZ - 1);
sockfd = socket(PF_LOCAL, SOCK_DGRAM, 0);
ioctl(sockfd, SIOCGMIIPHY, &ifr);
mii = (struct mii_ioctl_data*)&ifr.ifr_data;
mii->phy_id = (uint16_t)strtoul(argv[2], NULL, 0);
mii->reg_num = (uint16_t)strtoul(argv[3], NULL, 0);
mii->val_in = (uint16_t)strtoul(argv[4], NULL, 0);
ioctl(sockfd, SIOCSMIIREG, &ifr);
else
printf("mdio ethX phyId addr value\\n");
close(sockfd);
return 0;
我是在Z7 nano开发板的pynq 操作系统下调试通过的。
使用AXI 1G/2.5G Ethernet Subsystem
只有在使用SGMII和FDP接口。并且带有GTX 功能的Zynq 芯片才支持IEEE1588。
结束语
目前还只是一个方案,还没有具体编程和测试。敬请期待。
创作打卡挑战赛 赢取流量/现金/CSDN周边激励大奖以上是关于如何学习zynq以太网控制器及协议栈的主要内容,如果未能解决你的问题,请参考以下文章
STM32CubeMX学习笔记(41)——ETH接口+LwIP协议栈使用(DHCP)
STM32CubeMX学习笔记(41)——ETH接口+LwIP协议栈使用(DHCP)
STM32CubeMX学习笔记(42)——ETH接口+LwIP协议栈使用(静态IP)