前言
最近在学习zynq中的lwip协议族,找不到很好的记笔记的地方,所以就用csdn记录一下自己的学习过程。现在对lwip不熟悉,只是把官方的lwip echo server例程跑了一下,能跑通就一点点的照着学了,笔记都是根据自己的理解写的,而且部分内容可能也只针对lwip echo server例程有效,笔记可以供有缘人参考,但不敢保证全对,有不对的地方也期待有高人指点一二。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_40356705/article/details/136824649
一、概述
- 原型
s32_t xemacpsif_input(struct netif *netif)
- 参数
struct netif *netif :一个指向网络接口结构的指针。 - 作用
该函数主要功能是从网络接口读取数据包,并根据数据包类型进行相应的处理。
二、函数体
/*
* xemacpsif_input():
* 这个函数应当在数据包准备好从接口读取时被调用。
* 它使用low_level_input()函数来处理从网络接口实际接收字节的操作。
*/
s32_t xemacpsif_input(struct netif *netif)
{
struct eth_hdr *ethhdr; /* 定义以太网头部指针 */
struct pbuf *p; /* 定义pbuf指针,用于存储接收到的数据包 */
SYS_ARCH_DECL_PROTECT(lev); /* 声明用于保护系统架构的变量 */
#ifdef OS_IS_FREERTOS
while (1) /* 如果是在FreeRTOS环境下,进入无限循环 */
#endif
{
/* 使用系统架构提供的机制保护以下代码块 */
SYS_ARCH_PROTECT(lev);
/* 调用low_level_input函数读取数据包到pbuf */
p = low_level_input(netif);
/* 释放系统架构提供的保护 */
SYS_ARCH_UNPROTECT(lev);
/* 如果没有读取到数据包,则直接返回0 */
if (p == NULL) {
return 0;
}
/* ethhdr指向pbuf中的负载,即以太网头部 */
ethhdr = p->payload;
#if LINK_STATS
/* 如果定义了LINK_STATS,增加链路层接收统计 */
lwip_stats.link.recv++;
#endif /* LINK_STATS */
/* 根据以太网类型判断数据包类型 */
switch (htons(ethhdr->type)) {
/* 如果是以太网IP或ARP包 */
case ETHTYPE_IP:
case ETHTYPE_ARP:
#if LWIP_IPV6
/* 如果是IPv6包 */
case ETHTYPE_IPV6:
#endif
#if PPPOE_SUPPORT
/* 如果是PPPoE或PPPoE Discovery包 */
case ETHTYPE_PPPOEDISC:
case ETHTYPE_PPPOE:
#endif /* PPPOE_SUPPORT */
/* 将数据包发送到tcpip_thread进行处理 */
if (netif->input(p, netif) != ERR_OK) {//netif->input是一个函数在初始化时注册
/* 如果处理失败,打印调试信息并释放pbuf */
LWIP_DEBUGF(NETIF_DEBUG, ("xemacpsif_input: IP input error\r\n"));
pbuf_free(p);
p = NULL;
}
break;
/* 如果不是上述类型的包,则直接释放pbuf */
default:
pbuf_free(p);
p = NULL;
break;
}
}
/* 正常情况下,这里不会执行,因为前面有循环 */
return 1;
}
三、调用关系
被xemacif_input调用,调用了low_level_input及netif->input注册的函数