STM32 以太网接收数据流程 (基于UCOS II+LWIP)

🔥基于正点原子STM32F4 扩展例程,网络实验8 NETCONN_TCP 客户端
🔥基于正点原子STM32F4 扩展例程,网络实验8 NETCONN_TCP 客户端
🔥基于正点原子STM32F4 扩展例程,网络实验8 NETCONN_TCP 客户端
所用内容都是自己的理解,若有问题请及时指出

1、配置说明

  lwip_comm_init()做了如下几件事:

函数名说明
ETH_Mem_Malloc()为DMA发送和接收描述符以及数组申请内存(DMARxDscrTab、DMATxDscrTab、Rx_Buff、Tx_Buff)
lwip_comm_mem_malloc()为LWIP内存池和内存堆申请内存(mem、memp)
LAN8720_Init()初始化LAN8720接口、配置MAC、以太网DMA中断
tcpip_init(NULL,NULL)详细见下
lwip_comm_default_ip_set(&lwipdev)设置默认的IP地址端口等信息
netif_add(…)详细见下
netif_set_default(&lwip_netif)设置默认网口
netif_set_up(&lwip_netif)打开网口

1.1 tcpip_init

tcpip_init(NULL,NULL)这个函数主要完成:
   1、lwip_init():初始化TCPIP内核。
   函数内部调用了sys_timeouts_init();注册了超时处理函数,主要用作是在各种超时的情况下,跳转到对应的超时处理函数。例如ARP缓存表项的时间管理、IP分片数据报的重装等待超时、TCP中的建立连接超时、重传超时机制等,因此超时处理的实现是 TCP/IP 协议栈中一个重要部分。调用定时器注册函数sys_timeout注册进入超时管理链表中。参考:超时处理\定时器
   2、sys_mbox_new(&mbox, TCPIP_MBOX_SIZE):创建消息邮箱。
   主要是为之后以太网接收到数据后,将数据经过处理成的pbuf指针和网口netif指针传递到邮箱中供tcpip_thread任务调用处理消息,将消息进一步向上传递和处理。
   3、sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO):创建tcpip_thread任务。
   这是整个LWIP创建的一个信息处理的任务,用于处理接收到的消息以及处理超时处理事件。

1.2 netif_add

netif_add(&lwip_netif,&ipaddr,&netmask,&gw,NULL,&ethernetif_init,&tcpip_input);这个函数主要完成对网口的初始化,将IP地址、子网掩码、网关等参数初始化到lwip_netif网口结构体中,同时注册两个函数 ethernetif_init以及网卡接收数据函数 tcpip_input。
   netif_add函数内部会调用注册的ethernetif_init函数进一步完成初始化,ethernetif_init函数完成赋值网口的名字为“en”,注册发送数据函数etharp_output,注册ARP模块发送数据包函数low_level_output,最后调用low_level_init(netif),在low_level_init中赋值网口的MAC地址,最大传输的数据量1500字节,设置网口的功能最后使能TCP、UDP和ICMP的发送帧校验。
   这些配置完成后就是创建TCP连接、连接服务器等不是本文的重点这里不介绍,参考正点原子的例程。

2、接收数据流程

  假设某一时刻来数据消息了,最先进入的是以太网DMA接收中断

ETH_IRQHandler

   ETH_IRQHandler函数内部调用

lwip_pkt_handle

  lwip_pkt_handle再调用

ethernetif_input(&lwip_netif)

   ethernetif_input内部会调用:

   1、p=low_level_input(netif); 这个函数返回一个pbuf类型的数据, 将接收到的数据通过ETH_Rx_Packet函数(low_level_input内部调用)处理后放入pbuf中(数据包大小和数据包地址)返回指针p。
   2、err=netif->input(p, netif);将上面low_level_input函数得到的pubf数据包和netif网口数据放入netif->input函数,这个函数就是上一节的netif_add注册的tcpip_input函数。

tcpip_input

   此函数将pbuf和netif封装进msg,同时msg的类型被定义为TCPIP_MSG_INPKT,之后通过函数:

sys_mbox_trypost(&mbox, msg)

   这个函数会通过OSQPost发送信息到邮箱中

OSQPost((*mbox)->pQ, msg)
   此时在UCOSII的任务调度中会访问之前LWIP创建的tcpip_thread任务,在此任务中通过:
sys_timeouts_mbox_fetch(&mbox, (void **)&msg);
  此函数来判断邮箱中有无数据以及对超时事件的处理,这个函数让线程既阻塞等待消息又能执行周期性任务。通过消息邮箱来完成数据的向上传递,此后进一步会处理接收到的数据。最后通过netconn_recv(tcp_clientconn,&recvbuf)函数来获取最终得到的数据。至于怎么通过netconn_recv获得数据的下次再更新。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值