LWIP总结

介绍

Lwip,light weight IP;是由Adam Dunkels 开发的一个小型开源的TCP/IP协议栈;目前已经为全球共同开发的开源协议;支持TCPIP协议族的核心协议;包括:ARP/ICMP/TCP/UDP/IPV4/IPV6/DHCP等;其核心特点是:功能齐全、运行需求的RAM和ROM少;

编程模型

所有的功能和性能都可进行裁剪和配置;相关文件为:lwipopts.h

内部实现支持带操作系统和不带操作系统;核心框架是:外部单线程驱动协议栈状态机;底层使用中断进行数据的接收;

其提供三种API :1)RAW API 2)lwip API 3)BSD API。其中BSD API就是大家最熟悉的socket API了。Linux和Windows平台中的socket接口都与此大同小异;

移植

将lwip移植到不同的平台主要包括两个部分工作:

  1. MAC+PHY层移植,包括初始化、数据的收发;
  2. 应用层框架移植,如操作系统层的线程创建、定时器、消息邮箱;

平台

硬件:STM32F107 PHY芯片:DM9161AEP

软件:UCOS-ii

移植核心点

ST公司针对STM32F107 不带操作系统版本的LWIP移植版本,文件名为STM32F107_ETH_LwIP,版本为V1.0.0;由于其版本不再更新且与本软件平台不一致,所以不做参考;

由于STM32F1 STM32F2 STM32F4的以太网驱动都是一致的。所以到ST官网下载stm32cubdf2。其中有LWIP针对FREERTOS的移植;而FREERTOS与UCOS大同小异;所以只要针对其修改应用层框架移植的实现即可;相关代码位于:stm32cubef2\STM32Cube_FW_F2_V1.1.0\Projects\STM322xG_EVAL\Applications\LwIP\LwIP_UDPTCP_Echo_Server_Netconn_RTOS;

LWIP的代码使用1.4.1版本,可到LWIP官网上下载;也包含在stm32cubef2中;

移植的理论基础来源于lwip 1.4.1源码包中doc文件夹中的文件;同时官方也有移植到各个平台中的示例,文件为:contrib-1.4.1.zip,到官网上下载即可;

  1. MAC+PHY移植:

需要修改的文件为:

app_ethernet.c/h

ethernetif.c/h

同时需要将stm32cubef2驱动库中的stm32f2xx_hal_eth.c/h拷贝过来;

以上文件只需要配置好,保证编译没问题,则MAC+PHY层移植完成;

2. 应用层框架移植:

修改1个文件sys_arch.c,位于stm32cubef2\STM32Cube_FW_F2_V1.1.0\Middlewares\Third_Party\LwIP\system;

所有的移植即完成;

注意点

STM32Cube_FW_F2_V1.1.0此版本中关于lwip的驱动MAC代码是有bug的,具体表现在当以太网包数量加大时,会出现底层收数据很慢的情况;使用PING命令经常出现TIMEOUT;

此bug在STM32cubeF4中得到解决;相关问题原因描述见参考资料;

参考资料

  1. 核心论文 <<Design and Implementation of the lwIP TCP/IP Stack>> By Adam Dunkels.2001
  2. 移植资料

    http://www.stmcu.org/module/forum/thread-588339-1-1.html

<<lwIP TCP/IP stack demonstration for STM32F107xx connectivity line microcontrollers >> By ST

3.  lwip官方网站https://savannah.nongnu.org/projects/lwip/

时间: 2024-10-11 09:19:15

LWIP总结的相关文章

lwIP RAW_API

lwIP RAW TCP/IP接口 作者: Adam Dunkels, Leon Woestenberg, Christiaan Simons lwIP为使用TCP/IP协议通信的应用程序编程提供了两种接口接口(APIs): * 低层次的称之为"core" / "callback" 或者 "raw" API * 高层次的称之为"sequential" API lwIP "sequential" API为使用

LwIP - raw/callback API、协议栈API(sequential API)、BSD API(或者说 SOCKET API)

1.使用raw/callback API编程,用户编程的方法是向内核注册各种自定义的回调函数,回调函数是与内核实现交换的唯一方式. recv_udp, accept_function, sent_tcp, recv_tcp, do_connected, poll_tcp, err_tcp! 2.协议栈API(sequential API)是基于raw/callback API实现的,它与内核交换的方式也只能通过回调. netconn_new, netconn_delete, netconn_ge

2.3 stm32移植lwip常见问题和解决方式

1.PHY初始化 一般来说,stm32外部驱动PHY芯片有两种连接方式,MII和RMII总线,这个与硬件设计有关,不过stm32芯片一般都支持这两种总线连接方式,因为RMII总线在传输效果不变的情况下占用接口更少,因此一般推荐RMII方式. 以DP83848芯片为例: 从上面可以看出RMII总线对应的输入时钟要设置为50MHZ, 当然这与你原理图的布线有,连接PHY芯片X1接口对应GPIO接口的外设区域时钟就要设定为该值,考虑到挂在同区域外设的时钟要求,为了方便设计,对于stm32f207vet

lwip socket探秘之bind

一个基本的socket建立顺序是 Server端: socket() bind() listen() accept() recv() Client端: socket() connect() send() 本文着重介绍Server端的bind()过程. 用户调用bind()时,实际调用的是lwip_bind(),我们从这个函数看起: 1 int 2 lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) 3 { 4 ....

lwip socket探秘之listen

一个基本的socket建立顺序是 Server端: socket() bind() listen() accept() recv() Client端: socket() connect() send() 本文着重介绍Server端的listen()过程. 用户使用socket,调用listen()时,实际调用的是lwip里的lwip_listen().代码如下 1 /** 2 * Set a socket into listen mode. 3 * The socket may not have

lwip socket探秘之socket创建

一个基本的socket建立顺序是 Server端: socket() bind() listen() accept() recv() Client端: socket() connect() send() 本文着重介绍Server端的socket()过程. 用户使用socket时,首先会调用socket()函数创建一个socket.在lwip中实际调用的就是lwip_socket()函数. 代码如下: 1 int 2 lwip_socket(int domain, int type, int pr

LWIP裸机环境下实现TCP与UDP通讯

前面移植了LWIP,并且简单的实用了DHCP的功能,今天来使用一下实际的数据通讯的功能 首先是实现TCP客户端,我先上代码 #ifndef __TCP_CLIENT_H_ #define __TCP_CLIENT_H_ #include "network.h" //连接状态 enum tcp_client_states { ES_NONE = 0, ES_RECEIVED, //接收到了数据 ES_CLOSING //连接关闭 }; //TCP服务器状态 struct tcp_clie

stm32使用LWIP实现DHCP客户端

LWIP是一款开源的嵌入式网络协议栈,支持的功能很多,而且能在多任务环境下和单任务裸机环境下跑,今天说说他的移植过程,芯片为STM32,网卡为ENC28J60,无操作系统 首先下载LWIP的源代码,我下载的是1.4.1的源码,下载后解压,文件结构如图 将这四个目录中的文件全部拷贝到工程中,API是一些socket通讯的接口,需要在多任务的环境下实现,core里面存放的内核源码,我们主要使用IPV4,include目录下是需要包含的目录,lwip只要求我们包含include目录,里面的内层目录会自

lwip socket探秘之accept

一个基本的socket建立顺序是 Server端: socket() bind() listen() accept() recv() Client端: socket() connect() send() 本文着重介绍Server端的accept()过程. 上一篇我们已经分析了listen()过程,listen()过程新建了pcb并把它放到了tcp_listen_pcbs这个链表里. 接下来,Client端通过Server绑定的地址和端口号(通过bind绑定),给Server发包.Server收到