在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驱动接口,设备的抽象、接口的实现以及彼此之间的关系讲解完成。

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

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

相关文章

形式参数和实际参数

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在调用函数时&#xff0c;大多数情况下&#xff0c;主调函数和被调用函数之间有数据传递关系&#xff0c;这就是有参数的函数形式。函数参数的作用是…

前端面试题日常练-day43 【面试题】

题目 希望这些选择题能够帮助您进行前端面试的准备&#xff0c;答案在文末 1. 在Bootstrap中&#xff0c;以下哪个类用于创建一个具有响应式的栅格系统&#xff1f; a) .row b) .grid-system c) .container d) .responsive-grid 2. 哪个Bootstrap类用于创建一个具有圆角边框…

android-handlerThread

记住一点Handler是子线程到主线程&#xff0c;HandlerThread是主线程到子线程通信 一、HandlerThread简介 HandlerThread是一个轻量级的异步类&#xff0c;可以实现多线程&#xff0c;并且可以实现线程间的通信&#xff08;HandlerThread主要应用是实现主线程到子线程的通信&…

用于日常任务的实用 Python 脚本

Python 是一种多功能编程语言&#xff0c;以其简单易读而闻名。它广泛应用于从 Web 开发到数据分析等各个领域。Python 脚本&#xff0c;它们可以通过自动执行常见任务来使您的生活更轻松。 用于日常任务的实用 Python 脚本 1. 使用 Pandas 进行数据分析2. 使用 BeautifulSoup …

服务器怎么被远程桌面连接不上,远程桌面连接不上服务器的问题有效解决方案

远程桌面连接不上服务器是一个极其严重的问题&#xff0c;它可能直接影响到我们的工作效率、数据安全&#xff0c;甚至是整个业务运营的顺畅。因此&#xff0c;这个问题必须得到迅速且有效的解决。 当我们尝试远程桌面连接服务器时&#xff0c;可能会遇到连接不上的情况。这其中…

MFC:初步理解序列化与反序列化(含代码实现)

序列化与反序列化是MFC将对象数据以二进制数据流的形式进行存储和读取的机制&#xff0c;读、写的效率很高。通过序列化与反序列化&#xff0c;可以将程序中对象在内存中数据保存到文件 (磁盘) 或者从文件 (磁盘) 中读取到内存以恢复对象数据&#xff0c;从而实现程序对数据的持…

RxSwift - 实现一个MVVM架构的TableView

文章目录 RxSwift - 实现一个MVVM架构的TableView前沿MVVM架构的Tableview目录结构1、模型&#xff08;Model&#xff09;2、视图模型&#xff08;ViewModel&#xff09;3、视图&#xff08;View&#xff09; 界面效果 RxSwift - 实现一个MVVM架构的TableView 前沿 MVVM架构在…

分享一个实用的MySQL一键巡检脚本

今日分享一个实用的MySQL一键巡检脚本&#xff0c;脚本内容还不是很完善&#xff0c;后续会继续进行优化。大家可以先在测试环境执行&#xff0c;确认执行没问题后可以在生产环境进行操作&#xff0c;问题的可以私信我。 MySQL一键巡检脚本的作用主要是帮助数据库管理员快速且…

redux状态管理用法详解

在React中使用redux&#xff0c;官方要求安装俩个其他插件 - Redux Toolkit 和 react-redux 1.ReduxToolkit (RTK) 官方推荐编写 Redux 逻辑的方式&#xff0c;是一套工具的集合集&#xff0c;简化书写方式 简化 store 的配置方式&#xff1b; 内置 immer 支持…

dubbo复习:(19)dubbo 和spring整合(老古董)

一、服务端依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM…

华为SSH实验

华为SSH实验 实验拓扑&#xff1a; 实验要求&#xff1a;从SSH客户端AR1采用stelnet方式登录到SSH 服务器端。 实验步骤&#xff1a; 1.完成基本配置&#xff08;略&#xff09; sys Enter system view, return user view with CtrlZ. [AR1]sys CLIENT [CLIENT]INT g0/0/0 [C…

ECMAScript 详解:深入理解 JavaScript 的核心标准

ECMAScript 详解&#xff1a;深入理解 JavaScript 的核心标准 如果你是一名前端开发者&#xff0c;或者只是对编程感兴趣&#xff0c;那么你一定听说过 ECMAScript。它是 JavaScript 的标准&#xff0c;是现代 web 开发的基础。那么&#xff0c;究竟什么是 ECMAScript&#xf…

智能网联汽车翻译

智能网联汽车 自动驾驶功能场地试验方法及要求 2022-10-20 10:13:01 ChinaAutoRegs|GB/T 41798-2022英文版翻译 智能网联汽车 自动驾驶功能场地试验方法及要求 Intelligent and connected vehicles——Field testing methods and requirements for automated driving function…

打造你的首个QT 5计算器应用

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;QT 5的力量与我们的计算器 二、QT 5基础&#xff1a;理解UI设计与文件…

Java多线程(04)—— 保证线程安全的方法与线程安全的集合类

一、CAS 与原子类 1. CAS CAS&#xff08;compare and swap&#xff09;&#xff0c;是一条 cpu 指令&#xff0c;其含义为&#xff1a;CAS(M, A, B); M 表示内存&#xff0c;A 和 B 分别表示一个寄存器&#xff1b;如果 M 的值和 A 的值相同&#xff0c;则把 M 和 B 的值交…

数字IC基础:主要的FPGA厂商

相关阅读 数字IC基础https://blog.csdn.net/weixin_45791458/category_12365795.html?spm1001.2014.3001.5482 Xilinx&#xff08;现已被AMD收购&#xff09; Xilinx, 成立于1984年&#xff0c;是FPGA&#xff08;现场可编程门阵列&#xff09;技术的创始者和市场领导者。该公…

dmdts连接kingbase8报错

dmdts连接kingbase报错 环境介绍1 人大金仓jdbc配置2 dmdts 人大金仓jdbc默认配置3 dmdts 修改jdbc配置4 达梦产品学习使用列表 环境介绍 dts版本 使用dmdts连接kingbase金仓数据库报错 无效的URL 对比jdbc连接串,修改配置解决 1 人大金仓jdbc配置 配置URL模版信息等 类名…

民国漫画杂志《时代漫画》第36期.PDF

时代漫画36.PDF: https://url03.ctfile.com/f/1779803-1248636233-8a4a9d?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了&#xff0c;截止1937年6月战争来临被迫停刊共发行了39期。 ps: 资源来源网络!

【高校科研前沿】南大王栋、吴吉春教授团队在深度学习助力水库生态调度和优化管理方面取得新进展,成果以博士生邱如健为一作发表于水环境领域国际权威期刊

1.文章简介 论文名称&#xff1a;Integration of deep learning and improved multi-objective algorithm to optimize reservoir operation for balancing human and downstream ecological needs 第一作者及单位&#xff1a;邱如健&#xff08;博士生 南京大学&#xff09;…

Linux自动挂载服务autofs讲解

1.产生原因 2.配置文件讲解 总结&#xff1a;配置客户端&#xff0c;先构思好要挂载的目录如&#xff1a;/abc/cb 然后在autofs.master中编辑&#xff1a; /abc&#xff08;要挂载的主目录&#xff09; /etc/qwe&#xff08;在这个文件里去找要挂载的副目录&#xff0c;这个名…