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

2024-05-25 09:36

本文主要是介绍在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

解决不同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_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,.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,.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;
}

这篇关于在RT-Thread下为MPU手搓以太网MAC驱动-1的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1001126

相关文章

mac中资源库在哪? macOS资源库文件夹详解

《mac中资源库在哪?macOS资源库文件夹详解》经常使用Mac电脑的用户会发现,找不到Mac电脑的资源库,我们怎么打开资源库并使用呢?下面我们就来看看macOS资源库文件夹详解... 在 MACOS 系统中,「资源库」文件夹是用来存放操作系统和 App 设置的核心位置。虽然平时我们很少直接跟它打交道,但了

macOS怎么轻松更换App图标? Mac电脑图标更换指南

《macOS怎么轻松更换App图标?Mac电脑图标更换指南》想要给你的Mac电脑按照自己的喜好来更换App图标?其实非常简单,只需要两步就能搞定,下面我来详细讲解一下... 虽然 MACOS 的个性化定制选项已经「缩水」,不如早期版本那么丰富,www.chinasem.cn但我们仍然可以按照自己的喜好来更换

mac安装redis全过程

《mac安装redis全过程》文章内容主要介绍了如何从官网下载指定版本的Redis,以及如何在自定义目录下安装和启动Redis,还提到了如何修改Redis的密码和配置文件,以及使用RedisInsig... 目录MAC安装Redis安装启动redis 配置redis 常用命令总结mac安装redis官网下

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

Thread如何划分为Warp?

1 .Thread如何划分为Warp? https://jielahou.com/code/cuda/thread-to-warp.html  Thread Index和Thread ID之间有什么关系呢?(线程架构参考这里:CUDA C++ Programming Guide (nvidia.com)open in new window) 1维的Thread Index,其Thread

mac安装brew 与 HomeBrew

/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh >> brew_install BREW_REPO="

mac jdk 1.7 dmg 官方版

百度云下载 https://pan.baidu.com/s/1SQiidrPFF5aZr4xlx0ekoQ https://pan.baidu.com/s/1SQiidrPFF5aZr4xlx0ekoQ   补充说明: 实际上oracle对于历史版本的jdk都有归档可以在官方网站上下载,只是需要注册个号就可以了。 地址如下: https://www.oracle.com/cn/java

编程应该用 Mac 还是 PC ?

『有人的地方,就有江湖』—徐克。笑傲江湖。     序     一个竞争的市场,就会有对立的产生,这世界存在著很多不同的领域,领域好比是个江湖的缩影,因此就有许多门派的纷争,例如说浏览器领域有著最大宗的IE派,门派成长速度飞快,武功版号跳的跟台湾物价指数一样快的Chrome门,不断被模仿,一直被超越的Opera派;韧性极强,一直对抗几大势力的Firefox派等等,程序语言也有自己的领域

驱动(RK3588S)第七课时:单节点设备树

目录 需求一、设备树的概念1、设备树的后缀名:2、设备树的语法格式3、设备树的属性(重要)4、设备树格式举例 二、设备树所用函数1、如何在内核层种获取设备树节点:2、从设备树上获取 gpio 口的属性3、获取节点上的属性只针对于字符串属性的4、函数读取 np 结点中的 propname 属性的值,并将读取到的 u32 类型的值保存在 out_value 指向的内存中,函数的返回值表示读取到的

驱动安装注册表指令

HKCR: HKEY_CLASSES_ROOT HKCU: HKEY_CURRENT_USER HKLM: HKEY_LOCAL_MACHINE HKU: HEKY_USER HER: 相对根键