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

文章目录

    • 动手写驱动之前的思考
    • MAC驱动兼容不同的MPU平台
      • 解决不同MPU平台头文件包含的问题
      • 对MAC操作接口的抽象
      • 对MAC设备的抽象
      • MAC设备的注册

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

动手写驱动之前的思考

  • MAC驱动需要兼容不同的MPU平台
  • MAC驱动需要支持不同的PHY芯片
  • MAC驱动需要支持多个以太网接口
  • MAC驱动需要是否借鉴某个平台代码

在动手写驱动之前,脑海里就会在不停地思考这几个问题,等脑子里有个大概的可行框架就开始动手码代码。

MAC驱动兼容不同的MPU平台

Microchip 也有着丰富的MPU产品线(通过收购Atmel而获取),覆盖传统的ARM9、Cortex-A5和Cortex-A7内核。有的MPU它的以太网叫做GMAC,而有的又叫做EMAC,那编写驱动的时候就要留意对GMAC和EMAC的同时

解决不同MPU平台头文件包含的问题

选择在libraries/Kconfig文件下添加以下内容:

config SOC_SAM9X60_EKboolselect RT_USING_COMPONENTS_INITselect RT_USING_CACHEconfig SOC_SAM9X75_EKboolselect RT_USING_COMPONENTS_INITselect RT_USING_CACHEconfig SOC_SAMA5D2_XULTboolselect ARCH_ARM_CORTEX_Aselect ARCH_ARM_CORTEX_FPUconfig SOC_SAMA5D2_SOM1_EKboolselect ARCH_ARM_CORTEX_Aselect ARCH_ARM_CORTEX_FPUconfig SOC_SAMA7G54_EKboolselect ARCH_ARM_CORTEX_Aselect ARCH_ARM_CORTEX_FPU

那在sam9x75-ek/board/Kconfig文件下这么做:

menu "Microchip Harmony Plib Configuration"config SOC_SAM9X75boolselect ARCH_ARM_ARM9select SOC_SAM9X75_EKselect RT_USING_USER_MAINdefault y

通过这样的方式,在选择sam9x75-ek平台做开发的时候,就会自动选择上SOC_SAM9X75_EK这个宏定义,后面会用到这个定义。

接下来在gmac/hpl_mac_async.h头文件中添加以下代码实现了对不同平台头文件的包含:

#ifdef SOC_SAMA5D2
#include <sama5d27.h>
#endif#ifdef SOC_SAM9X75
#include <sam9x75.h>
#endif#ifdef SOC_SAMA7G54
#include <sama7g54.h>
#endif

有的MPU平台只有一个GMAC,那它给的MAC相关ID定义是ID_GMAC,如果包含2个GMAC的MPU平台,则会给出ID_GMAC0和ID_GMAC1,那我选择在hpl_mac_async.h头文件添加这样的定义(后面会讲解到这样定义的作用):

#define ID_GMAC_NONE               0xFF#ifdef ID_GMAC
#  define MAC0_ID                  ID_GMAC
#  define MAC1_ID                  ID_GMAC_NONE
#  define MAC0_IRQn                GMAC_IRQn
#  define MAC1_IRQn                ID_GMAC_NONE
#  define MAC0_REGS                GMAC_REGS
#  define MAC1_REGS                (void *)0
#else
#  define MAC0_ID                  ID_GMAC0
#  define MAC1_ID                  ID_GMAC1
#  define MAC0_IRQn                GMAC0_IRQn
#  define MAC1_IRQn                GMAC1_IRQn
#  define MAC0_REGS                GMAC0_REGS
#  define MAC1_REGS                GMAC1_REGS
#endif

对MAC操作接口的抽象

MAC操作接口的抽象,包括中断处理函数、初始化、使能和禁止、网络数据包的收发、获取接收数据包长度、过滤的设置、MAC地址的设置和非常重要的PHY读写访问接口:

struct h3_macplib_ops
{void     (*macdev_interrupt)(mac_dev *const dev);int32_t  (*macdev_init)(mac_dev *const dev, void *const hw);int32_t  (*macdev_deinit)(mac_dev *const dev);int32_t  (*macdev_enable)(mac_dev *const dev);int32_t  (*macdev_disable)(mac_dev *const dev);int32_t  (*macdev_change) (mac_dev *const dev, uint32_t speed);int32_t  (*macdev_send)(mac_dev *const dev, uint8_t *buf, uint32_t len);uint32_t (*macdev_recv)(mac_dev *const dev, uint8_t *buf, uint32_t len);uint32_t (*macdev_rxbyte)(mac_dev *const dev);int32_t  (*macdev_register)(mac_dev *const dev, mac_cb_type type, mac_async_cb fn);int32_t  (*macdev_filter)(mac_dev *const dev, uint8_t index, mac_filter *filter);int32_t  (*macdev_setmac)(mac_dev *const dev, uint8_t mac[6]);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);
};

对MAC设备的抽象

对MAC设备也做出了抽象,MPU中如果存在多个MAC接口,那就会有对应数量的MAC设备实例:

struct h3_macplib_dev
{const char   *name;IRQn_Type     irqnum;H3_MAC_REGS   regs;uint8_t       mac_addr[6];uint8_t       dev_id;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;
};

MAC设备的注册

对MAC设备对应的实例,其部分成员都会在h3_macplib.c文件里面做静态的初始化:

#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,.phy_dev    ={.name       = PHY0_DEVICE_NAME,.phyID1     = H3_MACPLIB_PHY0ID1,.phyID2     = H3_MACPLIB_PHY0ID2,.phyaddr    = PHY0_DEVICE_ADDRESS,},.mac_ops    = &h3_macdev_ops,
};
#endif#if defined(BSP_USING_GMAC1) || defined(BSP_USING_EMAC1)
struct h3_macplib_dev h3_macdev1 = {.name       = "e1",.irqnum     = MAC1_IRQn,.regs       = MAC1_REGS,.dev_id     = MAC1_ID,.phy_dev    ={.name       = PHY1_DEVICE_NAME,.phyID1     = H3_MACPLIB_PHY1ID1,.phyID2     = H3_MACPLIB_PHY1ID2,.phyaddr    = PHY1_DEVICE_ADDRESS,},.mac_ops    = &h3_macdev_ops,
};
#endif

实现对多个MAC设备的注册是这样来实现的:

static struct h3_macplib_dev *h3_macplib_devtable[] =
{0
#if defined(BSP_USING_GMAC0) || defined(BSP_USING_EMAC0), &h3_macdev0
#endif
#if defined(BSP_USING_GMAC1) || defined(BSP_USING_EMAC1), &h3_macdev1
#endif
};
int h3_macplib_init(void)
{rt_err_t state;uint8_t  macaddr = 0xAA;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;macplib_dev->rt_mdiobus.ops    = &h3_mdiobus_ops;/* GMAC MAC Address */macplib_dev->mac_addr[0] = 0x54;macplib_dev->mac_addr[1] = 0x27;macplib_dev->mac_addr[2] = 0x8d;macplib_dev->mac_addr[3] = 0x33;macplib_dev->mac_addr[4] = 0x55;macplib_dev->mac_addr[5] = macaddr++;macplib_dev->rt_ethdev.parent.init      = h3_macplib_initial;macplib_dev->rt_ethdev.parent.open      = h3_macplib_open;macplib_dev->rt_ethdev.parent.close     = h3_macplib_close;macplib_dev->rt_ethdev.parent.read      = h3_macplib_read;macplib_dev->rt_ethdev.parent.write     = h3_macplib_write;macplib_dev->rt_ethdev.parent.control   = h3_macplib_control;macplib_dev->rt_ethdev.parent.user_data = (void *)macplib_dev;macplib_dev->rt_ethdev.eth_rx = h3_macplib_rx;macplib_dev->rt_ethdev.eth_tx = h3_macplib_tx;/* register eth device */state = eth_device_init(&macplib_dev->rt_ethdev, macplib_dev->name);if (RT_EOK != state) {break;}eth_device_linkchange(&macplib_dev->rt_ethdev, RT_FALSE);}return state;
}

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

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

相关文章

React Native 之 AppState(应用状态)(二十二)

AppState 是 React Native 提供的一个 API&#xff0c;用于监听应用在前台、后台或未激活状态之间的切换。这对于管理应用的资源、调整应用的界面显示或响应系统事件&#xff08;如来电&#xff09;等场景非常有用。 AppState 模块通过监听系统广播的意图&#xff08;Intents&a…

2024Dragon Knight CTF复现web

穿梭隐藏的密钥 首先看看页面的源代码&#xff0c;但是发现f12和鼠标右键都被禁用了 用ctrlu查看&#xff0c;发现一个可疑页面 访问看看&#xff0c;发现还是只有一张图&#xff0c;查看源代码发现提示 扩展&#xff1a; Fuzz&#xff1a;Fuzz是一种基于黑盒的自动化软件模糊…

TXT文档拆分、合并、添加内容,修改内容、删除内容——首助编辑高手软件一招解决

下面这个TXT文档里面是一篇长篇小说&#xff0c;大家都知道一般小说文字内容是比较大的一个文件呢&#xff0c;想要拆分&#xff0c;拆分肯定是有方法呢&#xff0c;比如比较重统的方法手动一章一章复制出来&#xff0c;粘贴到另一个文档里面去粘贴&#xff0c;手动操作是不是很…

【GlobalMapper精品教程】083:基于DEM整体抬升或下降地形高程的两种方式

在Globalmapper24中文版中,可以很方便地对DEM高程数据进行整体抬升或下降。 文章目录 一、准备DEM数据二、高程整体修改1. 修改偏移2. 数据导出三、栅格计算器一、准备DEM数据 订阅专栏后,从私信查收实验数据及Globalmapper24中文版,加载实验数据包data083.rar中的dem数据,…

数据结构:希尔排序

文章目录 前言一、排序的概念及其运用二、常见排序算法的实现 1.插入排序2.希尔排序总结 前言 排序在生活中有许多实际的运用。以下是一些例子&#xff1a; 购物清单&#xff1a;当我们去超市购物时&#xff0c;通常会列出一份购物清单。将购物清单按照需要购买的顺序排序&…

[ROS 系列学习教程] 建模与仿真 - Xacro 语法

ROS 系列学习教程(总目录) 本文目录 一、属性与属性块二、数学表达式三、宏3.1 宏的基本使用3.2 属性块做为宏的入参3.3 任意数量元素做为宏的入参3.4 指定多个块元素的处理顺序3.5 宏嵌套3.6 默认参数3.7 局部属性 四、Rospack 命令五、包含其他 xacro 文件六、条件语句七、YA…

虚拟现实环境下的远程教育和智能评估系统(一)

本周讨论明确项目应用背景、待学习的技术点、技术路线、实施方案&#xff1b; 一、项目背景 在当前的在线教育环境中&#xff0c;尽管视频教学已经成为主流&#xff0c;但缺乏对学生学习状态的实时反馈和精准分析。传统的视频教学往往无法有效捕捉学生在观看过程中的专注程度…

机器人动力学模型与MATLAB仿真

机器人刚体动力学由以下方程控制&#xff01;&#xff01;&#xff01; startup_rvc mdl_puma560 p560.dyn 提前计算出来这些“disturbance”&#xff0c;然后在控制环路中将它“抵消”&#xff08;有时候也叫前馈控制&#xff09; 求出所需要的力矩&#xff0c;其中M项代表克服…

世界500强是如何解决邮件大附件影响业务问题的

电子邮件已成为众多企业沟通和文件传输的重要工具。然而&#xff0c;邮件发送大附件时&#xff0c;企业往往会遇到一系列挑战。本文将探讨邮件发送大附件的优劣势&#xff0c;分析其对业务可能造成的问题&#xff0c;并介绍500强企业是如何解决这些问题的。 邮件发送大附件的优…

V90 PN总线伺服通过FB285速度控制实现正弦位置轨迹运动(解析法和数值法对比测试)

V90总线伺服相关内容请参考专栏系列文章,这里不在详述 1、V90伺服PN总线速度随动控制 V90伺服PN总线速度随动控制(手摇轮功能)_手摇轮可以接总线plc吗?-CSDN博客文章浏览阅读632次。V90PN总线控制相关内容,请参考下面文章链接:博途1200/1500PLC V90 PN通信控制 (FB284功能…

Facebook的算法揭秘:如何塑造我们的信息

在当今数字化时代&#xff0c;Facebook已经成为人们日常生活中不可或缺的一部分。其信息流算法不仅决定着我们在平台上看到的内容&#xff0c;还对我们的观点、行为和体验产生了深远的影响。本文将深入探讨Facebook的算法运作方式&#xff0c;以及它对我们信息获取和社交行为的…

mybatis-plus主键生成需注意问题

mybatis-plus主键策略很方便&#xff0c;也有很多种&#xff0c;不过有2个地方还是需要引起注意&#xff1a; 1.如果不添加TableId注解&#xff0c;会默认匹配id字段为主键&#xff0c;所以当数据库主键字段和属性不是id时&#xff0c;需用TableId显式指定&#xff1b; 2.如果…

Java集合【超详细】2 -- Map、可变参数、Collections类

文章目录 一、Map集合1.1 Map集合概述和特点【理解】1.2 Map集合的基本功能【应用】1.3 Map集合的获取功能【应用】1.4 Map集合的两种遍历方式 二、HashMap集合2.1 HashMap集合概述和特点【理解】2.2 HashMap的组成、构造函数2.3 put、查找方法2.4 HashMap集合应用案例【应用】…

STL库--pair详解

目录 pair的定义 pair中元素的访问 pair常用函数实例解析 pair的常见用途 pair是一个很实用的小玩意&#xff0c;当想要将两个元素绑在一起作为一个合成元素、又不想要因此定义结构体时&#xff0c;使用pair可以很方便地作为一个代替品。也就是说&#xff0c;pair实际上可以…

java8 stream流的用法

java中经常需要对集合中部分属性进行收集汇总并添加到新集合中&#xff0c;并且过滤掉不符合条件的对象&#xff0c;其正确用法是&#xff1a; List<SkuImagesEntity> skuImagesEntities images1.stream().map(img -> {SkuImagesEntity skuImagesEntity new SkuIma…

FFMPEG学习笔记(一): 提取视频的纯音频及无声视频

文章目录 背景命令行批量处理 背景 我们想要单独获取视频的音频和无声的视频&#xff0c;我们可以通过ffmpeg来实现。 命令行 # 提取音频 ffmpeg -i input.mp4 -vn -c:a libmp3lame output.mp3# 提取无声视频 ffmpeg -i input.mp4 -c:v copy -an output.mp4-i input.mp4&…

【c++入门】函数重载,引用,内联函数,auto

函数重载 函数重载概念 什么是函数重载&#xff1f; 函数重载&#xff1a;是函数的一种特殊情况&#xff0c;C允许在同一作用域中声明几个功能类似的同名函数&#xff0c;这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同&#xff0c;常用来处理实现功能类似数据类…

pytorch学习day3

一、模型创建&#xff08;Module&#xff09; 网络创建流程 ​ 上面的图表展示了使用PyTorch创建神经网络模型的主要步骤。每个步骤按顺序连接&#xff0c;展示了从导入必要的库到最终测试模型的整个流程&#xff1a; 导入必要的库&#xff1a;首先导入PyTorch及其相关模块。定…

【Tlias智能学习辅助系统】03 部门管理 前后端联调

Tlias智能学习辅助系统 03 部门管理 前后端联调 前端环境 前端环境 链接&#xff1a;https://pan.quark.cn/s/8720156ed6bf 提取码&#xff1a;aGeR 解压后放在一个不包含中文的文件夹下&#xff0c;双击 nginx.exe 启动服务 跨域的问题已经被nginx代理转发了&#xff0c;所以…

vs code 中使用SSH 连接远程的Ubuntu系统

如下图&#xff0c;找到对应的位置 在电脑上找到以下位置 打开配置如下&#xff0c;记住&#xff0c;那个root为你的用户名&#xff0c;这个用户名&#xff0c;具体根据你的用户名来设置&#xff0c;对应的密码就是你登录Ubuntu时的密码 Host root192.168.0.64User rootHostNa…