Lwip移植过程(基于FreeRTOS v10.2.1)

Lwip移植过程(基于FreeRTOS)

准备过程

  • 首先准备带FreeRTOS的工程模板,如下图所示;

  • Lwip移植过程(基于FreeRTOS v10.2.1)_第1张图片

  • 下载LWIP源码,这里使用2.1.2版本,官网下载地址,拷贝源码到工程中去,如下图所示;

Lwip移植过程(基于FreeRTOS v10.2.1)_第2张图片

将LwIP源文件添加到工程中去

  • LWIP/api

Lwip移植过程(基于FreeRTOS v10.2.1)_第3张图片

  • LWIP/core

Lwip移植过程(基于FreeRTOS v10.2.1)_第4张图片

  • LWIP/core/ipv4

Lwip移植过程(基于FreeRTOS v10.2.1)_第5张图片

  • LWIP/netif

Lwip移植过程(基于FreeRTOS v10.2.1)_第6张图片

添加头文件信息

Lwip移植过程(基于FreeRTOS v10.2.1)_第7张图片

移植修改

  1. 编译后发现很多error,如下图所示
    Lwip移植过程(基于FreeRTOS v10.2.1)_第8张图片

  2. 添加lwipopts.h,在源码文件夹test\fuzz下可以找到该文件,如下图所示,该文件主要用于Lwip参数的配置,供用户修改,默认参数配置在opt.h文件中配置;
    Lwip移植过程(基于FreeRTOS v10.2.1)_第9张图片

  3. lwip-2.1.2文件夹下创建user文件夹,放置网络相关的用户配置文件,如下图所示
    Lwip移植过程(基于FreeRTOS v10.2.1)_第10张图片

  4. 添加lwipopts.h头文件路径,如下图所示
    Lwip移植过程(基于FreeRTOS v10.2.1)_第11张图片

  5. 再次编译,缺少arch/cc.h文件,如下图所示
    Lwip移植过程(基于FreeRTOS v10.2.1)_第12张图片

  6. 添加arch/cc.h文件,将下图文件夹下的3个*.h拷到lwip-2.1.2/user/arch*文件夹下
    Lwip移植过程(基于FreeRTOS v10.2.1)_第13张图片

  7. 修改cc.h文件内容如下

/*
 * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 *
 * This file is part of the lwIP TCP/IP stack.
 *
 * Author: Adam Dunkels 
 *
 */
#ifndef __ARCH_CC_H__
#define __ARCH_CC_H__

/* Include some files for defining library routines */
#include  /* printf, fflush, FILE */
#include 
#include  /* abort */
//#include 
#if (!defined(__CC_ARM)) && (!defined(__ARMCC_VERSION)) && (!defined(__ICCARM__))
#include 
#endif

#include "FreeRTOSConfig.h"

#ifndef BYTE_ORDER
#define BYTE_ORDER  LITTLE_ENDIAN
#endif

#define LWIP_PLATFORM_BYTESWAP 0

/** @todo fix some warnings: don't use #pragma if compiling with cygwin gcc */
//#ifndef __GNUC__
#if (!defined(__ICCARM__)) && (!defined(__GNUC__)) && (!defined(__CC_ARM))
	#include 
	#pragma warning (disable: 4244) /* disable conversion warning (implicit integer promotion!) */
	#pragma warning (disable: 4127) /* conditional expression is constant */
	#pragma warning (disable: 4996) /* 'strncpy' was declared deprecated */
	#pragma warning (disable: 4103) /* structure packing changed by including file */
#endif

#define LWIP_PROVIDE_ERRNO

#if ( configUSE_POSIX_ERRNO == 1 )
extern int FreeRTOS_errno;
#ifndef errno
#define errno FreeRTOS_errno
#endif
#endif

/* Define generic types used in lwIP */
#define LWIP_NO_STDINT_H    1
typedef unsigned   char    u8_t;
typedef signed     char    s8_t;
typedef unsigned   short   u16_t;
typedef signed     short   s16_t;
typedef unsigned   long    u32_t;
typedef signed     long    s32_t;

typedef size_t mem_ptr_t;
typedef u32_t sys_prot_t;



/* Define (sn)printf formatters for these lwIP types */
#define X8_F  "02x"
#define U16_F "hu"
#define S16_F "hd"
#define X16_F "hx"
#define U32_F "lu"
#define S32_F "ld"
#define X32_F "lx"
#define SZT_F U32_F


/* Compiler hints for packing structures */
#if defined(__ICCARM__)
#define PACK_STRUCT_STRUCT __packed
#else
#define PACK_STRUCT_STRUCT __attribute__( (packed) )
#endif

#if 0
#ifndef LWIP_DEBUG_USE_PRINTF
#define LWIP_LOGE(fmt,arg...)   LOG_E(lwip, "[lwip]: "fmt,##arg)
#define LWIP_LOGW(fmt,arg...)   LOG_W(lwip, "[lwip]: "fmt,##arg)
#define LWIP_LOGI(fmt,arg...)   LOG_I(lwip ,"[lwip]: "fmt,##arg)
#endif
#endif

#ifdef LWIP_DEBUG_USE_PRINTF
/* Plaform specific diagnostic output */
#define LWIP_PLATFORM_DIAG(x)   do { printf x; } while(0)
#else
#define LWIP_PLATFORM_DIAG(x)   do { printf(x) ; } while(0)
#endif

#define LWIP_PLATFORM_ASSERT(x) do {printf("Assertion \"%s\" failed at line %d in %s\n", \
                                     x, __LINE__, __FILE__); fflush(NULL); abort();} while(0)


//#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \
//  printf(("Assertion \"%s\" failed at line %d in %s\n", message, __LINE__, __FILE__)); \
//  handler;} } while(0)


/* C runtime functions redefined */
//#define snprintf _snprintf //2015-07-22 Cheng Liu @132663

u32_t dns_lookup_external_hosts_file(const char *name);

#define LWIP_RAND() ((u32_t)rand())

#endif /* __ARCH_CC_H__ */


  1. 修改lwipopt.h文件内容,代码如下
/*
 * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
 * All rights reserved. 
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
 * OF SUCH DAMAGE.
 *
 * This file is part of the lwIP TCP/IP stack.
 * 
 * Author: Simon Goldschmidt
 *
 */
#ifndef LWIP_HDR_LWIPOPTS_H__
#define LWIP_HDR_LWIPOPTS_H__

/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */
/* NO_SYS=1 无操作系统,0有操作系统,这里使用FreeRTOS */
#define NO_SYS                          0   
#define LWIP_TIMERS                     1
#define SYS_LIGHTWEIGHT_PROT            1

#define LWIP_NETCONN                    0
#define LWIP_SOCKET                     0
#define SYS_LIGHTWEIGHT_PROT            0

#define LWIP_IPV6                       0
#define IPV6_FRAG_COPYHEADER            0
#define LWIP_IPV6_DUP_DETECT_ATTEMPTS   0

/* Enable some protocols to test them */
#define LWIP_DHCP                       0
#define LWIP_AUTOIP                     0

#define LWIP_IGMP                       1
#define LWIP_DNS                        1

#define LWIP_ALTCP                      1

/* Turn off checksum verification of fuzzed data */
#define CHECKSUM_CHECK_IP               0
#define CHECKSUM_CHECK_UDP              0
#define CHECKSUM_CHECK_TCP              0
#define CHECKSUM_CHECK_ICMP             0
#define CHECKSUM_CHECK_ICMP6            0

/* Minimal changes to opt.h required for tcp unit tests: */
#define MEM_SIZE                        16000
#define TCP_SND_QUEUELEN                40
#define MEMP_NUM_TCP_SEG                TCP_SND_QUEUELEN
#define TCP_OVERSIZE                    1
#define TCP_SND_BUF                     (12 * TCP_MSS)
#define TCP_WND                         (10 * TCP_MSS)
#define LWIP_WND_SCALE                  1
#define TCP_RCV_SCALE                   2
#define PBUF_POOL_SIZE                  400 /* pbuf tests need ~200KByte */

/* Minimal changes to opt.h required for etharp unit tests: */
#define ETHARP_SUPPORT_STATIC_ENTRIES   1

#define LWIP_NUM_NETIF_CLIENT_DATA      1
#define LWIP_SNMP                       1
#define MIB2_STATS                      1
#define LWIP_MDNS_RESPONDER             1

#endif /* LWIP_HDR_LWIPOPTS_H__ */

  1. 添加带操作系统的网络接口文件sys_arch.csys_arch.h
    Lwip移植过程(基于FreeRTOS v10.2.1)_第14张图片
    Lwip移植过程(基于FreeRTOS v10.2.1)_第15张图片

  2. 在工程中添加sys_arch.c

  • LWIP/arch

  1. 再次编译,出现错误,是因为在网络接口的文件下添加了slipif.c SLIP组件文件,这里屏蔽掉就好,再次编译就好;其实在lwipopt.h中也可以删除了ipv6的宏定义,工程文件中的很多网络接口都可以屏蔽掉,根据使用情况添加即可。
    Lwip移植过程(基于FreeRTOS v10.2.1)_第16张图片
    Lwip移植过程(基于FreeRTOS v10.2.1)_第17张图片

添加PHY驱动

物理层驱动芯片:DM9161

Lwip移植过程(基于FreeRTOS v10.2.1)_第18张图片

驱动参考MDK的例程进行修改,若采用的芯片与官方提供的一致,可直接使用,仅需更改物理地址即可;
MDK下的驱动路径如下图所示,在ETH文件夹内;
也可以使用MDK官方提供的模板,在MDK安装路径下可以找到。

Lwip移植过程(基于FreeRTOS v10.2.1)_第19张图片

  1. 在工程文件的user目录下添加以太网驱动文件夹ETH_driver,并添加MDK文件夹下的驱动,这里我们复制如下图所示的文件,并修改文件名为自己的驱动芯片,该文件内容一般不需要做任何改动即可使用
    Lwip移植过程(基于FreeRTOS v10.2.1)_第20张图片
    Lwip移植过程(基于FreeRTOS v10.2.1)_第21张图片
  2. 添加文件到工程中去,并添加头文件路径


Lwip移植过程(基于FreeRTOS v10.2.1)_第22张图片

  1. 修改驱动芯片相应的寄存器映射地址,在PHY_XXXX.h中修改,这里根据字节使用的芯片手册进行更改即可。

添加MAC驱动

说明:MAC驱动在MDK安装包里也有,在D:\Keil_v5\ARM\PACK\Keil路径下,如下图所示,选择相应文件下的驱动即可

Lwip移植过程(基于FreeRTOS v10.2.1)_第23张图片

  1. 我这里使用的是STM32H7xx的芯片,复制下图中的文件到user/ETH_Driver目录下,并添加到工程中去
    Lwip移植过程(基于FreeRTOS v10.2.1)_第24张图片
    Lwip移植过程(基于FreeRTOS v10.2.1)_第25张图片Lwip移植过程(基于FreeRTOS v10.2.1)_第26张图片
  2. 添加驱动头文件
    Lwip移植过程(基于FreeRTOS v10.2.1)_第27张图片
    Lwip移植过程(基于FreeRTOS v10.2.1)_第28张图片
  3. 编译会发现缺少MX_Device.h文件,如下图所示
  4. 添加MX_Device.h文件,我们需要到MDK的目录下去搜索,比如我这里用的STM32H7xx,那么就再如下图文件夹下搜索,其实都是官方开发板下的demo,检索完,单开任意一个复制其文件就行
    Lwip移植过程(基于FreeRTOS v10.2.1)_第29张图片
    Lwip移植过程(基于FreeRTOS v10.2.1)_第30张图片
  5. 修改MX_Device.h文件内容,该文件主要定义了官方开发板的一些管脚使用信息,这里我们不需要删掉即可,

Lwip移植过程(基于FreeRTOS v10.2.1)_第31张图片

修改后内容如下:

/******************************************************************************
 * File Name   : MX_Device.h
 * Date        : 06/06/2019 08:02:00
 * Description : STM32Cube MX parameter definitions
 * Note        : This file is generated by STM32CubeMX (DO NOT EDIT!)
 ******************************************************************************/

#ifndef __MX_DEVICE_H
#define __MX_DEVICE_H

/*---------------------------- Clock Configuration ---------------------------*/

#define MX_LSI_VALUE                            32000
#define MX_LSE_VALUE                            32768
#define MX_HSI_VALUE                            64000000
#define MX_HSE_VALUE                            25000000
#define MX_EXTERNAL_CLOCK_VALUE                 12288000
#define MX_PLLDSIFreq_Value                     500000000
#define MX_SYSCLKFreq_VALUE                     400000000
#define MX_HCLKFreq_Value                       100000000
#define MX_CortexFreq_Value                     400000000
#define MX_APB1Freq_Value                       25000000
#define MX_APB2Freq_Value                       25000000
#define MX_CECFreq_Value                        32000
#define MX_RTCFreq_Value                        32000
#define MX_USBFreq_Value                        400000000
#define MX_WatchDogFreq_Value                   32000
#define MX_DSIFreq_Value                        96000000
#define MX_DSIPHYCLKFreq_Value                  96000000
#define MX_DSITXEscFreq_Value                   20000000
#define MX_SPDIFRXFreq_Value                    400000000
#define MX_MCO1PinFreq_Value                    64000000
#define MX_MCO2PinFreq_Value                    400000000


/*-------------------------------- CORTEX_M7  --------------------------------*/

#define MX_CORTEX_M7                            1

/* GPIO Configuration */

/*-------------------------------- SYS        --------------------------------*/

#define MX_SYS                                  1

/* GPIO Configuration */

/*-------------------------------- NVIC       --------------------------------*/

#define MX_NVIC                                 1

/*-------------------------------- GPIO       --------------------------------*/

#define MX_GPIO                                 1

/* GPIO Configuration */

#endif  /* __MX_DEVICE_H */


  1. 重新编译,发现缺少定义

    DMARxDscrTab 以太网 Rx DMA描述符
    DMATxDscrTab 以太网 Tx DMA描述符
    Rx_Buff 以太网 接收缓存

Lwip移植过程(基于FreeRTOS v10.2.1)_第32张图片
Lwip移植过程(基于FreeRTOS v10.2.1)_第33张图片
6. 在EMAC_STM32H7XX.c文件头中,我们可以找到如下说明,我们可以根据该说明新建一个ETH_Configuration.c文件,并按照说明实现即可

Configuration tab
-----------------
  1. Under Connectivity open \b ETH Configuration:
     - GPIO Settings: review settings, no changes required
          Pin Name | Signal on Pin | GPIO mode | GPIO Pull-up/Pull..| Maximum out | User Label
          :--------|:--------------|:----------|:-------------------|:------------|:----------
          PA1      | ETH_REF_CLK   | Alternate | No pull-up and no..| High        |.
          PA2      | ETH_MDIO      | Alternate | No pull-up and no..| High        |.
          PA7      | ETH_CRS_DV    | Alternate | No pull-up and no..| High        |.
          PC1      | ETH_MDC       | Alternate | No pull-up and no..| High        |.
          PC4      | ETH_RXD0      | Alternate | No pull-up and no..| High        |.
          PC5      | ETH_RXD1      | Alternate | No pull-up and no..| High        |.
          PG11     | ETH_TX_EN     | Alternate | No pull-up and no..| High        |.
          PG13     | ETH_TXD0      | Alternate | No pull-up and no..| High        |.
          PG14     | ETH_TXD1      | Alternate | No pull-up and no..| High        |.

     - NVIC Settings: enable interrupts
          Interrupt Table                      | Enable | Preemption Priority | Sub Priority
          :------------------------------------|:-------|:--------------------|:------------
          Ethernet global interrupt            |\b ON   | 0                   | 0

     - Parameter Settings: configure descriptor and RX buffer memory locations
          General:Ethernet Configuration | Value
          :------------------------------|:-------
          Ethernet MAC Address           | unused
          Tx Descriptor Length           | \b 4
          First Tx Descriptor Address    | \b 0x30040060
          Rx Descriptor Length           | \b 4
          First Rx Descriptor Address    | \b 0x30040000
          Rx Buffers Address             | \b 0x30040200
          Rx Buffers Length              | \b 1524          

     \n\note
     Add "RxDecripSection", "TxDecripSection" and "RxArraySection"  sections to the Scatter file if GNU Compiler or Arm Compiler 6 is used.\n      
     Example:
     \code{.sct}
       RW_ETH_RX_DESC 0x30040000 0x00000060 {
         *(.RxDecripSection)
       }
       RW_ETH_TX_DESC 0x30040060 0x000001A0 {
         *(.TxDecripSection)
       }
       RW_ETH_RX_BUF  0x30040200 0x00001800 {
         *(.RxArraySection)
       }
     \endcode
     \endnote

     - User Constants: not used

     Click \b OK to close the ETH Configuration dialog
 
  2. Under System open \b CORTEX_M7 Configuration
     - Parameter Settings: optionally enable cache and configure MPU
          Cortex Interface Settings    | Value
          :----------------------------|:-------
          CPU ICache                   | Enabled (optional)
          CPU DCache Length            | Enabled (optional)
          
          Cortex MPU Control Settings  | Value
          :----------------------------|:-------
          MPU Control Mode             | Background Region Privileged accesses only
          
          Cortex MPU Region 0 Settings | Value
          :----------------------------|:-------
          MPU Region                   | \b Enabled
          MPU Region Base Address      | \b 0x30040000
          MPU Region Size              | \b 256B
          MPU SubRegion Disable        | \b 0x0
          MPU TEX field level          | \b level 0
          MPU Access Permission        | \b ALL ACCESS PERMITTED
          MPU Instruction Access       | \b ENABLE
          MPU Shareability Permission  | \b ENABLE
          MPU Cacheable Permission     | \b DISABLE
          MPU Bufferable Permission    | \b ENABLE
*/

GPIO初始化;
NVIC中断配置;
以太网DMA接收/发送描述符的配置;
另外需要对MPU进行配置。
  1. ETH_Configuration.c文件内容如下:
#include "includes.h"


/* Ethernet Rx DMA 描述符 */
__attribute__((at(0x30040000))) ETH_DMADescTypeDef  DMARxDscrTab[ETH_RX_DESC_CNT]; 

/* Ethernet Tx DMA 描述符 */
__attribute__((at(0x30040060))) ETH_DMADescTypeDef  DMATxDscrTab[ETH_TX_DESC_CNT]; 

/* Ethernet 接收缓冲 */
__attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_MAX_PACKET_SIZE]; 


ETH_HandleTypeDef heth;


/*
*********************************************************************************************************
*	函 数 名: HAL_ETH_MspInit
*	功能说明: 以太网初始化调用的底层回调,用于初始化IO,时钟和中断
*	形    参: ---
*	返 回 值: 无
*********************************************************************************************************
*/
void HAL_ETH_MspInit(ETH_HandleTypeDef* heth)
{
	GPIO_InitTypeDef GPIO_InitStruct;

	/*
		PC1     ------> ETH_MDC
		PA1     ------> ETH_REF_CLK
		PA2     ------> ETH_MDIO
		PA7     ------> ETH_CRS_DV
		PC4     ------> ETH_RXD0
		PC5     ------> ETH_RXD1
		PB13    ------> ETH_TXD1
		PG11    ------> ETH_TX_EN
		PG13    ------> ETH_TXD0 
	*/
	if(heth->Instance==ETH)
	{
		/* 使能外设时钟 */
		__HAL_RCC_ETH1MAC_CLK_ENABLE();
		__HAL_RCC_ETH1TX_CLK_ENABLE();
		__HAL_RCC_ETH1RX_CLK_ENABLE();

		/* 使能时钟 */
		__HAL_RCC_GPIOA_CLK_ENABLE();
		__HAL_RCC_GPIOB_CLK_ENABLE();
		__HAL_RCC_GPIOC_CLK_ENABLE();
		__HAL_RCC_GPIOG_CLK_ENABLE();

		
		/* 配置PA1, PA2 , PA7 */
		GPIO_InitStruct.Pin =  GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
		GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
		GPIO_InitStruct.Pull = GPIO_NOPULL ; 
		GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
		HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

		/* 配置PB13 */
		GPIO_InitStruct.Pin = GPIO_PIN_13;
		HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

		/* 配置PC1, PC4和PC5 */
		GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5; 
		HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);	

		/* 配置PG11, PG12和PG13 */
		GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_13;
		HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

		/* 设置中断优先级 */
		HAL_NVIC_SetPriority(ETH_IRQn, 3, 0);
		HAL_NVIC_EnableIRQ(ETH_IRQn);	
	}
}

/*
*********************************************************************************************************
*	函 数 名: ETH_IRQHandler
*	功能说明: 以太网回调函数
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/
void ETH_IRQHandler(void)
{
	HAL_ETH_IRQHandler(&heth);
}
  1. 再次编译,一般情况就没有错误了。

添加网卡驱动接口

为了便于移植,这里直接使用MDK提供的ethernetif.c文件进行移植操作,文件路径如下;
同时还需要拷贝ethif_config.h文件,路径见下图

Lwip移植过程(基于FreeRTOS v10.2.1)_第34张图片
Lwip移植过程(基于FreeRTOS v10.2.1)_第35张图片

  1. 添加文件到工程中去,如下所示

Lwip移植过程(基于FreeRTOS v10.2.1)_第36张图片
2. 重新编译,无错误,到此移植完成

添加创建任务,进行Ping测试

添加lwip相关头文件
创建以太网初始化函数,代码如下
void net_init(void) 
{
	struct ip4_addr ipaddr;
	struct ip4_addr netmask;
	struct ip4_addr gw;

	/* 创建协议栈线程 */
	tcpip_init(NULL, NULL);

#if LWIP_DHCP
	ipaddr.addr = 0;
	netmask.addr = 0;
	gw.addr = 0;
#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

	/* 将网络接口添加到netif_list列表 */
	netif_add(&netif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input);

	/*  注册默认网络接口 */
	netif_set_default(&netif);
	netif_set_up(&netif);

	#if LWIP_DHCP
		dhcp_start (&netif);
	#endif
}

  1. 通过FreeRTOS创建一个eth任务,代码如下:
void vTaskEthCheck(void *pvParameters)
{
    /* 初始化网络 */
    printf("开始初始化网络.....");
    net_init();
    printf("初始化网络完成");
    while(1)
    {
    vTaskDelay(300); 
    }
  1. 编译运行,打开串口调试助手,发现有断言错误,如下图所示:

  1. 这是由于lwip使用了FreeRTOS,因此在tcpip.c里面会调用sys_thread_new创建一个TCP任务,如下图所示

Lwip移植过程(基于FreeRTOS v10.2.1)_第37张图片

  1. lwipopt.h中添加上图中用到的宏定义,如下图所示

Lwip移植过程(基于FreeRTOS v10.2.1)_第38张图片

  1. 继续编译、下载,能够正常初始化网络,但无法ping通,如下图所示

Lwip移植过程(基于FreeRTOS v10.2.1)_第39张图片

Lwip移植过程(基于FreeRTOS v10.2.1)_第40张图片

  1. 这是由于没加添加网卡接收任务,导致下位机未对接收的网卡数据产生反应,需要在ethernetif.c添加如下内容
//1.添加信号量定义
xSemaphoreHandle s_xSemaphore = NULL;

//2.在下面函数增加创建任务语句,如下
static void
low_level_init(struct netif *netif)
{
    .....//省略
    /* 创建接收处理任务 */
    s_xSemaphore = xSemaphoreCreateBinary();
	sys_thread_new("ethernetif_task",
                  ethernetif_task,          /* 任务入口函数 */
                  NULL,        	            /* 任务入口函数参数 */
                  TCPIP_THREAD_STACKSIZE,   /* 任务栈大小 */
                  2);                       /* 任务的优先级 */
}

//修改void ethernetif_poll (struct netif *netif) 函数如下

void ethernetif_poll (struct netif *netif) 
{
  struct ethernetif *eth = netif->state;

    while(1)
    {
        xSemaphoreTake(s_xSemaphore, portMAX_DELAY );
        taskENTER_CRITICAL();
        if (!eth->phy_ok || eth->link == ARM_ETH_LINK_DOWN) 
        {}
        if ((eth->rx_event) || (!eth->event_rx_frame)) 
        {
            eth->rx_event = false;
            /* process received ethernet packet */
            
            ethernetif_input (netif);
        }
        taskEXIT_CRITICAL(); 
    }
}

修改之后可以ping通

使用NETCONN 接口测速

Lwip移植过程(基于FreeRTOS v10.2.1)_第41张图片

你可能感兴趣的:(笔记)