首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >19.DM9000网卡驱动移植

19.DM9000网卡驱动移植

作者头像
嵌入式与Linux那些事
发布2021-05-20 15:46:28
9330
发布2021-05-20 15:46:28
举报

控制DM9000,接口为内存控制器,具体设置哪一个bank

一、首先来看DM9000C原理图

如下图所示:

(#:表示低电平有效)

SD0~15: 16位数据线,有CMD引脚决定访问类型 CMD: 命令线,当CMD为高,表示SD 传输的是数据,CMD为低表示传输的是地址 INT: 中断引脚,接在2440的GPF7脚上 IOR#: 读引脚,接在2440的nOE脚上 IOW#: 写引脚,接在2440的nWE脚上 CS#: 片选,放在2440的bank4的片选上面

1.其中2440手册的bank4地址区间如下图:
在这里插入图片描述
在这里插入图片描述

  bank4的区间位于: 0X20000000~0X28000000,当我们访问这个区间的地址,内存控制器便会使能网卡DM9000C的使能脚,所以我们的DM9000C的io基地址=0X20000000

  其中DM9000C的CMD引脚接在bank4的LADDR2上面

  比如当在地址0X2000 0000上读写数据时,表示读写的数据是DM9000C的地址

访问的地址0X2000 0004上读写数据时,表示读写的数据是DM9000C的数据

二、DM9000C收发过程

  当DM9000C收到外部的数据后,会暂存到内部地址中,然后产生一个上升沿中断,等待2440读取数据

  当DM9000C将2440的数据转发出去后,也会产生一个上升沿中断给2440

  如下图所示,DM9000C的中断引脚位于pin34脚

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  接在2440的GPF7引脚上,使用的中断为EINT7

三、DM9000C源代码分析

1.发现它的init_module()入口函数前有个条件编译
在这里插入图片描述
在这里插入图片描述

所以要注释掉 “#ifdef MODULE” 和 “#endif”

2.修改入口出口函数名,并修饰它们(修改函数名避免与内核的其它函数重名)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3.修改驱动的硬件相异性(设置基地址,寄存器,中断等)
3.1先来找找代码在哪里初始化DM9000C硬件的

进入dm9000c_init()

  -> dmfe_probe()

其中dmfe_probe()函数如下:

struct net_device * __init dmfe_probe(void)
{
struct net_device *dev;

dev= alloc_etherdev(sizeof(struct board_info));          //分配一个net_device结构体
... ...

err = dmfe_probe1(dev);                                 //调用dmfe_probe1()函数
... ...

err = register_netdev(dev);                            //向内核注册net_device结构体
... ...
}

  显然dmfe_probe1()函数就是用来初始化DM9000C硬件和设置net_device结构体的成员用的

3.2进入dmfe_probe1()函数

  如下图,这个iobase 变量就是我们DM9000C的io基地址0x20000000

在这里插入图片描述
在这里插入图片描述

iobase的作用:

  如上图, 读一次DM9000C的VID低字节之前,需要先将地址赋为0x20000000,也就是将DM9000C的CMD置0,然后向0x20000000写入要读的DM9KS_VID_L地址值

  最后再将地址+4,也就是赋为0x20000100,将CMD置1,然后读出0x20000100的值,也就是DM9000C的VID低字节

  DM9000C的读写方式都是这样的,先将CMD置0,写入DM9000C的地址,然后再将CMD置1,来读写数据

3.3所以在init函数中便重新设置iobase 变量,其中iobase是int型
在这里插入图片描述
在这里插入图片描述

并在exit出口函数中,添加iounmp()

在这里插入图片描述
在这里插入图片描述
3.4继续进入dmfe_probe1()函数,往下看

  如下图所示,屏蔽红框里的代码,该代码用来核对版本,我们的DM9000C版本号不一样,所以要屏蔽

在这里插入图片描述
在这里插入图片描述
3.5在init函数中,修改中断名,将irq改为IRQ_EINT7
在这里插入图片描述
在这里插入图片描述
3.6修改中断

  当使用了register_netdev()注册了网卡驱动net_device后,在内核中使用ifconfig就会进入net_device->open成员函数申请中断,激活队列等

  所以我们要修改open成员函数的申请中断函数,将触发中断改为“IRQT_RISING”,上升沿触发

在这里插入图片描述
在这里插入图片描述

四、设置2440的存储控制寄存器

设置2440的bank4的硬件位宽,时序,因为不同的硬件,涉及的数据收发都不同,

1.设置BWSCON总线宽度控制寄存器

  我们只设置BANK4的内容,所以只有下面3个(BANK0的位宽由OM[1:0] 硬件设置)

在这里插入图片描述
在这里插入图片描述

  设置ST4=0,不使用UB/LB(UB/LB:表示高字节与低字节数据是否分开传输)

  设置WS4=0,其中WAIT引脚为PE4,而我们DM9000C没有引脚接入PE4,所以禁止

  设置DW4=0x01,我们的DM9000C的数据线为16位

2.设置BANKCON4控制寄存器
在这里插入图片描述
在这里插入图片描述

   设置这些时序之前,首先来看DM9000C芯片手册时序图和2440的时序图

在这里插入图片描述
在这里插入图片描述

(hclk=100mhz,一个时钟周期就是10ns.nOE表示输出使能,读)   参考上图,得出BANKCON4 寄存器设置如下(HCLK=100MHZ,1个时钟等于10ns)   Tacs:地址信号稳定之后多少时间,才会发出片选信号!   设置Tacs=0,因为CS和CMD可以同时发出(bank4地址(也就是CMD)稳定多久后,CS片选才启动)   设置Tcos=T1=0(CS片选后,多久才能使能读写)   设置Tacc=T2>=10ns=1,表示2个时钟 (access cycle ,读写使能后,多久才能访问数据。读写信号宽度)   设置Tcoh=T4>=3ns=1,表示1个时钟 ,因为当DM9000的写信号取消后,数据线上的数据还需要至少3ns才消失(nOE读写取消后,片选需要维持多长时间)   设置Tcah=0,因为 CS和CMD可以同时结束 (CS片选取消后,地址(也就是CMD)需要维持多长时间)   代码如下图,在init入口函数中设置

在这里插入图片描述
在这里插入图片描述

   (PS:若DM9000C无法驱动,可能是Tacc时间太短,导致读取不到数据,可以将Tacc设大一点)

  与硬件相关的部分已经改好了,接下来开始编译

五、编译测试

编译之前,首先添加该驱动需要的内核头文件:

#include <asm/delay.h>
#include <asm/irq.h>
#include <linux/irq.h>
#include <asm/io.h>
#include <asm/arch-s3c2410/regs-mem.h>

编译无误后,便开始测试DM9000C驱动程序:

  1. 把dm9dev9000c.c放到内核的drivers/net目录下,来替换原来内核的DM9000C
  2. 修改drivers/net/Makefile

obj-$(CONFIG_DM9000) += dm9000.o

改为

obj-$(CONFIG_DM9000) += dm9dev9000c.o
  1. make uImage
  2. 使用新内核启动

ifconfig eth0 192.168.2.107

ping 192.168.2.1

可以ping通,说明移植成功

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-12-24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、首先来看DM9000C原理图
    • 1.其中2440手册的bank4地址区间如下图:
    • 二、DM9000C收发过程
    • 三、DM9000C源代码分析
      • 1.发现它的init_module()入口函数前有个条件编译
        • 2.修改入口出口函数名,并修饰它们(修改函数名避免与内核的其它函数重名)
          • 3.修改驱动的硬件相异性(设置基地址,寄存器,中断等)
            • 3.1先来找找代码在哪里初始化DM9000C硬件的
            • 3.2进入dmfe_probe1()函数
            • 3.3所以在init函数中便重新设置iobase 变量,其中iobase是int型
            • 3.4继续进入dmfe_probe1()函数,往下看
            • 3.5在init函数中,修改中断名,将irq改为IRQ_EINT7
            • 3.6修改中断
        • 四、设置2440的存储控制寄存器
          • 1.设置BWSCON总线宽度控制寄存器
            • 2.设置BANKCON4控制寄存器
            • 五、编译测试
            相关产品与服务
            命令行工具
            腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档