77范文网 - 专业文章范例文档资料分享平台

嵌入式系统设计大学教程 - 习题与解答(8)

来源:网络收集 时间:2019-08-26 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

(1)初始化CS8900A芯片

对于CS8900A芯片,初始化函数是通过cs89x0_probe()和cs89x0_probe1()函数来实现。 int cs89x0_probe(struct device *dev) {

int base_addr = CS8900_BASE;

return cs89x0_probe1(dev,base_addr); }

其中CS8900_BASE是I/O被映射到的基地址。 static int cs89x0_probel(struct device *dev, int ioaddr) {

irq2dev_map[0] = dev; ……

/* 初始化寄存器,建立片选和芯片工作方式*/

*(volatile unsigned char *)0xfffff42b |= 0x01; /* output /sleep */

*(volatile unsigned short *)0xfffff428 |= 0x0101; /* not sleeping */ *(volatile unsigned char *)0xfffff42b &= ~0x02; /* input irq5 */ *(volatile unsigned short *)0xfffff428 &= ~0x0202;/* irq5 fcn on */ *(volatile unsigned short *)0xfffff102 = 0x8000; /* 0x04000000 */ *(volatile

unsigned

short

*)0xfffff112

=

0x01e1

/*128k,2ws,FLASH,en*/

??

/* 初始化设备结构*/ if (dev->priv == NULL){

dev->priv = kmalloc(sizeof(struct net_local),GFP_KERNEL);

memset(dev->priv, 0, sizeof(struct net_local)); }

dev->base_addr = ioaddr;

lp = (struct net_local *)dev->priv; ??

/* 取得芯片类型*/

rev_type = readreg(dev, PRODUCT_ID_ADD); lp->chip_type = rev_type &~ REVISON_BITS;

lp->chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A'; lp->send_cmd = TX_AFTER_ALL; ??

/*注册接口方法*/ dev->open = net_open; dev->stop = net_close;

dev->hard_start_xmit = net_send_packet; dev->get_stats = net_get_stats;

dev->set_multicast_list = &set_multicast_list;

dev->set_mac_address = &set_mac_address; ??

ether_setup(dev); }

(2)编写设备打开函数与关闭函数

打开和关闭一个网络接口是由ifconfig命令来完成的。当使用ifconfig为一个接口赋地址时,它完成两项工作。第一,它通过ioctl(SIOCSIFADDR)(即Socket I/O Control Set InterFace ADDRess)来赋地址;第二,它通过ioctl(SIOCSIFFLAGS)(即Socket I/O Control Set InterFace FLAGS)对dev->flag中的IFF_UP置位来打开接口。

CS8900A是一个ISA设备,不支持共享中断,但是这在嵌入式系统外设比较少的情况下对系统的性能没什么影响。另外,在接口可以和外界通信以前,还需要将芯片上的硬件地址复制到dev->dev_addr指针指向的空间上,这个工作也可以在初始化函数cs89x0_probe1中完成。

设备打开函数net_open的基本流程如下:

① 没有在初始化函数中注册中断号和I/O地址,则在设备打开时要进行注册;

② 将该设备挂到irq2dev_map中。若使用基于中断的数据接收方式,以后就可以通过中断号和irq2dev_map数组直接查找相应的设备了;

③ 初始化物理设备的寄存器;

④ 设置接口相应的dev的私有数据结构(dev->priv)中的一些字段;

⑤ 设置dev中的tbusy,interrupt和start等字段。 设备关闭函数net_close()与打开函数动作相反。 (3)数据包发送/接收函数的编写

在CS8900A芯片的I/O模式下,数据包的发送流程

① 发送一个传输命令到TxCMD端口(I/O base + 0004h),使芯片进入发送状态;

② 将要发送数据帧的长度发送到TxLength端口(I/O base + 0006h);

③ 通过信息包指针端口(I/O base +000Ch)读取Burst寄存器(寄存器18),判断Rdy4TxNOW位(第8位)的值。如果Rdy4TxNOW值为1,则跳到第4步;如果Rdy4TxNOW位的值为0,驱动程序将等待一段时间,再判断Rdy4TxNOW的值,直到它为1为止。另外,如果程序中Rdy4TxiE(寄存器BufCFG的第8位)被置为1,当CS8900A的发送缓冲区可写时,Rdy4Tx(寄存器BufEvent的第8位)将被置为1,并触发一个中断,这时候就不需要判断Rdy4TxNOW了;

④ 程序发送函数将反复执行写指令,将数据发送到接收/发送数据端口(I/O base +0000h)。

net_rx()函数的操作流程如下: ① 申请skb缓存区存储新的数据包; ② 从硬件中读取新到达的数据;

③ 调用函数netif_rx(),将新的数据包向网络协议的上一层传送; ④ 修改接口的统计函数。 4)中断处理函数的编写

一般的中断服务程序的基本流程如下: ① 确定发生中断的具体网络接口

② 打开标志位dev->interrupt,表示本服务程序正在被使用; ③ 读取中断状态寄存器,根据寄存器判断中断发生的原因。有两种可能,一种是有新数据包到达;另一种是上次的数据传输已完成。

④ 若是因为有新数据包到达,则调用接收数据包的子函数net_rx();

⑤ 如果中断是上次传输引起,则通知协议的上一层,修改接口的统计信息,关闭标志位tbusy,为下次传输做准备;

⑥ 关闭标志位interrupt。

CS8900A驱动程序的中断处理函数的实现代码如下:

void cs8900_interrupt(int irq, void *dev_id, struct pt_regs * regs) {

struct device *dev = (struct device *)(irq2dev_map[/* FIXME */0]);

struct net_local *lp; int ioaddr, status; dev = irq2dev_map[0]; dev->interrupt = 1;

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说教育文库嵌入式系统设计大学教程 - 习题与解答(8)在线全文阅读。

嵌入式系统设计大学教程 - 习题与解答(8).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/jiaoyu/687994.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: