专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
重发关于以太网中断处理函数——附代码篇
2019-03-24 14:28
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
TI MCU
3245
7
1526
如题!为什么在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
我测试过它的硬件速度,硬件应该完全跟得上软件的速度,既然如此,为什么还要加队列呢?
加载中...
查看其它7个回答
一周热门
更多
>
相关问题
相关文章
×
关闭
采纳回答
向帮助了您的知道网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
×
付费偷看金额在0.1-10元之间
确定
×
关闭
您已邀请
0
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
一周热门 更多>