【无OS】基于STM32移植LWIP 1.4.1之Ping

1.前言

在STM32平台移植LWIP 1.4.1实现Ping功能,首先需要做一些准备工作,例如:

  1. 《基于STM32移植LWIP的资料准备》
  2. 《基于STM32移植LWIP硬件相关介绍》

移植的目标平台是STM32F429,在以前资料准备中有提到STM32官网有STM32F4x7微控制器的LwIP TCP/IP协议栈的演示代码,我们在很大程度上可以参考移植到目标平台。

下面介绍的移植过程是基于硬件平台STM32F429,在移植了STM32标准库的基础上面进行的。

2.Main函数

首先我们移植的是main函数,因为它是整个程序的入口。我们可以参考下载的STM32F4x7 LwIP TCP/IP协议栈演示代码:
PATH:STM32F4x7_ETH_LwIP_V1.1.1\Project\Standalone\tcp_echo_client\src\main.c
通过参考代码我们需要实现以下任务:

  • SysTick_Init,初始化STM32的工作系统时钟;
  • TIM3_Int_Init,初始化Timer3,并且作为LwIP协议栈需要的本地时间心跳。
  • ETH_BSP_Config,配置以太网GPIO和DMA,通过SMI接口设置PHY网卡(LAN8742A)相关寄存器。
  • LwIP_Init,初始化LwIP协议栈;
  • 通过ETH_CheckFrameReceived循环检测是否有接收到数据包,LwIP_Pkt_Handle处理接收到的网络数据包。
  • LwIP_Periodic_Handle,处理LwIP周期性任务;
int main(void)
{
    
    
	...
	
	// init systick
	SysTick_Init();

	//init timer3 10ms
	TIM3_Int_Init(100-1,8400-1);
	
	/* Configure ethernet (GPIOs, clocks, MAC, DMA) */
	ETH_BSP_Config();
	
	/* Initilaize the LwIP stack */
	LwIP_Init();

	while(1){
    
    		
		/* check if any packet received */
		if (ETH_CheckFrameReceived())
		{
    
     
		  /* process received ethernet packet */
		  LwIP_Pkt_Handle();
		}
		/* handle periodic timers for LwIP */
		LwIP_Periodic_Handle(os_get_tick_counter());
	}

	//return 0;
}

3.配置以太网(GPIOs, MAC, DMA)

配置以太网,我们可以参考下载的STM32F4x7 LwIP TCP/IP协议栈演示代码:
PATH:STM32F4x7_ETH_LwIP_V1.1.1\Project\Standalone\tcp_echo_client\src\stm32f4x7_eth_bsp.c
将GPIO配置为以太网功能,MAC和DMA的配置直接按照参考代码。

备注:在配置以太网的时候,需要外部的PYH地址。前面硬件介绍时有提及到,应该被设置成PHYAddress = 0

void ETH_BSP_Config(void)
{
    
    
  /* Configure the GPIO ports for ethernet pins */
  ETH_GPIO_Config();

  /* Configure the Ethernet MAC/DMA */
  ETH_MACDMA_Config();

  /* Get Ethernet link status*/
  if(GET_PHY_LINK_STATUS())
  {
    
    
    EthStatus |= ETH_LINK_FLAG;
  }
}

4.将LwIP添加到工程

STM32F4x7 LwIP TCP/IP协议栈演示代码中的LwIP拷贝到当前工程:
PATH:STM32F4x7_ETH_LwIP_V1.1.1\Utilities\Third_Party\lwip-1.4.1
把需要编译的LwIP源文件添加到IDE工具,我这里使用的时Keil工具。

  • LwIP 源码太大了,我们不需要那么多东西,所以我们只需要将 LwIP 源码
    中的 src 文件文件夹添加进去即可。

  • 分别将apicorenetif添加到Keil工程中

  • 将STM32F4x7平台的以太网驱动拷贝到当前工程,并且重命名为STM32F429:
    PATH:STM32F4x7_ETH_LwIP_V1.1.1\Libraries\STM32F4x7_ETH_Driver

  • 在工程中添加 LwIP 头文件路径,并且把 C99 模式也勾选上,添加完成的示意图如下:

5.解决编译报错的问题

  • 错误1
    error: #5: cannot open source input file "lwip/opt.h": No such file or directory
    解决办法
    确认是否正确添加头文件路径,lwip-1.4.1\src\include
  • 错误2
    ..\lwip-1.4.1\src\include\lwip/opt.h(45): error: #5: cannot open source input file "lwipopts.h": No such file or directory
    解决办法
    STM32F4x7 LwIP TCP/IP协议栈演示代码中的lwipopts.h拷贝到当前工程,
    PATH:STM32F4x7_ETH_LwIP_V1.1.1\Project\Standalone\tcp_echo_client\inc\lwipopts.h

    备注:lwipopts.h就是用于配置 LwIP 的相关参数的,一般来说 LwIP 默认会有参数的配置,存放在 opt.h文件中,如果用户没有在lwipopts.h 文件进行配置,那么 LwIP 就会使用 opt.h默认的参数,注意,在移植的时候出现定义某些参数是非常重要的,这对我们 LwIP 的性能至关重要,甚至在配置错误的时候能直接导致 LwIP 的运行崩溃。这里我只是实现简单的Ping功能,所以直接使用默认配置就可以了。

  • 错误3
    ..\lwip-1.4.1\src\include\lwip/arch.h(43): error: #5: cannot open source input file "arch/cc.h": No such file or directory
    解决办法
    lwip-1.4.1\port\STM32F4x7\arch\cc.h拷贝到当前工程并且添加到系统头文件路径。

    备注:cc.h文件中包含处理器相关的变量类型、数据结构及字节对齐的相关宏。
    LwIP 中使用的基本变量类型均以位数进行命名,为抽象的变量类型定义,开发者需要根据所用处理器及编译器特性进行定义,一般我们直接将变量直接定义为 C语言的基本类型,如 unsigned char、int等,这样子可以保证 LwIP 协议栈就与平台无关了。除此之外我们还可以定义大小端模式,输出调试的宏等。

  • 错误4
    Error: L6218E: Undefined symbol LwIP_Init (referred from main.o).
    Error: L6218E: Undefined symbol LwIP_Periodic_Handle (referred from main.o).
    Error: L6218E: Undefined symbol LwIP_Pkt_Handle (referred from main.o).
    解决办法
    前面移植main函数时是直接参考拷贝过来,但是并未真正的实现这些函数。我们可以继续参考下载的STM32F4x7 LwIP TCP/IP协议栈演示代码:
    PATH:STM32F4x7_ETH_LwIP_V1.1.1\Project\Standalone\tcp_echo_client\src\netconf.c
    并将其拷贝到当前工程,然后重新编译。
  • 错误5
    netconf.c(36): error: #5: cannot open source input file "ethernetif.h": No such file or directory
    解决办法
    我们可以将lwip-1.4.1\port\STM32F4x7\Standalone\ethernetif.h拷贝到当前工程,但是发现还是有很多的函数并没有实现。因为我们添加的是lwip-1.4.1的模板(lwip-1.4.1\src\netif\ethernetif.c),每个平台这个文件需要定制化。这里有参考代码(lwip-1.4.1\port\STM32F4x7\Standalone\ethernetif.c),将其添加到当前工程并重新编译。

    备注:ethernetif.c主要是网卡有关的底层驱动函数。

6.验证测试

最后验证测试成功,如下:
在这里插入图片描述

7.资料下载地址

移植成功的完整代码下载地址如下:
https://download.csdn.net/download/ZHONGCAI0901/12921796

猜你喜欢

转载自blog.csdn.net/ZHONGCAI0901/article/details/109022185
今日推荐