【LwIP-移植(NO_SYS)】- 工程添加LwIP源码(一)

工程添加LwIP源码

源码版本:lwip-1.4.1、STM32F107_ETH_LwIP_V1.0.0(ST官方LwIP的移植例程)

硬件平台:STM32F103xx

IDE:           MDK KEIL5


目录

工程添加LwIP源码

1 前言

2 源码准备

3 分析源码包

4 添加文件到工程

5 编译工程

6 硬件平台支持LwIP


1 前言

写LwIP移植的文章主要记录个人的移植技巧和思路。有一段时间看了大量的LwIP的移植教程和博客,都没有很好地阐明移植的思路和方法,让初学者无法完全的掌握移植技巧,同时导致一大部分初学者对移植产生了畏惧。从本文开始,将详细讲明怎样在没有国内教程的情况下去移植LwIP。

2 源码准备

Lwip的源码可以通过该链接进行下载:http://savannah.nongnu.org/projects/lwip/。本次记录采用的是lwip-1.4.1版本。

3 分析源码包

1. 进入lwip-1.4.1文件夹,文件组织如下:

/

2. doc、src、test文件夹的用途:

  • doc:单从文件夹名称可以知道该文件夹是供给用户使用的移植说明文档。

  • src:该文件包含了LwIP的源码。

  • test:该文件是官方提供的测试程序,我们可以不使用。

如果单从文件夹名称还是看不出这几个文件夹的用途,我们可以查看lwip-1.4.1目录下的一些说明文档。

  • CHANGELOG:打开这个文档,我们可以知道该文档是记录版本的新特性和改动。
  • COPYING:查看该文件,可以知道这是作者的版权说明。
  • FILES:这个文档主要讲述doc、src文件夹的用途。
  • UPGRADING:这个文档记录版本间的改动,为旧版本的升级提供说明。

通过上述两点,我们大概了解到移植从来未接触过的源码主要通过官方提供的文档说明进行移植。

3. doc目录下的文件

同理,我们首先查看FILES文件,其内容如下:

FILES文档已经为我们解释了很清楚。如果英文水平不好的话,请查查翻译。

笔者前期主要将LwIP移植到无系统的工程上,因此只需要用到rawapo.txt参考文档。至于其他文档,根据实际需求进行使用,可能后期文章将会使用到。对于rawapi.txt的内容,此处不进行展开,请自己硬着头皮去翻译去读。

4. src目录下

同样,进入src目录下首先查看的是FILES文档,其内容如下:

该文档也解释了src目录下文件夹的作用,仅仅采用低层次的raw API方法使用LwIP的话,只需要用到core、include、netif三个文件夹。至于api文件夹在使用高层次的API接口时才需用到。

 

4 添加文件到工程

1. 在工程目录下创建文件夹LWIP,把lwip-1.4.1整个文件夹拷贝到LWIP下。如下图所示:

2. 在keil平台添加3个分组,如下图所示:

 

 3. 添加文件到指定分组中

(1) 由于本次移植是不带OS的,因此LWIP/API暂时不加入文件。

(2) 将协议栈相关文件添加到LWIP/CORE分组下,如下图所示:

(3) 将netif文件夹下的部分文件加入/LWIP/NETIF分组中

 

(4) 设置头文件路径

 

 

5 编译工程

编译 整个工程,当然肯定会报错,这也是我们想要的结果,我们需根据报错信息修改整个工程目录,看看LwIP还需要什么文件。

1. 缺少lwipopts.h头文件,这个官方没给我们说明要自己创建的,根据文件名可以知道这个是用户的LwIP配置文件。我们在LWIP目录下创建USER文件夹,并在该文件夹中新建lwipopts.h,同时在keil平台中加入分组“LWIP/USER”,把lwipopts.h加入该分组,方便修改。当然,别忘了添加头文件路径。再次编译工程,新的报错信息如下:

2. 缺少cc.h文件,从arch关键字可以看出,这个文件与平台相关,涉及到平台相关的一般都是关于编译器、数据类型的声明等。这个我们不用自己写,直接引用ST官方的LWIP移植工程。

3. 将port文件夹下的arch文件夹拷贝到工程目录下的LWIP文件夹中。把arch的路径添加到keil的头文件路径。再次编译。

4. 将工程中的"arch/cc.h"改为"cc.h" ,再次编译,又是出现上面类同的错误信息,同理。

5. 上述报错,缺少sys_arch.h头文件,这个头文件与OS有关,我们在arch下 创建一个空头文件即可。

6. 从上述的错误可见,缺少与OS相关的通信机制,我们在lwipopts.htouw头文件中添加“#define NO_SYS 1”,然后编译。

7. 在lwipopts.h文件中再将LWIP_SOCKET和LWIP_NETCONN宏定义为0,再次编译。

 8.我们在arch目录下新建sys_arch.c文件,把该文件加入keil中的LWIP/ARCH分组中,并往该文件夹加入如下代码:

#include "lwip/sys.h"
#include "sys_arch.h"

u32_t sys_now(void)
{
    return 0;
}

9.再次编译,工程不再报错,只有警告。这说明我们移植成功一大半了。

 

6 为LwIP提供底层接口

LwIP已经加入到了我们的工程中,虽说编译通过了,但还不能直接用,毕竟我们还没有给LwIP提供与硬件平台相关的驱动。说到驱动的话,我们就应该找到LwIP提供的驱动接口框架文件。这个文件不难找,前面提过netif文件夹就是底层接口相关的,从netif目录下的FILE文件可知ethernetif.c文件是我们所找的文件,同时也是我们必须修改的文件。

6.1 简述ethernetif.c文件

粗略地阅读ethernetif.c文件,我们可以发现如下所示的一条语句:

这条语句又叫我们看前面的注释...如下:

 翻译就不翻译了,大概知道这是网络底层接口的框架就行了。由于该文件被宏条件给屏蔽了,也就是说之前我们编译通过的LwIP并没有网络底层接口框架。我们把"#if 0"改为"#if 1",然后我们就开始完善这个框架。

6.2 完善LwIP底层网络接口

由上往下地阅读ethernetif.c文件,不放过每一个函数的注释,因为这些注释会告诉你函数的作用,以及需要用户修改什么地方。

(1) low_level_init接口

static void
low_level_init(struct netif *netif)
{
  struct ethernetif *ethernetif = netif->state;
  
  /* set MAC hardware address length */
  netif->hwaddr_len = ETHARP_HWADDR_LEN;

  /* set MAC hardware address */
  netif->hwaddr[0] = ;
  ...
  netif->hwaddr[5] = ;

  /* maximum transfer unit */
  netif->mtu = 1500;
  
  /* device capabilities */
  /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
  netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
 
  /* Do whatever else is needed to initialize interface. */  
}

从注释可以知道,low_level_init是硬件初始化接口,会被ethernetif_init接口调用。再看low_level_init接口内部语句,需要我们完善的有:

  • MAC地址(此处的MAC地址必须与以太网硬件设置的MAC地址一致
  • 以太网硬件初始化接口(不是必须指定在此处,可以在LwIP初始化前)

(2)low_level_output

/**
 * This function should do the actual transmission of the packet. The packet is
 * contained in the pbuf that is passed to the function. This pbuf
 * might be chained.
 *
 * @param netif the lwip network interface structure for this ethernetif
 * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
 * @return ERR_OK if the packet could be sent
 *         an err_t value if the packet couldn't be sent
 *
 * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
 *       strange results. You might consider waiting for space in the DMA queue
 *       to become availale since the stack doesn't retry to send a packet
 *       dropped because of memory failure (except for the TCP timers).
 */

static err_t
low_level_output(struct netif *netif, struct pbuf *p)
{
  struct ethernetif *ethernetif = netif->state;
  struct pbuf *q;

  initiate transfer();
  
#if ETH_PAD_SIZE
  pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif

  for(q = p; q != NULL; q = q->next) {
    /* Send the data from the pbuf to the interface, one pbuf at a
       time. The size of the data in each pbuf is kept in the ->len
       variable. */
    send data from(q->payload, q->len);
  }

  signal that packet should be sent();

#if ETH_PAD_SIZE
  pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
  
  LINK_STATS_INC(link.xmit);

  return ERR_OK;
}

 这个接口将网络层数据包通过以太网硬件发送出去,因此该接口我们需将网络层数据包封装为帧数据包并通过物理层发送出去。以太网芯片实现了链路层和网络层,因此我们在此加入向下封装和发送数据的过程。如何向下封装和发送,此处不加多解说,根据实际使用的硬件平台自行添加。实现这一部分,需要我们了解struct pbuf数据结构。

 

 

待续。。。

 

 

  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
stm32f107 lwip freertos cube例程是一种在stm32f107芯片上实现的嵌入式系统开发框架。此例程结合lwip、freertos和cube库,使开发者能够更轻松高效地开发网络应用。 首先,stm32f107是意法半导体(STMicroelectronics)推出的一款性能强大的32位微控制器芯片。它具有高度集成的硬件资源,包括多个通用IO口、串行接口、SPI接口、定时器等。此外,它内置了ARM Cortex-M3处理器,可提供高性能和低功耗的处理能力。 lwip(Lightweight IP)是一款轻量级的TCP/IP协议栈,专门为嵌入式系统设计。它具有占用资源少、高度可移植和易于使用的特点。lwip提供了TCP、UDP、IP、ARP和ICMP等协议的实现,使开发者能够通过网络进行数据传输和通信。 而freertos(Free Real-Time Operating System)是一种开源的实时操作系统(RTOS),为嵌入式系统提供了任务管理、内存管理和通信机制等功能。通过freertos,开发者可以更好地组织和管理任务,提高系统的实时性和可靠性。 在stm32f107 lwip freertos cube例程中,cube库为开发者提供了一种高层次的编程接口,简化了硬件配置和初始化的过程。它提供了一系列的驱动库和协议栈,如ETH(以太网)驱动库、USB驱动库等,以及对lwip和freertos的集成支持。这使得开发者能够更快速地搭建和配置网络应用,减少了开发时间和复杂性。 通过使用stm32f107 lwip freertos cube例程,开发者可以轻松地实现网络应用,如Web服务器、FTP服务器、TCP/IP通信等。同时,它也提供了丰富的示例代码和文档,以帮助开发者更好地理解和使用相关功能。 总之,stm32f107 lwip freertos cube例程是一种功能强大、易于使用的嵌入式系统开发框架。它结合了stm32f107芯片、lwip协议栈、freertos操作系统和cube库,为开发者提供了一种高效的网络应用开发方案。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值