cs8900网卡驱动简要解析(5)

上次说到的cs8900_start函数中,完成了中断申请任务。什么是中断?中断是一种电信号,由硬件设备产生,并直接送入中断控制器的输入引脚上,然后再由中断控制器向处理器发送相应的信号。

 

其中中断处理函数cs8900_interrupt没有讲。中断处理函数是中断发生时系统要执行的函数。本文将主要介绍中断处理函数的功能。我们不分析中断实现机制,而是关心中断发生时,要做哪些事情。要知道,中断处理函数设计的好坏,会直接关心到性能乃至稳定问题。

 

虽然我不会讲中断的实现,但是你必须清楚中断的两种类型:

1.        轮询(polling 让内核定期对设备的状态进行查询,然后做出相应的处理;

2.        中断(interrupt 让硬件在需要的时候向内核发出信号(变内核主动为硬件主动)。

 

如果你对中断的实现感兴趣,你应该去了解hw_interrupt_typeirq_desc_t irqaction这些数据结构。

 

我们的中断处理函数通过switch/case语句判断中断类型,并进行相应处理。具体过程是:首先读出ISQ寄存器的值,然后根据ISQ的值分别处理各种情况。当中断发生时,这些中断实际反映在相应的寄存器中,ISQ寄存器用低6位记录了当前寄存器的编号,高10位记录了当前寄存器的实际内容。代码如下:

while ((status = cs8900_read (dev, PP_ISQ))) {

handled = 1;

switch (RegNum (status)) {

case RxEvent:               //接收到了数据包

cs8900_receive (dev);

break;

 

case TxEvent:               //根据open中的设置,分别处理各种类型的发送事件。

priv->stats.collisions += ColCount (cs8900_read (dev,PP_TxCOL));

if (!(RegContent (status) & TxOK)) {

priv->stats.tx_errors++;

if ((RegContent (status) & Out_of_window)) priv->stats.tx_window_errors++;

if ((RegContent (status) & Jabber)) priv->stats.tx_aborted_errors++;

break;

} else if (priv->txlen) {

priv->stats.tx_packets++;

priv->stats.tx_bytes += priv->txlen;

}

priv->txlen = 0;

netif_wake_queue (dev);

break;

case BufEvent:              //两种情况,分别进行处理。

//RxMiss置位,表示传输过程中丢帧,于是读寄存器获取丢失的包的数目。

                            if ((RegContent (status) & RxMiss)) {

                                     u16 missed = MissCount (cs8900_read (dev,PP_RxMISS));

                                     priv->stats.rx_errors += missed;

                                     priv->stats.rx_missed_errors += missed;

                            }

//TxUnderrun置位,表示在帧结束前网卡运行已过时。改变网络状态结构体中对应元素的值,接着通知上层可往下发送包数据。

                            if ((RegContent (status) & TxUnderrun)) {

                                     priv->stats.tx_errors++;

                                     priv->stats.tx_fifo_errors++;

 

                                     priv->txlen = 0;

                                     netif_wake_queue (dev);

                            }

                            /* FIXME: if Rdy4Tx, transmit last sent packet (if any) */

                            break;

 

                   case TxCOL:                //当传输出现冲突错误时,通过读寄存器值得到当前冲突的个数,加到统计结构体中的对应元素值上。

                            priv->stats.collisions += ColCount (cs8900_read (dev,PP_TxCOL));

                            break;

 

                   case RxMISS:              //读寄存器获取丢失帧的个数。

                            status = MissCount (cs8900_read (dev,PP_RxMISS));

                            priv->stats.rx_errors += status;

                            priv->stats.rx_missed_errors += status;

                            break;

                   }

 

其中的细节我们下次再说。

 

一句话总结:中断处理函数是中断产生时执行的函数,它根据中断种类进行处理。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值