🔥基于正点原子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,ðernetif_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函数内部调用
lwip_pkt_handle再调用
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函数。
此函数将pbuf和netif封装进msg,同时msg的类型被定义为TCPIP_MSG_INPKT,之后通过函数:
这个函数会通过OSQPost发送信息到邮箱中