目录
1. lwIP添加到工程
2. 添加头文件
3. 修改网卡驱动
4. lwIP 时基
5. 协议栈初始化
6. 获取数据包
6.1 查询方式
6.2 中断方式
7. ping 命令和ipconfig命令
如上图,把源码中src 添加到工程,并添加LwIP 头文件路径。比较简单,不做赘述
lwipopts.h、cc.h、pref.h,并放入 新建的/arch 目录。
在之前有说明相关的配置,这里直接从“contrib-2.1.0 官方例程中拷贝,并修改。
参考contrib-2.1.0\examples\ethernetif 修改。
实现sys_now()函数来获取系统的时钟,以毫秒为单位,LwIP 通过两次获取的时间就能判断是否有超时,从而让内核去处理对应的事件。一般用滴答定时器产生1ms的基准,并关联该函数。
使用LwIP,那就必须先将协议栈初始化,我们就创建一个函数,在函数中初始化协议栈,注册网卡,设置主机的IP 地址、子网掩码、网关地址等。
挂载网卡的函数netif_add()。注意器
void LwIP_Init(void)
{
/* IP addresses initialization */
/* USER CODE BEGIN 0 */
#ifdef USE_DHCP
ip_addr_set_zero_ip4(&ipaddr);
ip_addr_set_zero_ip4(&netmask);
ip_addr_set_zero_ip4(&gw);
#else
IP4_ADDR(&ipaddr,IP_ADDR0,IP_ADDR1,IP_ADDR2,IP_ADDR3);
IP4_ADDR(&netmask,NETMASK_ADDR0,NETMASK_ADDR1,NETMASK_ADDR2,NETMASK_ADDR3);
IP4_ADDR(&gw,GW_ADDR0,GW_ADDR1,GW_ADDR2,GW_ADDR3);
#endif /* USE_DHCP */
/* USER CODE END 0 */
/* Initilialize the LwIP stack without RTOS */
lwip_init();
/* add the network interface (IPv4/IPv6) without RTOS */
netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input);
/* Registers the default network interface */
netif_set_default(&gnetif);
if (netif_is_link_up(&gnetif))
{
/* When the netif is fully configured this function must be called */
netif_set_up(&gnetif);
}
else
{
/* When the netif link is down this function must be called */
netif_set_down(&gnetif);
}
/* USER CODE BEGIN 3 */
/* USER CODE END 3 */
}
netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input); --> ethernet_input()
获取数据包的方式有两种,一种是查询方式,另一种是中断方式。查询方式通过主函数的while 循环进行周期性处理,去获取网卡中是否接收到数据包,然后递交给上层协议去处理,而中断方式则不一样,在网卡接收到一个数据包的时候,就触发中断,通知CPU 去处理,这样子效率就会高很多,特别是在操作系统环境下,我们都采用中断方式去获取数据包。
方式需底层驱动配置支持,在初始化的时候,如果网卡接收模式被配置为ETH_RXINTERRUPT_MODE,则表示使用
中断方式获取数据包,而如果网卡接收模式被配置为ETH_RXPOLLING_MODE 则表明用查询方式获取数据包。
使用查询方式获取数据包的时候,我们只需要在程序中周期性调用网卡接收函数即可
int main(void)
{
//板级外设初始化
BSP_Init();
//LwIP协议栈初始化
LwIP_Init();
while (1)
{
//调用网卡接收函数
ethernetif_input(&gnetif);
//处理LwIP中定时事件
sys_check_timeouts();
}
}
中断方式来接收数据,当接收完成的时候,就通知CPU 来处理即可,效率会比较高
int flag = 0;
int main(void)
{
//板级外设初始化
BSP_Init();
//LwIP协议栈初始化
LwIP_Init();
while (1)
{
if(flag)
{
flag = 0;
//调用网卡接收函数
ethernetif_input(&gnetif);
}
//处理LwIP中定时事件
sys_check_timeouts();
}
}
void ETH_IRQHandler(void)
{
HAL_ETH_IRQHandler(&heth);
}
/**
* @brief Ethernet Rx Transfer completed callback
* @param heth: ETH handle
* @retval None
*/
extern int flag ;
void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
{
flag = 1;
// LWIP_Process();
}
https://blog.csdn.net/XieWinter/article/details/99962809
执行“arp -a”命令,可以看到电脑主机的ARP 表,我们开发板的IP地址与MAC 地址都正确出现在ARP 表。
总结:无操作系统移植相对比较简单,需要主要该方式只能使用lwIP raw API接口
例程:https://download.csdn.net/download/xiewinter/11588610