欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Lwip移植过程(基于FreeRTOS)

程序员文章站 2024-01-23 12:16:34
...

Lwip移植过程(基于FreeRTOS)

准备过程

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

  • Lwip移植过程(基于FreeRTOS)

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

Lwip移植过程(基于FreeRTOS)

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

  • LWIP/api

Lwip移植过程(基于FreeRTOS)

  • LWIP/core

Lwip移植过程(基于FreeRTOS)

  • LWIP/core/ipv4

Lwip移植过程(基于FreeRTOS)

  • LWIP/netif

Lwip移植过程(基于FreeRTOS)

添加头文件信息

Lwip移植过程(基于FreeRTOS)

移植修改

  1. 编译后发现很多error,如下图所示
    Lwip移植过程(基于FreeRTOS)

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

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

  4. 添加lwipopts.h头文件路径,如下图所示
    Lwip移植过程(基于FreeRTOS)

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

  6. 添加arch/cc.h文件,将下图文件夹下的两个*.h拷到lwip-2.1.2/user/arch*文件夹下
    Lwip移植过程(基于FreeRTOS)
    Lwip移植过程(基于FreeRTOS)

  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 <aaa@qq.com>
 *
 */
#ifndef LWIP_ARCH_CC_H
#define LWIP_ARCH_CC_H

#include <stdio.h>
#include <stdlib.h>

#if defined (__CC_ARM ) || \
   (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
#include <errno.h>
#undef  EDOM
#undef  ERANGE
#undef  EILSEQ
#undef  ESIGNUM
#undef  EINVAL
#undef  ENOMEM
#define LWIP_PROVIDE_ERRNO
#else
#define LWIP_PROVIDE_ERRNO
#endif

/* Define platform endianness (might already be defined) */
#ifndef BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN
#endif /* BYTE_ORDER */

/* 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 "lu"

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

/* Platform specific diagnostic output */
#define LWIP_PLATFORM_DIAG(x) do {printf x;} while(0)

#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_RAND() ((u32_t)rand())

#endif /* LWIP_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_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)
Lwip移植过程(基于FreeRTOS)
Lwip移植过程(基于FreeRTOS)
10. 在工程中添加sys_arch.c

  • LWIP/arch

Lwip移植过程(基于FreeRTOS)

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

添加PHY驱动

物理层驱动芯片:DM9161

Lwip移植过程(基于FreeRTOS)

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

Lwip移植过程(基于FreeRTOS)

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

Lwip移植过程(基于FreeRTOS)
Lwip移植过程(基于FreeRTOS)

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

添加MAC驱动

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

Lwip移植过程(基于FreeRTOS)

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

Lwip移植过程(基于FreeRTOS)

修改后内容如下:

/******************************************************************************
 * 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)
Lwip移植过程(基于FreeRTOS)
6. 在EMAC_STM32H7XX.c文件头中,我们可以找到如下说明,我们可以根据该说明新建一个ETH_Configuration.c文件,并按照说明实现即可

Configuration tab
-----------------
  1. Under Connectivity open \b ETH Configuration:
     - <b>GPIO Settings</b>: 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        |.

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

     - <b>Parameter Settings</b>: 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 <b>"RxDecripSection", "TxDecripSection" and "RxArraySection" </b> 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

     - <b>User Constants</b>: not used

     Click \b OK to close the ETH Configuration dialog
 
  2. Under System open \b CORTEX_M7 Configuration
     - <b>Parameter Settings</b>: 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)
Lwip移植过程(基于FreeRTOS)

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

Lwip移植过程(基于FreeRTOS)
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, &ethernetif_init, &ethernet_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. 编译运行,打开串口调试助手,发现有断言错误,如下图所示:

Lwip移植过程(基于FreeRTOS)

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

Lwip移植过程(基于FreeRTOS)

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

Lwip移植过程(基于FreeRTOS)

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

Lwip移植过程(基于FreeRTOS)

Lwip移植过程(基于FreeRTOS)

  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)

相关标签: 笔记