LWIP学习系列(二):STM32中ETH外设的配置与LWIP的结合使用_stm32 leip low_level_input()(2)

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

netif->name[1] = IFNAME1;
/* We directly use etharp_output() here to save a function call.

  • You can instead declare your own function an call etharp_output()
  • from it if you have to do some checks before sending (e.g. if link
  • is available…) */

#if LWIP_IPV4
#if LWIP_ARP || LWIP_ETHERNET
#if LWIP_ARP
netif->output = etharp_output;
#else
/* The user should write ist own code in low_level_output_arp_off function /
netif->output = low_level_output_arp_off;
#endif /
LWIP_ARP /
#endif /
LWIP_ARP || LWIP_ETHERNET /
#endif /
LWIP_IPV4 */

#if LWIP_IPV6
netif->output_ip6 = ethip6_output;
#endif /* LWIP_IPV6 */

netif->linkoutput = low_level_output;

/* initialize the hardware */
low_level_init(netif);

return ERR_OK;
}


* 由**lwip官方**下载的示例代码



err_t
ethernetif_init(struct netif *netif)
{
struct ethernetif *ethernetif;

LWIP_ASSERT(“netif != NULL”, (netif != NULL));

ethernetif = mem_malloc(sizeof(struct ethernetif));
if (ethernetif == NULL) {
LWIP_DEBUGF(NETIF_DEBUG, (“ethernetif_init: out of memory\n”));
return ERR_MEM;
}

#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname /
netif->hostname = “lwip”;
#endif /
LWIP_NETIF_HOSTNAME */

/*

  • Initialize the snmp variables and counters inside the struct netif.
  • The last argument should be replaced with your link speed, in units
  • of bits per second.
    */
    MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);

netif->state = ethernetif;
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
/* We directly use etharp_output() here to save a function call.

  • You can instead declare your own function an call etharp_output()
  • from it if you have to do some checks before sending (e.g. if link
  • is available…) /
    #if LWIP_IPV4
    netif->output = etharp_output;
    #endif /
    LWIP_IPV4 /
    #if LWIP_IPV6
    netif->output_ip6 = ethip6_output;
    #endif /
    LWIP_IPV6 */
    netif->linkoutput = low_level_output;

ethernetif->ethaddr = (struct eth_addr *) & (netif->hwaddr[0]);

/* initialize the hardware */
low_level_init(netif);

return ERR_OK;
}


**小结:**由上面两种程序对比,可以看出大同小异。基本上都是对**netif 网卡结构体进行赋值**,然后**真正的初始化**交由**low\_level\_init**来进行。


#### (3)**
### STM32Cube ETH LwIP `low_level_input` 示例及实现细节 #### 1. `low_level_input` 的功能作用 `low_level_input` 是 LwIP 协议栈中的一个关键函数,用于从硬件接收数据并将其传递给协议栈进行处理。在以太网外设中,当接收到数据包时,`low_level_input` 函数负责将数据包从硬件缓冲区复制到 LwIP 的 `pbuf` 数据结构中[^2]。 - **功能**: 将接收到的数据包从硬件缓冲区读取,并封装为 LwIP 的 `pbuf` 数据结构。 - **作用**: 在中断模式或轮询模式下,`low_level_input` 都是数据进入 LwIP 协议栈的入口点。 --- #### 2. `low_level_input` 的实现细节 以下是 `low_level_input` 的典型实现逻辑: ```c err_t low_level_input(struct netif *netif) { struct pbuf *p = NULL; struct eth_hdr *ethhdr; u8_t buf[1514]; // 缓冲区大小需根据最大帧长度设置 // 从硬件读取数据包 if (ethernet_read_packet(buf, sizeof(buf)) == ERR_OK) { // 创建 pbuf 并分配内存 p = pbuf_alloc(PBUF_RAW, sizeof(buf), PBUF_POOL); if (p != NULL && p->len == sizeof(buf)) { // 将数据复制到 pbuf 中 memmove(p->payload, buf, p->len); // 设置以太网头部信息 ethhdr = p->payload; NETIF_SET_LINK_UP(netif); // 将 pbuf 传递给上层协议 if (netif->input(p, netif) != ERR_OK) { LWIP_DEBUGF(NETIF_DEBUG, ("low_level_input: netif input error\n")); pbuf_free(p); // 如果上层协议处理失败,则释放 pbuf p = NULL; } } else { LWIP_DEBUGF(NETIF_DEBUG, ("low_level_input: pbuf alloc failed\n")); } } return p != NULL ? ERR_OK : ERR_VAL; } ``` --- #### 3. `low_level_input` 的调用场景 - **中断模式**: 在中断服务程序中,当以太网控制器检测到数据包到达时,会触发中断。在中断回调函数中调用 `ethernetif_input()`,该函数最终会调用 `low_level_input()` 来处理接收到的数据包[^2]。 - **轮询模式**: 在主循环中定期调用 `ethernetif_input()`,从而间接调用 `low_level_input()` 来检查是否有新的数据包需要处理。 --- #### 4. 相关文件函数 - **`ethernetif.c`**: 包含了以太网硬件 LwIP 数据交互的接口函数,例如 `ethernetif_input()` 和 `low_level_init()` 等[^2]。 - **`lwip_init.c`**: 负责初始化 LwIP 协议栈,并创建相关任务(如果使用 FreeRTOS)。 - **`stm32f4x7_eth.c`**: 提供了 STM32 以太网外设的底层驱动函数,例如 `HAL_ETH_ReadPacket()` 和 `HAL_ETH_Start()` 等[^2]。 --- #### 5. 注意事项 - **缓存一致性问题**: 在某些 STM32 系列中(如 H7 系列),需要特别注意缓存一致性问题。如果使用了 MPU(存储保护单元),可能需要清空或无效化缓存[^3]。 - **内存分配**: `pbuf` 的分配需要确保有足够的内存池空间。如果内存不足,可能导致数据包丢失。 - **中断优先级**: 在中断模式下,合理配置以太网控制器的中断优先级可以提高系统的实时性[^2]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值