当前位置: 首页 > news >正文

在RT-Thread下为MPU手搓以太网MAC驱动-4

文章目录

    • MAC驱动里面对MDIO的支持
    • MAC驱动与MDIO总线

这是个人驱动开发过程中做的一些记录,仅代表个人意见和理解,不喜勿喷

  • MAC驱动需要支持不同的PHY芯片

MAC驱动里面对MDIO的支持

在第一篇文章中提到对MAC设备做出了抽象,其中MAC抽象里面有提供通过MDIO总线去访问PHY寄存器的读写操作接口(有省去其他操作接口)

struct h3_macplib_ops
{int32_t  (*macdev_writephy)(mac_dev *const dev, uint16_t addr, uint16_t reg, uint16_t data);int32_t  (*macdev_readphy) (mac_dev *const dev, uint16_t addr, uint16_t reg, uint16_t *val);
};

那我们同时也需要实现一个MDIO设备驱动,因为在RT-Thread下也有定义MDIO相关的操作接口。

struct rt_mdio_bus_ops
{rt_bool_t (*init)(void *bus, rt_uint32_t src_clock_hz);rt_size_t (*read)(void *bus, rt_uint32_t addr, rt_uint32_t reg, void *data, rt_uint32_t size);rt_size_t (*write)(void *bus, rt_uint32_t addr, rt_uint32_t reg, void *data, rt_uint32_t size);rt_bool_t (*uninit)(void *bus);
};struct rt_mdio_bus
{void *hw_obj;char *name;struct rt_mdio_bus_ops *ops;
};

我们可以看到在RT-Thread下对MDIO设备和驱动接口也做了抽象的定义,比如MDIO驱动的操作接口包括初始化、读、写和解除初始化操作。对于MDIO设备,其包含对应的硬件内容,MDIO设备名和操作接口

static struct rt_mdio_bus_ops h3_mdiobus_ops =
{.init   = h3_mdioplib_init,.read   = h3_mdioplib_read,.write  = h3_mdioplib_write,.uninit = RT_NULL,
};

在mac驱动下,MDIO设备驱动的读取接口实现如下,在这个驱动接口实现中,我们通过获取MDIO总线下包含的硬件信息,做一个类型的强制转换,获取到了指向macplib_dev实例的指针,然后就可以通过这个macplib_dev访问mac设备抽象接口提供的PHY寄存器访问操作,实现了MDIO的读操作,整个代码还是相当的简单。

static rt_size_t h3_mdioplib_read(void *bus, rt_uint32_t addr,rt_uint32_t reg, void *data, rt_uint32_t size)
{rt_uint16_t val;rt_uint32_t *data_ptr = (rt_uint32_t *)data;struct h3_macplib_dev *macplib_dev;struct rt_mdio_bus    *mdioplib_bus = (struct rt_mdio_bus *)bus;RT_ASSERT(data != NULL);RT_ASSERT(bus  != NULL);if (4 != size) {return 0;}macplib_dev = (struct h3_macplib_dev *)mdioplib_bus->hw_obj;macplib_dev->mac_ops->macdev_readphy(&macplib_dev->mac_dev,(rt_uint16_t)addr, (rt_uint16_t)reg,&val);/* Get data from MII register. */*data_ptr = (rt_uint32_t)val;return 4;
}

在mac驱动下另外一个需要注意的地方是,mac驱动需要提供一个类似mdio驱动查找接口,用于PHY设备在初始化的时候,查找需要的MDIO设备驱动接口,用来实现对PHY寄存器的访问,代码实现如下。

rt_mdio_t *h3_mdioplib_search(const char *name)
{rt_uint32_t table_sz = sizeof(h3_macplib_devtable)/sizeof(uint32_t);struct h3_macplib_dev *macplib_dev;for (uint32_t i = 1; i < table_sz; i++){macplib_dev = h3_macplib_devtable[i];if (rt_strcmp(name, macplib_dev->rt_mdiobus.name) == 0){return &macplib_dev->rt_mdiobus;}}return NULL;
}

在PHY驱动中,对PHY设备的抽象定义时,增加了一个mdio_name的定义,用于定义该PHY设备对应的MDIO总线设备名,然后PHY设备可以通过该mdio_name名字,去查找到对应的MDIO总线设备。

struct h3_kszplib_dev
{const char *phy_name;uint32_t    phy_addr;const char *mdio_name;struct rt_phy_device rt_phydev;
} ;
static rt_phy_status h3_ksz9plib_init(struct rt_phy_device *phy, void *object,rt_uint32_t phy_addr, rt_uint32_t src_clock_hz)
{rt_bool_t ret;rt_phy_status result  = PHY_STATUS_FAIL;rt_uint32_t counter   = PHY_TIMEOUT_COUNT;rt_uint32_t regval    = 0;rt_uint32_t deviceID  = 0;struct rt_mdio_bus    *mdio_bus;struct h3_kszplib_dev *kszplib_dev;RT_ASSERT(phy != RT_NULL);kszplib_dev = rt_container_of(phy, struct h3_kszplib_dev, rt_phydev);mdio_bus    = h3_mdioplib_search(kszplib_dev->mdio_name);RESULT_MATCH_CHECK(mdio_bus, RT_NULL, outs)kszplib_dev->phy_addr = phy_addr;phy->bus              = mdio_bus;phy->addr             = phy_addr;ret = mdio_bus->ops->init(mdio_bus, src_clock_hz);NOT_MATCH_CHECK(ret, RT_TRUE, outs)/* Initialization after PHY stars to work. */do{h3_kszplib_read(phy, GMII_PHYID1, &deviceID);counter--;} while ((deviceID != GMII_PHYID1_KSZ9131) && (counter != 0));RESULT_MATCH_CHECK(counter, 0, outs)result = h3_kszplib_read(phy, GMII_MCR, &regval);RESULT_MATCH_CHECK(result, PHY_STATUS_FAIL, outs)regval |= GMII_MCR_ANENABLE | GMII_MCR_ANRESTART;result  = h3_kszplib_write(phy, GMII_MCR, regval);RESULT_MATCH_CHECK(result, PHY_STATUS_FAIL, outs)counter = PHY_TIMEOUT_COUNT;/* Check auto negotiation complete. */do{result = h3_kszplib_read(phy, GMII_MSR, &regval);RESULT_MATCH_CHECK(result, PHY_STATUS_FAIL, outs)if ((regval & GMII_MSR_ANEGCOMPLETE) != 0){break;}} while (--counter > 1);outs:return result;
}

MAC驱动与MDIO总线

在mac设备的抽象中,由于都包含了rt_mdio_bus,因此在mac设备实例的初始化的时候,都将mac设备与其提供的mdio总线进行绑定,例如在实例初始化时的静态绑定。

struct h3_macplib_dev
{const char   *name;IRQn_Type     irqnum;H3_MAC_REGS   regs;rt_uint8_t    mac_addr[6];rt_uint8_t    dev_id;rt_uint8_t    reserved;mac_async_dev mac_dev;phy_async_dev phy_dev;const struct rt_mdio_bus_ops *mdio_ops;const struct h3_macplib_ops  *mac_ops;struct rt_mdio_bus rt_mdiobus;struct eth_device  rt_ethdev;
} ;
#if defined(BSP_USING_GMAC0) || defined(BSP_USING_EMAC0)
struct h3_macplib_dev h3_macdev0 = {.name       = "e0",.irqnum     = MAC0_IRQn,.regs       = MAC0_REGS,.dev_id     = MAC0_ID,.rt_mdiobus ={.name       = MDIO0_DEVICE_NAME,.ops        = &h3_mdiobus_ops,},.phy_dev    ={.name       = PHY0_DEVICE_NAME,.phyID1     = H3_MACPLIB_PHY0ID1,.phyID2     = H3_MACPLIB_PHY0ID2,.phyaddr    = PHY0_DEVICE_ADDRESS,},.mac_ops    = &h3_macdev_ops,
};
#endif

初始化时的绑定(仅展示部分相关代码)。

int h3_macplib_init(void)
{rt_err_t    state;rt_uint32_t table_sz = sizeof(h3_macplib_devtable)/sizeof(uint32_t);struct h3_macplib_dev *macplib_dev;for (uint32_t i = 1; i < table_sz; i++){macplib_dev = h3_macplib_devtable[i];macplib_dev->mac_dev.devid     = macplib_dev->dev_id;macplib_dev->rt_mdiobus.hw_obj = (void *)macplib_dev;}
}

到此为止,mac驱动接口、PHY驱动接口和MDIO驱动接口,设备的抽象、接口的实现以及彼此之间的关系讲解完成。

相关文章:

在RT-Thread下为MPU手搓以太网MAC驱动-4

文章目录 MAC驱动里面对MDIO的支持MAC驱动与MDIO总线 这是个人驱动开发过程中做的一些记录&#xff0c;仅代表个人意见和理解&#xff0c;不喜勿喷 MAC驱动需要支持不同的PHY芯片 MAC驱动里面对MDIO的支持 在第一篇文章中提到对MAC设备做出了抽象&#xff0c;其中MAC抽象里面有…...

可的哥(Codigger)推出Monaco编辑器插件,提升编程体验

Monaco编辑器&#xff0c;作为业界领先的代码编辑器&#xff0c;在编程体验中发挥着不可或缺的重要作用&#xff0c;能够在多种编程语言和开发环境中表现出色&#xff0c;为开发者提供高效、便捷的编程环境。可的哥&#xff08;Codigger&#xff09;在应用商店上线Monaco编辑器…...

为什么选择mobx

对于React而言&#xff0c;大家熟能而详的是redux&#xff0c;但我们的项目用的是mobx&#xff0c;接下来就让我给你详细说下它的优势和不足&#xff0c;可以参考。 MobX是什么&#xff1f; MobX 是一种简单易用的状态管理库&#xff0c;它采用基于观察者的模式&#xff0c;可…...

如何解决段转储问题

非常恶心 &#xff0c;这个问题困了我一个月&#xff0c;怀疑过代码有问题 &#xff0c;怀疑过数据集没处理好&#xff0c;怀疑过环境没有配置好&#xff0c;尝试改动&#xff0c;跑过很多次&#xff0c;还是段转储报错卡住。。。 然后一个月荒废&#xff0c;打算放弃这个模型…...

【杂谈】AIGC之ChatGPT-与智能对话机器人的奇妙对话之旅

与智能对话机器人的奇妙对话之旅 引言 在数字时代的浪潮中&#xff0c;ChatGPT如同一位智慧的旅伴&#xff0c;它不仅能够与我们畅谈古今&#xff0c;还能解答我们的疑惑&#xff0c;成为我们探索知识海洋的得力助手。今天&#xff0c;就让我们走进ChatGPT的世界&#xff0c;…...

CentOS7配置国内清华源并安装docker-ce以及配置docker加速

说明 由于国内访问国外的网站包括docker网站&#xff0c;由于种种的原因经常打不开&#xff0c;或无法访问&#xff0c;所以替换成国内的软件源和国内镜像就是非常必要的了&#xff0c;这里整理了我安装配置的基本的步骤。 国内的软件源有很多&#xff0c;这里选择清华源作为…...

JL-03-Y1 清易易站

产品概述 清易易站是清易电子新研发的一体式气象站&#xff0c;坚持科学化和人文化相结合的设计理念&#xff0c;应用新检测原理研发的传感器观测各类气象参数&#xff0c;采用社会上时尚的工艺理念设计气象站的整体结构&#xff0c;实现了快速观测、无线传输、数据准确、精度较…...

PipeSer管线管网云服务

行业需求 地下管网&#xff0c;作为现代城市不可或缺的基础设施&#xff0c;堪称城市的“地下生命线”。它承载着城市的供水、排水、燃气、电力、通信等重要功能&#xff0c;是确保城市正常运转和居民生活便利的关键所在。将地下管网的复杂布局和运行状态以三维形式直观展现出来…...

kubesphere报错

1.安装过程报错unable to sign certificate: must specify a CommonName [rootnode1 ~]# ./kk init registry -f config-sample.yaml -a kubesphere.tar.gz _ __ _ _ __ | | / / | | | | / / | |/ / _ _| |__ ___| |/…...

【QT5】<总览二> QT信号槽、对象树及样式表

文章目录 前言 一、QT信号与槽 1. 信号槽连接模型 2. 信号槽介绍 3. 自定义信号槽 二、不使用UI文件编程 三、QT的对象树 四、添加资源文件 五、样式表的使用 六、QSS文件的使用 前言 承接【QT5】&#xff1c;总览一&#xff1e; QT环境搭建、快捷键及编程规范。若存…...

2024.05.24 校招 实习 内推 面经

绿*泡*泡VX&#xff1a; neituijunsir 交流*裙 &#xff0c;内推/实习/校招汇总表格 1、实习丨蔚来2025届实习生招募计划开启&#xff08;内推&#xff09; 实习丨蔚来2025届实习生招募计划开启&#xff08;内推&#xff09; 2、校招&实习丨联芯集成电路2025届暑期实习…...

如何理解 Java 8 引入的 Lambda 表达式及其使用场景

Lambda表达式是Java 8引入的一项重要特性&#xff0c;它使得编写简洁、可读和高效的代码成为可能。Lambda表达式本质上是一种匿名函数&#xff0c;能够更简洁地表示可传递的代码块&#xff0c;用于简化函数式编程的实现。 一、Lambda表达式概述 1. 什么是Lambda表达式 Lambd…...

GPT-4与GPT-4O的区别详解:面向小白用户

1. 模型介绍 在人工智能的语言模型领域&#xff0c;OpenAI的GPT-4和GPT-4O是最新的成员。这两个模型虽然来源于相同的基础技术&#xff0c;但在功能和应用上有着明显的区别。 GPT-4&#xff1a;这是一个通用型语言模型&#xff0c;可以理解和生成自然语言。无论是写作、对话还…...

使用throttle防止按钮多次点击

背景&#xff1a;如上图所示&#xff0c;点击按钮&#xff0c;防止按钮点击多次 <div class"footer"><el-button type"primary" click"submitThrottle">发起咨询 </el-button> </div>import { throttle } from loda…...

Echarts 在折线图的指定位置绘制一个图标展示

文章目录 需求分析需求 在线段交汇处用一个六边形图标展示 分析 可以使用 markPoint 和 symbol 属性来实现。这是一个更简单和更标准的方法来添加标记点在运行下述代码后,你将在浏览器中看到一个折线图,其中在 [3, 35] (即图表中第四个数据点 Thu 的 y 值为 35 的位置)处…...

适用于 Windows 的 8 大数据恢复软件

数据恢复软件可帮助您恢复因意外删除或由于某些技术故障&#xff08;如硬盘损坏等&#xff09;而丢失的数据。这些工具可帮助您从硬盘驱动器 (HDD) 中高效地恢复丢失的数据&#xff0c;因为这些工具不支持从 SSD 恢复数据。重要的是要了解&#xff0c;您删除的数据不会被系统永…...

HTTP基础

一、HTTP协议 1、HTTP协议概念 HTTP的全称是&#xff1a;Hyper Text Transfer Protocol&#xff0c;意为 超文本传输协议。它指的是服务器和客户端之间交互必须遵循的一问一答的规则。形容这个规则&#xff1a;问答机制、握手机制。 它规范了请求和响应内容的类型和格式, 是基于…...

深入了解Linux命令:visudo

深入了解Linux命令&#xff1a;visudo 在Linux系统中&#xff0c;sudo&#xff08;superuser do&#xff09;是一个允许用户以其他用户身份&#xff08;通常是超级用户或其他用户&#xff09;执行命令的程序。sudo的配置文件/etc/sudoers存储了哪些用户可以执行哪些命令的权限…...

十大排序 —— 希尔排序

十大排序 —— 希尔排序 什么是希尔排序插入排序希尔排序递归版本 我们今天来看另一个很有名的排序——希尔排序 什么是希尔排序 希尔排序&#xff08;Shell Sort&#xff09;是插入排序的一种更高效的改进版本&#xff0c;由Donald Shell于1959年提出。它通过比较相距一定间…...

SpringCloud Hystrix服务熔断实例总结

SpringCloud Hystrix断路器-服务熔断与降级和HystrixDashboard SpringCloud Hystrix服务降级实例总结 本文采用版本为Hoxton.SR1系列&#xff0c;SpringBoot为2.2.2.RELEASE <dependency><groupId>org.springframework.cloud</groupId><artifactId>s…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...

FFmpeg avformat_open_input函数分析

函数内部的总体流程如下&#xff1a; avformat_open_input 精简后的代码如下&#xff1a; int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...

倒装芯片凸点成型工艺

UBM&#xff08;Under Bump Metallization&#xff09;与Bump&#xff08;焊球&#xff09;形成工艺流程。我们可以将整张流程图分为三大阶段来理解&#xff1a; &#x1f527; 一、UBM&#xff08;Under Bump Metallization&#xff09;工艺流程&#xff08;黄色区域&#xff…...