RTL8201 以太网PHY芯片 调试记录
一、概述
为了尽量给甲方降低成本,决定使用较低成本的PHY芯片RTL8201F-VB-CG芯片。移植官网的以太网demo程序,git上下载了一份很好看的rtl8201F的驱动程序,用来替换官方demo的lan8742程序。并没有直接通,于是开始了调试之路。
二、平台
芯片型号:stm32h753
官网例程文件名:STM32Cube_FW_H7_V1.10.0
三、原理图

四、遇到的问题
使用官网lwip的demo,下载RTL8201F-VB-CG驱动程序并替换lan8742驱动芯片程序,使用PC机ping设备ping不通
五、调试过程
1.确定PHY驱动芯片的寄存器可以读取和写入。
通过函数接口HAL_ETH_ReadPHYRegister和HAL_ETH_WritePHYRegister进行读写。这里我是可以直接正常读写的,所以并没遇到太大阻力。但我还是请教了一下其他朋友,了解到PHY寄存器的读写依靠22,23引脚。22引脚为时钟线,测量波形约2M左右,没记错的话。
2.深入调试了STM32对于以太网的初始化程序
主要是HAL_ETH_Init函数,先上代码。
HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
{uint32_t tickstart;if (heth == NULL){return HAL_ERROR;}if (heth->gState == HAL_ETH_STATE_RESET){heth->gState = HAL_ETH_STATE_BUSY;#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1)ETH_InitCallbacksToDefault(heth);if (heth->MspInitCallback == NULL){heth->MspInitCallback = HAL_ETH_MspInit;}/* Init the low level hardware */heth->MspInitCallback(heth);
#else/* Init the low level hardware : GPIO, CLOCK, NVIC. */HAL_ETH_MspInit(heth);#endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */}__HAL_RCC_SYSCFG_CLK_ENABLE();if (heth->Init.MediaInterface == HAL_ETH_MII_MODE){HAL_SYSCFG_ETHInterfaceSelect(SYSCFG_ETH_MII);}else{HAL_SYSCFG_ETHInterfaceSelect(SYSCFG_ETH_RMII);}/* Dummy read to sync with ETH */(void)SYSCFG->PMCR;/* Ethernet Software reset *//* Set the SWR bit: resets all MAC subsystem internal registers and logic *//* After reset all the registers holds their respective reset values */SET_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR);/* Get tick */tickstart = HAL_GetTick();/* Wait for software reset */while (READ_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR) > 0U){if (((HAL_GetTick() - tickstart) > ETH_SWRESET_TIMEOUT)){/* Set Error Code */heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT;/* Set State as Error */heth->gState = HAL_ETH_STATE_ERROR;/* Return Error */return HAL_ERROR;}}/*------------------ MDIO CSR Clock Range Configuration --------------------*/HAL_ETH_SetMDIOClockRange(heth);/*------------------ MAC LPI 1US Tic Counter Configuration --------------------*/WRITE_REG(heth->Instance->MAC1USTCR, (((uint32_t)HAL_RCC_GetHCLKFreq() / ETH_MAC_US_TICK) - 1U));/*------------------ MAC, MTL and DMA default Configuration ----------------*/ETH_MACDMAConfig(heth);/* SET DSL to 64 bit */MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_DSL, ETH_DMACCR_DSL_64BIT);/* Set Receive Buffers Length (must be a multiple of 4) */if ((heth->Init.RxBuffLen % 0x4U) != 0x0U){/* Set Error Code */heth->ErrorCode = HAL_ETH_ERROR_PARAM;/* Set State as Error */heth->gState = HAL_ETH_STATE_ERROR;/* Return Error */return HAL_ERROR;}else{MODIFY_REG(heth->Instance->DMACRCR, ETH_DMACRCR_RBSZ, ((heth->Init.RxBuffLen) << 1));}/*------------------ DMA Tx Descriptors Configuration ----------------------*/ETH_DMATxDescListInit(heth);/*------------------ DMA Rx Descriptors Configuration ----------------------*/ETH_DMARxDescListInit(heth);/*--------------------- ETHERNET MAC Address Configuration ------------------*//* Set MAC addr bits 32 to 47 */heth->Instance->MACA0HR = (((uint32_t)(heth->Init.MACAddr[5]) << 8) | (uint32_t)heth->Init.MACAddr[4]);/* Set MAC addr bits 0 to 31 */heth->Instance->MACA0LR = (((uint32_t)(heth->Init.MACAddr[3]) << 24) | ((uint32_t)(heth->Init.MACAddr[2]) << 16) |((uint32_t)(heth->Init.MACAddr[1]) << 8) | (uint32_t)heth->Init.MACAddr[0]);heth->ErrorCode = HAL_ETH_ERROR_NONE;heth->gState = HAL_ETH_STATE_READY;return HAL_OK;
}
在该代码的这一段发现程序返回了错误。于是查找手册对比这个bit位的作用
while (READ_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR) > 0U){if (((HAL_GetTick() - tickstart) > ETH_SWRESET_TIMEOUT)){/* Set Error Code */heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT;/* Set State as Error */heth->gState = HAL_ETH_STATE_ERROR;/* Return Error */return HAL_ERROR;}}
3.获取手册上关于这个bit位的描述
手册上关于这个bit位的描述如下,我的理解是,芯片需要检查所有的时钟,在检测到时钟的情况下,会自动复位完成。

4.测量PHY芯片各个时钟线的状态
通过向朋友的学习,测量了PHY芯片15引脚的时序,因为使用RMII模式,所以该时钟引脚理论值约为50M。而我的这次调试,问题的根源也在这里。
在运行程序时,我测量了PHY芯片15引脚,发现该引脚有时钟输出,我就误认为这里的时钟没问题,后面总结过后,才发现是寄存器配置后,PHY芯片的时钟才开始输出。所以在测量时,最好是打断点进行调试,断点要打在HAL_ETH_Init初始化之前。
5.阅读PHY芯片手册,找到在HAL_ETH_Init初始化之前提供时钟的办法
通过查看PHY芯片的芯片手册,关于该芯片12引脚的描述如下,在该引脚拉低或者浮空(芯片内部默认接地)的情况下,15引脚会默认输出时钟信号

六、解决的办法
将12引脚的上拉电阻去掉。stm32h7检测到PHY芯片的时钟信号后,以太网驱动的初始化会正常进行。再ping设备,通了!!!
七、总结
关于这个问题,也是请教朋友的过程中,意外学习到,一般来说以太网的时钟信号应该由控制芯片来提供,在这里也就是该由stm32h7芯片来提供时钟。但是我在手册上并没有看到输出时钟的方法(或许我看漏了吧)。所以在初始化流程并没有正常的进行。
而原理图的来源,是我们硬件工程师从一款海思的产品上copy下来的,所以他认为没什么问题。可能Soc芯片都有以太网时钟信号输出的能力吧。
所以不同的平台,驱动方式会略有差异,但问题终归是解决了。
相关文章:
RTL8201 以太网PHY芯片 调试记录
一、概述 为了尽量给甲方降低成本,决定使用较低成本的PHY芯片RTL8201F-VB-CG芯片。移植官网的以太网demo程序,git上下载了一份很好看的rtl8201F的驱动程序,用来替换官方demo的lan8742程序。并没有直接通,于是开始了调试之路。 二…...
Java中Static关键字的五种用法详解
Static的五种用法大致如下: 修饰成员变量,使其成为类变量,也叫静态变量修饰成员方法,使其成为类方法修饰内部类,使其成为静态内部类静态代码块静态导包 直接一点,static关键字就是把属性和方法变为类相关&…...
WebSocket 测试工具
一、WebSocket 简介 WebSocket是一种在单个TCP连接上进行全双工通信的协议。 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直…...
低代码开发的未来~
IT 团队依靠笨重的软件开发流程和劳动密集型的手工编码来构建有形、可靠和现代应用程序的时代即将结束。随着新自动化技术的兴起、渴望创新的客户和最终用户的期望和需求迅速提高以及开发人员的短缺,软件行业被迫寻求替代方法,不仅提供服务和产品&#x…...
蓝桥杯真题——模拟灌溉系统
尽量每天都自己写一遍模板,记住模板就好写了 以下内容直接在模板内进行 基本任务:要求“模拟智能灌溉系统”能够实现土壤湿度测量、土壤湿度和时间显示、湿度阈值设 定及存储等基本功能。通过电位器 Rb2 输出电压信号,模拟湿度传感器输出信号…...
【数据结构】双向链表实现
Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员,2024届电子信息研究生 目录 一、什么是双向链表 二、双向链表的实现 一、什么是双向链表 双向链表也叫双链表,是链表的一种,它的每个数据节点中都有两个指针,分别指向直接后…...
无公网IP,SSH远程连接Linux CentOS服务器【内网穿透】
文章目录1. Linux CentOS安装cpolar2. 创建TCP隧道3. 随机地址公网远程连接4. 固定TCP地址5. 使用固定公网TCP地址SSH远程本次教程我们来实现如何在外公网环境下,SSH远程连接家里/公司的Linux CentOS服务器,无需公网IP,也不需要设置路由器。 …...
CentOS 7+Docker搭建rabbitMQ无法访问15672端口
CentOS 7Docker搭建rabbitMQ无法访问15672端口 1.我拉取的镜像自带管理UI界面 所以不可能是没有开启管理UI界面的原因 2.防火墙关闭状态 所以也不是防火墙的问题 3.在虚拟机本机localhost:15672也访问不了 4.端口监听是正常的 5.最后发现我容器内curl能够通,容…...
面试官:如何保证接口幂等性?一口气说了9种方法!
本文已经收录到Github仓库,该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点,欢迎star~ Github地址 大家好,我是大彬~ 今…...
蓝桥杯刷题冲刺 | 倒计时14天
作者:指针不指南吗 专栏:蓝桥杯倒计时冲刺 🐾马上就要蓝桥杯了,最后的这几天尤为重要,不可懈怠哦🐾 文章目录1.最长递增2.走迷宫3.解立方根4.回文特判5.修改数组1.最长递增 题目 链接: 最长递增…...
【数据结构】树的概念
Halo,这里是Ppeua。平时主要更新C语言,C,数据结构算法......感兴趣就关注我吧!你定不会失望。 🌈个人主页:主页链接 🌈算法专栏:专栏链接 我会一直往里填充内容哒! &…...
Qt Glog toStdWString转char* 中文乱码
#include <QTextCodec>void LogWriter::init(void) {InitGoogleLogging("ui-fundus");char log_path[256] {0};FLAGS_stderrthreshold GLOG_INFO; // INFO WARNING ERROR FATAL, 是输出到stderr(app Output/cli)的阀值FLAGS_alsologtostderr false; // 当这…...
基于线性Kalman观测器(LKF)的2、4、7自由度悬架主动控制合集
目录 前言 1. 1/4车悬架仿真分析 2. 1/2车悬架仿真分析 3. 整车车悬架仿真分析 3.1 KF观测状态 3.2性能指标 4 .KF调参总结 5.文章总结 前言 对于kalman的原理介绍在上篇文章中已经做了详尽剖析,本篇进行实战,将其应用于悬架系统,其实…...
第二章 作业(6789B)【编译原理】
第二章 作业【编译原理】前言推荐第二章 作业678911最后前言 以下内容源自《编译原理》 仅供学习交流使用 推荐 无 第二章 作业 6 6.令文法G6为 N→D|ND D→0|1|2|3|4|5|6|7|8|9 (1)G6的语言L(G6)是什么? (2)给出句子0127、34和568的最左推导和最右推导。 (…...
【java】连续最大和、统计回文
目录 1.连续最大和 2.统计回文 1.连续最大和 链接:连续最大和_牛客题霸_牛客网 (nowcoder.com) 描述:一个数组有 N 个元素,求连续子数组的最大和。 例如:[-1,2,1],和最大的连续子数组为[2,1],其和为 3 输…...
AI真的快让我们失业了,从ChatGPT到Midjourney
参考文章: https://mp.weixin.qq.com/s/3RdHPPhYgDfB6KY6Y9Sk2A跟AI有关的新闻,一个接着一个。前一天你还和往常一样进入梦乡,第二天醒来就能被新的AI新闻“炸弹”震得心惊。 以ChatGPT为代表的AI语言模型,以Midjourney为代表的…...
JVM学习 GC垃圾回收机制 (堆内存结构、GC分类、四大垃圾回收算法)
🤖 作者简介:努力的clz ,一个努力编程的菜鸟 🐣🐤🐥 👀 文章专栏:《JVM 学习笔记》 ,本专栏会专门记录博主在学习 JVM 中学习的知识点,以及遇到的问题。 …...
ChatGPT 有哪些神奇的使用方式?
ChatGPT在语言处理领域有着非常广泛的应用,可以用来进行语音识别、文本摘要、问答系统、机器翻译、智能客服、情感分析、智能写作等方面的应用。随着技术的不断发展和进步,ChatGPT在未来的应用场景和领域也将会有更加广泛的拓展和应用。ChatGPT可以应用于…...
【JavaEE】Java设计模式-单例模式(饿汉式与懒汉式)
目录 1.设计模式是啥? 2.单例模式 2.1什么是单例模式 2.2饿汉模式 2.3懒汉模式 3.懒汉模式与饿汉模式的区别 3.1.线程安全方面 3.2.资源加载和性能 4.如何保证懒汉模式的线程安全 1.设计模式是啥? 设计模式是前人经过总结,通过…...
(算法基础)朴素版Prim算法
适用情景在最小生成树问题当中,涉及到权重和最小值。并且这个图是稠密图(n^2 ~ m)的情形下时间复杂度O(N^2)算法解释先得知道一下什么是无向图的生成树,树总该知道的吧,生成树就是包含这个无向图中的n个点,并且有n-1条边ÿ…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...
渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...
