硬件设计采用RTL8211FS芯片,vitis默认的IWIP库不支持此芯片。

网口相关知识可以翻看前期文章

以太网PHY_MDIO通信(基于RTL8211)--FPGA学习笔记22-CSDN博客

以太网ARP协议——FPGA学习笔记23_fpga以太网学习-CSDN博客

以太网ICMP协议(ping指令)——FPGA学习笔记25_icmp报文 以太网类型-CSDN博客

以太网UDP协议栈实现(支持ARP、ICMP、UDP)--FPGA学习笔记26_description: 接收arp、icmp、udp三种以太网报文,并对相应的数据进行解析,输出给-CSDN博客

感谢小梅哥论坛大佬文章

【Zynq】【Lwip】解决频繁打印link up/down、绿灯不亮、自协商结束后插入网线无反应的问题
https://www.corecourse.cn/forum.php?mod=viewthread&tid=29789
(出处: 芯路恒电子技术论坛)
【Zynq】【Lwip】解决使用官方lwip模板时自动协商失败的问题
https://www.corecourse.cn/forum.php?mod=viewthread&tid=29166
(出处: 芯路恒电子技术论坛)
 

关于芯片兼容修改问题,重点关注以下函数

void init_emacps(xemacpsif_s *xemacps, struct netif *netif);

static u32_t get_Realtek_phy_speed(XEmacPs *xemacpsp, u32_t phy_addr)

LWIP环回代码简解:

1、板级前置初始化

为芯片分配MAC地址,可修改

初始化平台,关闭 I/D Cache、初始化 UART、注册中断控制器、映射 GEM 寄存器等(板级支持包干的事)。

2、协议栈内存 + 网络接口数据结构清零

把 lwIP 全局结构(内存池、定时器、PCB 链表等)全部清零,为后续添加网卡做准备。

3、向 lwIP 注册“唯一”的网卡

把前面得到的 MAC、IP、网关、子网掩码、GEM 基地址打包,创建一个 struct netif 实例 server_netif,并挂到 lwIP 全局链表。

让 lwIP 后续发送默认走这张网卡。

开启指定网口

4、定时器与中断

开启中断功能。使能 IRQ,GEM 接收完成中断、定时器中断等开始工作。

  • 后面主循环会周期性置位:

    • TcpFastTmrFlag = 1 每 250 ms(TCP 快速定时器)

    • TcpSlowTmrFlag = 1 每 500 ms(TCP 慢速定时器)
      这两标志在 xemacif_input() 内部由中断服务程序刷新。

5、DHCP而客户端

#if LWIP_DHCP==1

dhcp_start(echo_netif);
启动 DHCP 状态机,开始 Discover-Offer-Request-Ack 四步舞。

while((ip_addr == 0) && (dhcp_timoutcntr > 0))
主循环里不断调用 xemacif_input() 收包,让 DHCP 状态机跑起来;24×0.5 s = 12 s 超时。

超时仍未拿到地址就 fallback 到静态 192.168.1.10。

6、用户代码绑定

print_app_header() // 打印一条提示

start_application() // 创建 PCB、绑定端口、注册回调

transfer_data() // 周期发送或处理数据

一些函数详解:

void init_emacps(xemacpsif_s *xemacps, struct netif *netif);

Xilinx GEM(PS 端千兆以太网)在 lwIP 下的“一站式硬件启动器”,把 MAC 控制器、PHY、链路速率全部配置到可收发状态

1、拿到MAC控制器句柄

  • xemacps 是 Xilinx 驱动库 XEmacPs 的实例,后续所有寄存器操作都靠它。

2、打开巨型帧 / 组播选项(可选)

  • 巨型帧(9018 B)需要提前使能,否则硬件会截断。
  • 组播选项让 MAC 接受多播哈希表过滤,为 IGMP 服务。

3、把软件 MAC 地址写进硬件寄存器

  • 第 3 个参数 1 表示使用“地址槽 1”(0 留给特殊帧)。

  • 失败直接打印调试信息并继续往下走(后面还可改)。

4、配置 MDIO 时钟

  • 根据 CPU 频率把 MDC 降到 ≤2.5 MHz,满足 IEEE 802.3 要求。

5、探测并初始化 PHY

分两条路:

a) 板载 PCS/PMA 1000Base-X 或 SGMII 口
→ 直接调用 phy_setup_emacps(xemacpsp, 固定地址)
→ 地址由 xparameters.h 给出(例如 1 或 7)。

b) 标准 RGMII/MDIO 总线
detect_phy() 先把 0-31 号 PHY 扫一遍,把在位 PHY 记录到数组 phymapemac0/1[]
→ 然后对每一个在位地址调用 phy_setup_emacps(),完成:
- 软件复位
- 设置自动协商通告(10/100/1000)
- 等待协商完成
- 回传实际链路速率(10/100/1000 Mbps)

 先遍历 1–31 号地址里所有被标记为 TRUE 的 PHY,全部初始化;如果一个都没找到,就退而求其次用广播地址 0 再试一次。

执行完这段代码后:

  • phyaddrforemac 保存了实际使用的 PHY 地址;

  • link_speed 要么等于 10/100/1000,要么标记失败;

  • 后续 XEmacPs_SetOperatingSpeed() 就依据 link_speed 给 MAC 设速。

void detect_phy(XEmacPs *xemacpsp);

        在 MDIO 总线上把 0–31 号地址全部扫一遍,找到真正挂着的 PHY

        (1)先确定是 EMAC0 还是 EMAC1

  • Zynq/MP 有两路 GEM 控制器,函数根据基地址区分当前扫描的是哪一路,然后把结果写到 全局数组 phymapemac0[]phymapemac1[]

        (2)从 31 到 1 号地址倒序扫描

  • 地址 0 是广播地址,跳过;

  • 倒序可以避免某些交换芯片伪应答带来的误判。

        (3)读 “PHY ID 寄存器” 做存在性检测

        此处注意兼容,板载PHY是否为此寄存器地址。

  • PHY_DETECT_REG 通常是 寄存器 2(PHY Identifier 1)

  • 如果读到 0xFFFF,说明该地址没有芯片响应,直接跳过。

        (4)判断芯片是否真实存在

  • PHY_DETECT_MASK 把厂商 OUI 的固定位拉出来做匹配;

  • 满足条件就把 phymapemacX[phy_addr] = TRUE,后面 init_emacps() 会只对这些“真正在位”的地址进行初始化。

        (5)打印调试信息

  • 打开 LWIP_DEBUG 时会看到类似XEmacPs detect_phy: PHY detected at address 1.

        (6)进一步读寄存器 2 做厂商识别


 

  • 这一步只是提示如果 PHY 不是这三家,初始化脚本里对特殊寄存器的配置可能不适用,需要你自己确认。

        扫描结束后,phymapemac0[] / phymapemac1[] 里为 TRUE 的索引就是本总线上实际存在的 PHY 地址;init_emacps() 会遍历这些地址,分别调用 phy_setup_emacps() 完成真正的配置。

6、链路失败退出

  • 此时 MAC 仍处于复位态,lwIP 不会收到任何包。

7、把协商到的速率写回 MAC

  • 告诉 GEM 控制器当前是 10/100/1000 Mbps,内部会重新计算 MII/RGMII 时钟分频。

  • 后面紧跟一段空转延时,让硬件锁定时钟——经验值 20 000 空循环 ≈ 几十微秒。(该部分延时可适当加长)参考文章:

【Zynq】【Lwip】解决频繁打印link up/down、绿灯不亮、自协商结束后插入网线无反应的问题
 

8、全局链路状态变量供后续查询

  • xemacpsif_input() 里会定期查这个变量,发现掉线就丢弃收包,防止错误中断淹掉 CPU。

关于init_emacps()的调用:

init_emacps() 的调用路径只有一条,而且 完全藏在 Xilinx 的 lwIP 适配层内部,用户代码里根本看不到它的名字:

xemac_add()                                                              ← 用户唯一显式调用
 └─ netif_add(netif, ..., xemacpsif_init, ...)                 ← lwIP 标准 API
     └─ xemacpsif_init(netif)                                        ← 在 xemacpsif.c 里
         └─ init_emacps(netif)                                        ← 就在这里被调用

xemac_add() 只在 main() 里被用户显式调用一次;它的使命就是“把 MAC 地址、IP 地址、底层初始化函数挂到 lwIP 的 netif 链表”,成功后退出,后续数据收发不再经过它。

static u32_t get_IEEE_phy_speed(XEmacPs *xemacpsp, u32_t phy_addr)

get_IEEE_phy_speed() 是一个 “厂商识别 + 分发” 的派发函数,根据 PHY 芯片的厂商 ID,把速率解析工作转给对应的专用函数,返回 10/100/1000 或失败。

1、读取 寄存器 2(PHY Identifier 1) 的高 16 位,拿到 OUI 前缀。

  • 三家常量已定义:

    • PHY_TI_IDENTIFIER 0x2000

    • PHY_REALTEK_IDENTIFIER 0x001C

    • 其余默认走 Marvell 分支(0x0141 或其他)

此处注意兼容,以防进入错误分支

2、直接调用对应的厂商函数:

3、返回协商速率

关于static u32_t get_IEEE_phy_speed(XEmacPs *xemacpsp, u32_t phy_addr)的调用

get_IEEE_phy_speed() 只被 phy_setup_emacps() 调用一次,负责 “识别厂商 → 转交对应的寄存器解析函数 → 拿到链路速率”

main()
 └─ xemac_add()
     └─ xemacpsif_init()
         └─ init_emacps()
             └─ phy_setup_emacps()
                 └─ get_IEEE_phy_speed()   ← 这里

static u32_t get_Realtek_phy_speed(XEmacPs *xemacpsp, u32_t phy_addr)

这段代码就是 Realtek PHY 专用的速率获取函数 get_Realtek_phy_speed(),作用与之前的通用协商流程完全一致,只不过把“读速率”这一步固定到 Realtek 的 SPECIFIC_STATUS_REG(通常是 0x1A) 上。

  • get_IEEE_phy_speed() 调用,参数已确认 phy_identity == 0x001C(Realtek)。

  • MDIO 时钟已通过 XEmacPs_SetMdioDivisor() 降到 ≤2.5 MHz。

  • 函数运行在裸机,中断关闭,CPU 主频 666 MHz(Zynq-7000 典型值)。

1、读取并修改 10/100 通告寄存器(地址 0x04

  • MDIO 帧:Start (2b) + Op(2b) + PHYaddr(5b) + Reg(5b) + TA(2b) + 16-bit data

  • 实际总线波形 64 位,约 25 µs 完成。

  • 读回值假设为 0x01E1(出厂默认值)。

control |= IEEE_ASYMMETRIC_PAUSE_MASK   // bit11 = 1| IEEE_PAUSE_MASK              // bit10 = 1| ADVERTISE_100                // bit8  = 1| ADVERTISE_10;                // bit7  = 1
  • 新值 0x05E1 → 表示“本端支持 10/100 全双工 + 对称/非对称流控”。

  • 再次产生 MDIO 写帧,PHY 内部立即更新通告寄存器。

2 、读取并修改 1000 M 通告寄存器(地址 0x09

写入数据0000 0011 0000 0000

  • 读回 0x0000(Realtek RTL8211 默认未设 1000 M 通告)。

control |= ADVERTISE_1000;   // bit9 = 1
  • 新值 0x0200 → 表示“本端支持 1000 M 全双工”。(实际代码为0x0300,可以兼容YT8531)

  • 写入完成,PHY 内部把 1000 M 能力加入下次自协商 FLP 脉冲。

3、重启自协商 + 软复位

XEmacPs_PhyRead(xemacpsp, phy_addr, 0x00, &control);
control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE  // bit12 = 1| IEEE_STAT_AUTONEGOTIATE_RESTART // bit9  = 1
  • 新值 0x1200(保持之前设置的 0x1200,再置 bit9)

  • 写完后 PHY 立即发出携带新通告的 Fast Link Pulse (FLP) 序列,链路伙伴开始协商。

  • 软复位:PHY 内部状态机回到初始态,寄存器除 0x00 外全部恢复默认值,但 0x04/0x09 的通告值已被锁存,复位后仍保留。

  • 复位期间 bit15 保持 1,典型耗时 < 100 µs(RTL8211 数据手册标称 60 µs)。

4、轮询等待复位完成

5、等待自协商完成(最耗时)

  • 初始 status 读回 0x7849(bit5 = 0,协商未完成)。

while (!(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE)) {  // bit5sleep(1);            // 裸机 sleep(1) ≈ 1 stimeout_counter++;if (timeout_counter == 30) return XST_FAILURE;XEmacPs_PhyRead(xemacpsp, 0x01, &status);
}

  • 最坏情况 30 s 后超时退出;正常千兆对千兆 1–2 s 内 bit5 置 1

  • 串口每秒打印一次 “Waiting for PHY to complete autonegotiation.”

  • 成功后打印 “autonegotiation complete”。

6、读取 Realtek 专用速率寄存器(注意兼容问题

  • 按位掩码比对,立即得到整数速率。注意兼容问题。

  • 若 resolved 位未置 1,说明协商失败,走 return XST_FAILURE;

get_Realtek_phy_speed() 就是 “把 Realtek PHY 的寄存器按官方顺序撸一遍,直到 0x1A 的 resolved 位拉起来,再把 bit14:13 翻译成 Mbps

关于get_Realtek_phy_speed() 的调用

在static u32_t get_IEEE_phy_speed(XEmacPs *xemacpsp, u32_t phy_addr)中调用,其他厂商配置代码类似。

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

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

相关文章

《Science》神经炎症综述思路套用:从机制到跨领域研究范式

2025 年 6 月首都医科大学团队在《Science》发表的综述《Immunological dimensions of neurological disease: from mechanisms to therapeutics》(神经疾病的免疫维度:从机制到疗法),系统性解析了神经炎症的动态演变规律与双面性,提出阶段化、精准化治疗新范式。本文基于…

嵌入式学习笔记--Linux系统编程阶段--DAY07进程间通信--存储映射和共享内存

1.存储映射存储映射 I/O (Memory-mapped I/O) 使一个磁盘文件与存储空间中的一个缓冲区相映射。于是当从缓冲区中取数据&#xff0c;就相当于读文件中的相应字节。于此类似&#xff0c;将数据存入缓冲区&#xff0c;则相应的字节就自动写入文件。这样&#xff0c;就可在不适用 …

.Net程序员就业现状以及学习路线图(四)

一、.Net程序员就业现状分析 1. 市场需求与岗位分布 2025年数据显示&#xff0c;.Net开发岗位在全国IT岗位中占比约0.009%&#xff0c;主要集中在一线城市如深圳、上海等地 2 4。行业分布呈现以下特点&#xff1a;‌软件行业‌&#xff1a;占比43.3% ‌研发领域‌&#xff1a;占…

Monorepo 是什么?如何使用并写自己的第三方库

1. 什么是 Monorepo&#xff1f; Monorepo&#xff08;单仓库&#xff09;指的是把多个项目/包放在一个代码仓库里统一管理。常见结构&#xff1a; /repo-root/packages/ui-lib/utils/apps/web-apppackage.jsonpnpm-workspace.yaml好处&#xff1a; 内部库能直接共享&#xff0…

使用CI/CD部署后端项目(gin)

写在前面&#xff1a;使用CI/CD部署gin项目到服务器中 前端可以参考&#xff1a;使用CI/CD部署nextjs项目 使用 GitHub Actions 配置后端 CI/CD&#xff08;含部署到服务器&#xff09; 本文档介绍如何在 GitHub 仓库中配置 CI/CD&#xff0c;将 PROJECT_NAME 项目自动构建并…

Coze添加知识库解析的Embedding和PaddleOCR模型配置

1. Embedding模型配置 使用ollama模型&#xff0c;导入qwen3的embedding-8B模型&#xff0c;导入流程参考&#xff1a; Ollama离线部署模型 qwen3-Embedding模型文件可从魔塔社区下载&#xff1a; Qwen3-Embedding-8B 1.2 Coze配置 在coze_studio/docker目录下输入: vim .en…

02-Media-6-rtsp_server.py 使用RTSP服务器流式传输H264和H265编码视频和音频的示例程序

rtsp_server.py 是使用k230的板载摄像头和WIFI联网功能,使用RTSP服务器流式传输视频和音频的程序示例。程序核心是创建了一个RtspServer类,该类用于初始化、启动、停止RTSP服务器,并进行视频和音频的流传输。 一、首先,程序导入必要的模块,包括视频编码、传感器、媒体处理…

13-Java-面向对象-封装和this关键字

文章目录封装this关键字封装 告诉我们&#xff0c;如何正确设计对象的属性和方法。原则&#xff1a;对象代表什么&#xff0c;就得封装对应的数据&#xff0c;并提供数据对应的行为 package common;/*** Author: 大海* Date: 2025-09-06*/public class GirlFriend {/*private…

三高项目-缓存设计

三高项目-缓存设计 分流、并发 导流&#xff1a;将原本复杂操作的请求&#xff0c;引导到简单的操作上。以后再来查&#xff0c;不需要经过复杂的计算。 成本&#xff1a;空间&#xff0c;收益&#xff1a;节省了时间。 不要以为仅仅是 redis&#xff0c;map等。 对应。kv…

happen-before原则

什么是 happen-before 原则&#xff1f; happen-before 是一个逻辑关系&#xff0c;用于描述两个操作之间的 “先后顺序”—— 如果操作 A happen-before 操作 B&#xff0c;那么 A 的执行结果必须对 B 可见&#xff0c;且 A 的执行顺序在逻辑上先于 B。也就是保证指令有序性和…

4.1 机器学习 - 评估指标

模型评估是判断 “模型是否有效” 的核心环节&#xff0c;需结合任务类型&#xff08;分类 / 回归&#xff09;、数据分布&#xff08;如类别不平衡&#xff09;和商业目标选择指标。本节聚焦分类任务的核心评估指标&#xff0c;从定义、计算逻辑到适用场景逐一拆解&#xff0c…

雅菲奥朗SRE知识墙分享(七):『可观测性的定义与实践』

在分布式系统日益复杂的当下&#xff0c;故障不再是“是否发生”&#xff0c;而是“何时爆发”。SRE可观测性正是应对不确定性的“显微镜”与“导航仪”&#xff1a;通过指标、日志、追踪三大数据血脉&#xff0c;实时外化系统黑盒&#xff0c;让每一次抖动、每一行报错、每一次…

C++ 详细讲解vector类

目录 1. 什么是vector? 2. vector的使用 1. 构造函数---初始化 1. 默认构造函数(无参构造&#xff09; 2. 填充构造函数(指定数量和初始值&#xff09; 3. 范围构造函数(通过迭代器拷贝其他容器元素&#xff09; 4. 拷贝构造函数(直接拷贝另一个vector&#xff09; 注…

Windows Server2012 R2 安装.NET Framework 3.5

Windows Server2012 R2 安装.NET Framework 3.5 虚拟机系统是Windowsserver 2012R2&#xff0c;在安装SQlserver2012时候警告未安装.NET Framework 3.5。于是找了个.NET Framework 3.5的安装包&#xff0c;但是由于系统原因无法正常安装。按照提示从控制面板-程序-启动或关闭Wi…

IDEA中Transaction翻译插件无法使用,重新配置Transaction插件方法

原因 由于Transaction默认的翻译引擎为谷歌翻译&#xff0c;由于一些原因&#xff0c;这个翻译无法使用&#xff0c;因此导致插件无法使用。 解决办法 更换Transaction插件翻译引擎即可。 方法步骤 1.进入Idea的设置里&#xff0c;找到Tool下的Transaction选项2.更改翻译引擎&a…

外置flash提示音打包脚本

批处理脚本说明文档 - 音频资源打包与分发 一、脚本功能概述 本批处理脚本&#xff08;.bat 文件&#xff09;用于将指定目录下的多个音频文件&#xff08;.wtg 和 .mp3 格式&#xff09;打包为音频资源配置文件&#xff08;tone.cfg&#xff09;&#xff0c;进一步将配置文件与…

Go语言设计模式(三)抽象工厂模式

抽象工厂模式与工厂模式类似,被认为是工厂方法模式的另一层抽象.抽象工厂模式围绕创建其他工厂的超级工厂工作.1.角色:1.1抽象产品:构成产品系列的一组不同但相关的产品的声明接口.1.2具体产品:实现抽象产品接口的类,主要用于定义产品对象,由相应的具体工厂创建.1.3抽象工厂:创…

大狗王 DG1+ 13.6G矿机详细参数解析与性能评测

近年来&#xff0c;随着加密货币挖矿行业的不断发展&#xff0c;越来越多的矿机厂商推出了高性能、低功耗的矿机设备。大狗王&#xff08;DG1&#xff09;13.6G矿机便是其中一款备受关注的设备&#xff0c;特别是在LTC&#xff08;莱特币&#xff09;、Doge&#xff08;狗狗币&…

Python 算术运算练习题

计算数字特征值题目描述 编写一个程序&#xff0c;接收用户输入的两个整数 a 和 b&#xff08;a > b > 0&#xff09;&#xff0c;计算并输出以下结果&#xff1a;a 与 b 的和的平方a 除以 b 的商和余数a 与 b 的平均数&#xff08;保留 2 位小数&#xff09;示例请输入整…

OS项目构建效能改进策划方案

一、现状分析与问题定位构建稳定性问题&#xff1a; 表现&#xff1a;非代码变更引发的构建失败&#xff08;如环境依赖、工具链版本、第三方库更新、资源竞争等&#xff09;“幽灵构建”时有发生。影响&#xff1a;严重破坏开发流程的顺畅性&#xff0c;耗费大量开发/测试人员…