重发关于以太网中断处理函数——附代码篇

2019-03-24 14:28发布

如题!为什么在stellar_interrupt()这个函数中,只有在接收到数据时才处理接收和发送队列?发送队列为什么要依托于接收数据才能对其处理————这是几天前发的一个求问帖子!   “晕!你再仔细看看那部分代码,明明是先处理接收(p != NULL有接收时也一并处理发送),若没有接收则直接处理发送的。不要被#if/#else/#endif里面多余的的{误导了! ”这是fre777的回答!但是我不同意你的观点!   现在重发此贴!附源代码请教大家!                    以下这个函数是lwip的以太网中断处理函数(在startup_rvmdk.s(keil工具)或者start_ewarm.c(IAR工具)中注册的Ethernet中断处理函数),这个函数的路径一般是.....lm3s8962-4053-driveroardsek-lm3s8962enet_io(本人的驱动库是4053,因为我要用lwip1.3.0),其中核心处理函数是——stellarisif_interrupt()这个函数; 其代码的主要意思是只要有发送或者接收中断就调用stellarisif_interrupt()函数来处理。
void lwIPEthernetIntHandler(void)
{
    unsigned long ulStatus;
    ulStatus = EthernetIntStatus(ETH_BASE, false); /* 读取并清除中断状态 */
    EthernetIntClear(ETH_BASE, ulStatus);

    if(ulStatus)                                  /* 如果发送的是一个TX/RX中断,那么调用底层的中断处理函数*/
    {
        stellarisif_interrupt(&lwip_netif); // 核心函数,我的问题在这个函数里面!!!!!!!!!!!!!!!
    }
#if NO_SYS /*********************************************************************************************************
**如果系统没有使用一个RTOS,那么我们将所有的lwip处理都放在中断服务程序里面。在接收队列上服务任何的数据包
*********************************************************************************************************/
    stellarisif_input(&lwip_netif);     lwIPServiceTimers();                      /* LWIP的定时器事件服务*/
#endif
}
           那么接下来就要分析stellarisif_interrupt()这个函数了!!以下是源代码,其路径可通过:右键-Go To Definition 进入 或者 其路径一般是:.....lm3s8962-4053-driver hird_partylwip-1.3.0portsstellaris etif                         我在相应的代码后面附上一些注释来说明我的问题,在最后在综述一下!希望高人指点!   stellarisif_interrupt(struct netif *netif)
{
  struct ethernetif *ethernetif;
  struct pbuf *p;
  /* setup pointer to the if state data */
  ethernetif = netif->state;
  /**
   * Process the transmit and receive queues as long as there is receive
   * data available
   *
   */
 /*以下这段红 {MOD}的代码,我在这里逐一分析一下,中文注释都是我个人加上的!*/
  p = low_level_receive(netif);  //此函数的功能是:从以太网接口中读取一个数据包
  while(p != NULL) {   
 //只要接收的数据不为空,就进入while循环来对接收的数据包进行处理
    /* Add the rx packet to the rx queue */
    if(!enqueue_packet(p, ðernetif->rxq)) { 
//这个if{...}的意思是:如果将数据包发送到接收队列的操作不成功那么就丢弃这个数据包。
      /* Could not place the packet on the queue, bail out. */
      pbuf_free(p);
      break;
    }
     //  我们看,从进入while循环开始到这里为止都是对接收的数据包进行处理:也就是把“接收的数据包”——rx packet,送到“接收队列”——rx queue,    //那么我们在接着往下看,接下来这段代码(到分割线为止)是处理发送队列的操作,此操作首先做的是查看发送fifo是否为空和发送的数据包是否有效(参照英文注释)。如果条件成立    //              那么将从pbuf队列中pop(弹出、出栈的意思)出一个pbuf packet。然后调用lwip最底层的发送函数low_level_transmit(netif, p)来将这个弹出的数据包通过以太网接口(netif)发送走。
    /* Check if TX fifo is empty and packet available */
    if((HWREG(ETH_BASE + MAC_O_TR) & MAC_TR_NEWTX) == 0) {
      p = dequeue_packet(ðernetif->txq);
      if(p != NULL) {
        low_level_transmit(netif, p);   //最底层的发送函数,通过这个函数将弹出的数据包通过以太网接口(netif)发送走。
      }
    }
 /*至此,处理函数做了两件事:1、处理了通过 p = low_level_receive(netif)这句话接收的数据包。  2、“借”处理接收数据包的机会(为了形象的描述加上点一点点的生动的语言:L 惭愧中),来对发送队列进行处理.*/      //接下来在读取一个数据包,然后回到while循环开始新一轮的处理!!     /* Read another packet from the RX fifo */
    p = low_level_receive(netif);
  }
///////////////////////////////////////////////////分割线//////////////////////////////////////////////////////////////////////////////////////////////   /* One more check of the transmit queue/fifo */  /*请看上句英文注释——“再经行一次对发送队列的检查&&&&&&注意One more这个词(我理解是再一次)”,也就是怕在while循环中的对发送队列处理不完全,再检查处理一次!然后结束整个函数处理*/
  if((HWREG(ETH_BASE + MAC_O_TR) & MAC_TR_NEWTX) == 0) {
    p = dequeue_packet(ðernetif->txq);
    if(p != NULL) {
      low_level_transmit(netif, p);
    }
  }
}
   那么,我的问题出来了:为什么只有在接收到数据时才处理接发送队列?发送队列为什么要依托于接收数据才能对其处理(我们可以看到是先通过判断接收到的数据包是否有效,也就是如果不为空则进行接下来的处理,),在最后只是补充一次处理(One more),这样的处理方法能对发送队列处理完全吗?————也就是说如果没有接收到数据包,只是通过发送中断进入,那么就只能通过One more 这段代码来进行一次并且只有一次对发送队列的处理,这样的处理方法彻底吗??                         请教对lwip原理理解高深的高人进行指点!!!!!我的分析可能有误,请大家提出自己的观点!!谢谢!!        [ 本帖最后由 历史的天空 于 2011-2-20 23:29 编辑 ] 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
7条回答
maqinglong
2019-03-25 13:16
我测试过它的硬件速度,硬件应该完全跟得上软件的速度,既然如此,为什么还要加队列呢?

一周热门 更多>

相关问题

    相关文章