RTL8139有4个发送描述符,有各自的发送状态寄存器TSD0~TSD3和发送起始地址寄存器TSAD0~TSAD3,每个发送描述符可发送1个数据包。在函数Rtl8139Send()中申请1个发送数据包缓冲区,将协议栈传下来的数据包拷贝进该缓冲区,然后将该缓冲区的首地址写入发送起始地址寄存器,最后填写发送状态寄存器,并将其OWN位置0,表示将该缓冲区交给RTL8139的发送DMA管理,启动发送操作。发送完成后RTL8139产生中断,进人中断服务程序Rtl8139Int(),调用Rtl8139HandleSendInt(),在该函数中读取发送状态寄存器。如果OWN位为1,则表示发送DMA操作完成,释放相应的发送缓冲;否则表示发送DMA操作未完成,该发送缓冲仍由RTL8139硬件所有,下次进入发送中断再重新查看OWN位。如此循环往复,直到OWN位变为1,才能释放相应的发送缓冲,其占用的发送描述符变为可用。

以上过程可归结为两点:

a)在Rtl8139Send()中申请1个数据包缓冲区,占用1个发送描述符;

b)在Rtl8139Int()中释放相应的数据包缓冲区和发送描述符。

从以上分析可以看出,只要发包的这两个环节不出问题,发包流程就不会中断,另外,在Rtl8139HandleSendInt()中,不是仅仅释放1个包缓冲和描述符,而是将所有启动过发包操作、发送状态寄存器的OWN位变为1的描述符和相应包缓冲都释放掉。这样可增强程序的稳定性,在有突发包的情况下,CPU可能来不及响应中断,即造成中断丢失,但只要还有1个描述符可用,发包完成后能进中断,就可以把以前占用的缓冲和描述符全部释放掉。如果突发包太多,CPU连续4个发包中断未响应,发送描述符全被占用,下次进入Rtl8139Send()将无发送描述符可用,也就不会再有发包中断,Rtl8139HandleSendInt()不会被调用,发送描述符无法释放,发包流程就此中断,不能恢复,这就是上述RTL8139不能ping通的原因。

  • UC3846控制芯片工作原理控制图 逆变焊机原理与用途
  • 数字万用表电阻档测试二极管正反向没有阻值(使用万用表测量二极管的正向电阻,为什么各档)
  • 学单片机需要学数电模电吗(学单片机要先学数电模电吗)
  • 电工怎么选择适合自己用的万用表(电工初学者买什么样的万用表好)
  • 单片机需要同时运行多个任务怎么办(单片机怎么同时执行多个任务)
  • 电机保护的方案取决于负载的机械特性
  • 绝缘电阻表正负搭接不复零位是怎么回事
  • 短路怎么用万用表查