LwIP协议栈源码说明

版本变更
2.1.x
   LWIP 从 2.0.3 版本,直接跳到了 2.1.0 版本,又是一个大的版本更新。增加了一些功能!同时源码的目录结构也有了一定的变化(增加了一些文件)! 按照 LWIP 的发布策略,以后 2.1.x 都是从 2.1.0 版本开始的 BUG 修复版本,最新的 BUG 修复版本是 2.1.2。具体变化参见源码目录下的 CHANGELOG 文件。下图显示了 2.0.3 版 和 2.1.2 版的文件对比差异:

关于这个版本,官网有个这么一句话 “ Oh, and this will be the last release with a separate contrib repository. I’ll be merging the files from contrib into the main repository soon after the release. In the git world, having two separate repositories just doesn’t work nice. ” 。大意就是,这是带有独立 contrib 库的最后一版本,后续会将 contrib 合并到 LWIP 主版本库中。
  其次,如果详细去看 LWIP 的说明文档,会发现文档中有些描述还是之前的,并没有跟随版本变更而改变!例如在doc目录下,原来的系统结构模板文件名为sys_arch.txt,在此版本没有了这个文件,但是说明文档中,仍然有这部分的介绍!

2.0.x
   LWIP 从 1.4.1 版本,直接跳到了 2.0.x 版本,是一个大的版本更新。源码结构变化比较大! 按照 LWIP 的发布策略,以后 2.0.x 都是从 2.0.0 版本开始的 BUG 修复版本,最终的 BUG 修复版本是 2.0.3。2.0.3 版本修复自 2.0.2 以来的一些错误,没有任何功能的变化。具体如下:

2017-09-11: Simon Goldschmidt
tcp_in.c: fix bug #51937 (leaking tcp_pcbs on passive close with unacked data)
2017-08-02: Abroz Bizjak/Simon Goldschmidt
multiple fixes in IPv4 reassembly (leading to corrupted datagrams received)
2017-03-30: Simon Goldschmidt
dhcp.c: return ERR_VAL instead of asserting on offset-out-of-pbuf
2017-03-23: Dirk Ziegelmeier
dhcp.h: fix bug #50618 (dhcp_remove_struct() macro does not work)
 

 

1.x.x

最终版本为 1.4.1。

源码目录文件

  要使用 LWIP 的源码由两部分组成,分别为 LWIP 和 contrib 。这两个是由两个独立的版本库,并且由不同的人来负责的!我们在实际使用 LWIP 时,这两部分都是需要使用的!

其中,contrib 中是一些和平台移植相关的代码,LWIP 则是 TCP/IP 协议栈的核心源码!
  下面我就以 2.0.3 版为例!从 1.4.1 到 2.0.3(从 2.0.0 开始),LwIP 的源码有了一定的变化,甚至于源码的文件结构也不一样,内部的一些实现源文件也被更新和替换了。其源码目录结构如下所示(对于简单的文件以注释的形式给出,核心源码下文会详细说明):
 

LWIP-2.0.3
│  CHANGELOG	// 版本更新记录,从中可以看到 LwIP 不同版本的变化
│  COPYING		// 版权说明
│  FILES		// 其中说明了其所在目录下的各目录或文件的用途。在不同的目录下会有不同的该文件
│  README		// 简介文档
│  UPGRADING	// 版本升级后可能出现不兼容,该文档记录了从老版本升级需要修改的地方。对于升级自己使用的 LwIP 版本时很有用处。
├─doc
│  │  contrib.txt	// LwIP 作为开源软件,如果想要为其做贡献,则需要遵循一定的准则,例如:提交代码的风格、报告Bug等。该文档给出了详细的贡献准则。
│  │  doxygen_docs.zip	// 用 doxygen 生成的 LwIP 的配套文档
│  │  FILES			// 其中说明了该目录下的每个文件的用途
│  │  mdns.txt		// MDNS 的说明文档
│  │  mqtt_client.txt
│  │  NO_SYS_SampleCode.c
│  │  ppp.txt		// lwIP的PPP接口文档
│  │  rawapi.txt	// 告诉读者怎样使用协议栈的 Raw/Callback API 进行编程
│  │  savannah.txt	// 说明了如何获取当前的开发源代码
│  │  sys_arch.txt  // 在有操作系统的移植的时候会被使用到,包含了移植说明,规定了移植者需要实现的函数、宏定义等,后面有详细说明。
│  └─doxygen		// doxygen 脚本,主要用来维护 LwIP 的配套文档。对于使用LwIP来说用不到
│      │  generate.bat
│      │  generate.sh
│      │  lwip.Doxyfile
│      │  main_page.h
│      └─output
│              index.html
├─src /* 源码文件部分下面独立详细说明 */
│  │  Filelists.mk
│  │  FILES		// 主要记录了该目录下每个文件、目录的用途
│  ├─api
│  │      api_lib.c
│  │      api_msg.c
│  │      err.c
│  │      netbuf.c
│  │      netdb.c
│  │      netifapi.c
│  │      sockets.c
│  │      tcpip.c
│  ├─apps
│  │  ├─httpd
│  │  │  │  fs.c
│  │  │  │  fsdata.c
│  │  │  │  fsdata.h
│  │  │  │  httpd.c
│  │  │  │  httpd_structs.h
│  │  │  ├─fs
│  │  │  │  │  404.html
│  │  │  │  │  index.html
│  │  │  │  └─img
│  │  │  │          sics.gif
│  │  │  └─makefsdata
│  │  │          makefsdata
│  │  │          makefsdata.c
│  │  │          readme.txt
│  │  ├─lwiperf
│  │  │      lwiperf.c
│  │  ├─mdns
│  │  │      mdns.c
│  │  ├─mqtt
│  │  │      mqtt.c
│  │  ├─netbiosns
│  │  │      netbiosns.c
│  │  ├─snmp
│  │  │      snmpv3.c
│  │  │      snmpv3_dummy.c
│  │  │      snmpv3_mbedtls.c
│  │  │      snmpv3_priv.h
│  │  │      snmp_asn1.c
│  │  │      snmp_asn1.h
│  │  │      snmp_core.c
│  │  │      snmp_core_priv.h
│  │  │      snmp_mib2.c
│  │  │      snmp_mib2_icmp.c
│  │  │      snmp_mib2_interfaces.c
│  │  │      snmp_mib2_ip.c
│  │  │      snmp_mib2_snmp.c
│  │  │      snmp_mib2_system.c
│  │  │      snmp_mib2_tcp.c
│  │  │      snmp_mib2_udp.c
│  │  │      snmp_msg.c
│  │  │      snmp_msg.h
│  │  │      snmp_netconn.c
│  │  │      snmp_pbuf_stream.c
│  │  │      snmp_pbuf_stream.h
│  │  │      snmp_raw.c
│  │  │      snmp_scalar.c
│  │  │      snmp_table.c
│  │  │      snmp_threadsync.c
│  │  │      snmp_traps.c
│  │  ├─sntp
│  │  │      sntp.c
│  │  └─tftp
│  │          tftp_server.c
│  ├─core
│  │  │  def.c
│  │  │  dns.c
│  │  │  inet_chksum.c
│  │  │  init.c
│  │  │  ip.c
│  │  │  mem.c
│  │  │  memp.c
│  │  │  netif.c
│  │  │  pbuf.c
│  │  │  raw.c
│  │  │  stats.c
│  │  │  sys.c
│  │  │  tcp.c
│  │  │  tcp_in.c
│  │  │  tcp_out.c
│  │  │  timeouts.c
│  │  │  udp.c
│  │  ├─ipv4
│  │  │      autoip.c
│  │  │      dhcp.c
│  │  │      etharp.c
│  │  │      icmp.c
│  │  │      igmp.c
│  │  │      ip4.c
│  │  │      ip4_addr.c
│  │  │      ip4_frag.c
│  │  └─ipv6
│  │          dhcp6.c
│  │          ethip6.c
│  │          icmp6.c
│  │          inet6.c
│  │          ip6.c
│  │          ip6_addr.c
│  │          ip6_frag.c
│  │          mld6.c
│  │          nd6.c
│  ├─include
│  │  ├─lwip
│  │  │  │  api.h
│  │  │  │  arch.h
│  │  │  │  autoip.h
│  │  │  │  debug.h
│  │  │  │  def.h
│  │  │  │  dhcp.h
│  │  │  │  dhcp6.h
│  │  │  │  dns.h
│  │  │  │  err.h
│  │  │  │  errno.h
│  │  │  │  etharp.h
│  │  │  │  ethip6.h
│  │  │  │  icmp.h
│  │  │  │  icmp6.h
│  │  │  │  igmp.h
│  │  │  │  inet.h
│  │  │  │  inet_chksum.h
│  │  │  │  init.h
│  │  │  │  ip.h
│  │  │  │  ip4.h
│  │  │  │  ip4_addr.h
│  │  │  │  ip4_frag.h
│  │  │  │  ip6.h
│  │  │  │  ip6_addr.h
│  │  │  │  ip6_frag.h
│  │  │  │  ip_addr.h
│  │  │  │  mem.h
│  │  │  │  memp.h
│  │  │  │  mld6.h
│  │  │  │  nd6.h
│  │  │  │  netbuf.h
│  │  │  │  netdb.h
│  │  │  │  netif.h
│  │  │  │  netifapi.h
│  │  │  │  opt.h
│  │  │  │  pbuf.h
│  │  │  │  raw.h
│  │  │  │  sio.h
│  │  │  │  snmp.h
│  │  │  │  sockets.h
│  │  │  │  stats.h
│  │  │  │  sys.h
│  │  │  │  tcp.h
│  │  │  │  tcpip.h
│  │  │  │  timeouts.h
│  │  │  │  udp.h
│  │  │  ├─apps
│  │  │  │      FILES
│  │  │  │      fs.h
│  │  │  │      httpd.h
│  │  │  │      httpd_opts.h
│  │  │  │      lwiperf.h
│  │  │  │      mdns.h
│  │  │  │      mdns_opts.h
│  │  │  │      mdns_priv.h
│  │  │  │      mqtt.h
│  │  │  │      mqtt_opts.h
│  │  │  │      netbiosns.h
│  │  │  │      netbiosns_opts.h
│  │  │  │      snmp.h
│  │  │  │      snmpv3.h
│  │  │  │      snmp_core.h
│  │  │  │      snmp_mib2.h
│  │  │  │      snmp_opts.h
│  │  │  │      snmp_scalar.h
│  │  │  │      snmp_table.h
│  │  │  │      snmp_threadsync.h
│  │  │  │      sntp.h
│  │  │  │      sntp_opts.h
│  │  │  │      tftp_opts.h
│  │  │  │      tftp_server.h
│  │  │  ├─priv
│  │  │  │      api_msg.h
│  │  │  │      memp_priv.h
│  │  │  │      memp_std.h
│  │  │  │      nd6_priv.h
│  │  │  │      tcpip_priv.h
│  │  │  │      tcp_priv.h
│  │  │  └─prot
│  │  │          autoip.h
│  │  │          dhcp.h
│  │  │          dns.h
│  │  │          etharp.h
│  │  │          ethernet.h
│  │  │          icmp.h
│  │  │          icmp6.h
│  │  │          igmp.h
│  │  │          ip.h
│  │  │          ip4.h
│  │  │          ip6.h
│  │  │          mld6.h
│  │  │          nd6.h
│  │  │          tcp.h
│  │  │          udp.h
│  │  ├─netif
│  │  │  │  etharp.h
│  │  │  │  ethernet.h
│  │  │  │  lowpan6.h
│  │  │  │  lowpan6_opts.h
│  │  │  │  slipif.h
│  │  │  └─ppp
│  │  │      │  ccp.h
│  │  │      │  chap-md5.h
│  │  │      │  chap-new.h
│  │  │      │  chap_ms.h
│  │  │      │  eap.h
│  │  │      │  ecp.h
│  │  │      │  eui64.h
│  │  │      │  fsm.h
│  │  │      │  ipcp.h
│  │  │      │  ipv6cp.h
│  │  │      │  lcp.h
│  │  │      │  magic.h
│  │  │      │  mppe.h
│  │  │      │  ppp.h
│  │  │      │  pppapi.h
│  │  │      │  pppcrypt.h
│  │  │      │  pppdebug.h
│  │  │      │  pppoe.h
│  │  │      │  pppo.h
│  │  │      │  pppos.h
│  │  │      │  ppp_impl.h
│  │  │      │  ppp_opts.h
│  │  │      │  upap.h
│  │  │      │  vj.h
│  │  │      └─polarssl
│  │  │              arc4.h
│  │  │              des.h
│  │  │              md4.h
│  │  │              md5.h
│  │  │              sha1.h
│  │  └─posix
│  │      │  errno.h
│  │      │  netdb.h
│  │      └─sys
│  │              socket.h
│  └─netif
│      │  ethernet.c
│      │  ethernetif.c
│      │  FILES
│      │  lowpan6.c
│      │  slipif.c
│      └─ppp
│          │  auth.c
│          │  ccp.c
│          │  chap-md5.c
│          │  chap-new.c
│          │  chap_ms.c
│          │  demand.c
│          │  eap.c
│          │  ecp.c
│          │  eui64.c
│          │  fsm.c
│          │  ipcp.c
│          │  ipv6cp.c
│          │  lcp.c
│          │  magic.c
│          │  mppe.c
│          │  multilink.c
│          │  ppp.c
│          │  pppapi.c
│          │  pppcrypt.c
│          │  PPPD_FOLLOWUP
│          │  pppoe.c
│          │  pppo.c
│          │  pppos.c
│          │  upap.c
│          │  utils.c
│          │  vj.c
│          └─polarssl
│                  arc4.c
│                  des.c
│                  md4.c
│                  md5.c
│                  README
│                  sha1.c
└─test	// 一些协议栈内核测试程序.在实际使用时一般用不到!可直接删除。
    ├─fuzz
    │  │  config.h
    │  │  fuzz.c
    │  │  lwipopts.h
    │  │  Makefile
    │  │  output_to_pcap.sh
    │  │  README
    │  └─inputs
    │      ├─arp
    │      │      arp_req.bin
    │      ├─icmp
    │      │      icmp_ping.bin
    │      ├─ipv6
    │      │      neighbor_solicitation.bin
    │      │      router_adv.bin
    │      ├─tcp
    │      │      tcp_syn.bin
    │      └─udp
    │              udp_port_5000.bin
    └─unit
        │  lwipopts.h
        │  lwip_check.h
        │  lwip_unittests.c
        ├─core
        │      test_mem.c
        │      test_mem.h
        │      test_pbuf.c
        │      test_pbuf.h
        ├─dhcp
        │      test_dhcp.c
        │      test_dhcp.h
        ├─etharp
        │      test_etharp.c
        │      test_etharp.h
        ├─ip4
        │      test_ip4.c
        │      test_ip4.h
        ├─mdns
        │      test_mdns.c
        │      test_mdns.h
        ├─tcp
        │      tcp_helper.c
        │      tcp_helper.h
        │      test_tcp.c
        │      test_tcp.h
        │      test_tcp_oos.c
        │      test_tcp_oos.h
        └─udp
                test_udp.c
                test_udp.h

api目录

LwIP 提供了两种类型的 API : Callback-style APIs 和 Sequential-style APIs 。其中,Callback-style APIs 即为LwIP最底层的接口,被称为Raw API或者Native API;而Sequential-style APIs主要是对底层接口进行了封装,主要包含:Netconn API、NETIF API和Socket API。在实际使用中,使用者可以任选一种API来使用。
  api目录下主要包含对底层API(raw API)封装后的高级API的代码。 如果直接使用底层的的Raw API,则不需要该目录下的文件。而封装后的高级别的这两种API实现的原理都是通过引进邮箱和信号量等通信与同步机制,来实现对内核中***Raw API(native API)***函数的封装和调用。要使用这两种类型的API,需要底层操作系统的支持。

 

  • Raw API:(有时称为native API)是一个设计用于在没有操作系统时,实现零拷贝发送和接收的事件驱动的API。 这个API也被核心堆栈用于各种协议之间的交互。 这是在没有操作系统的情况下,运行lwIP时唯一可用的API。因为Callback/Raw API是协议栈提供的三种编程接口中最复杂的一种, 它通过直接与协议栈内 核函数交互以实现编程,所以整个过程比较复杂。源码的doc目录下有一个专门的文档:rawapi.txt说明了具体如何使用Raw API。
  •  
  • Netconn API: 为普通的、顺序的程序提供了使用lwIP栈的方法。 线程安全,仅从非TCPIP线程调用。 基于网络缓冲区(包含数据包缓冲区(PBUF))的TX / RX处理,以避免复制数据。这与BSD Socket API非常相似。 执行模型基于 打开-读取-写入-关闭 范例。 由于TCP / IP堆栈本质上是事件,所以TCP / IP代码和应用程序必须驻留在不同的执行上下文(线程)中。

  • Socket API: 它是建立在Netconn API之上的。其主要是由于BSD Socket API是网络通信的一个实现。线程安全,仅从非TCPIP线程调用。BSD Socket API已经是网络套接字的事实上的抽象标准。目前,所有主流操作系统均实现了BSD Socket API。出于此,LwIP也提供了一套BSD Socket API。但是,标准 socket 库中的部分函数仍无法直接通过封装 Netconn API 来实现,因此 LwIP 中提供的socket 函数并不完整,用户最好不要使用它进行实际应用程序开发。对应文件为posix/sys/socket.h。

  • api_lib.c: 包含 对外提供的 sequential API 函数的实现。函数名均以netconn_开头。主要分为三组API:同时可用于TCP和UDP的API、只能用于TCP的API、只能用于UDP的API。

  • api_msg.c: 包含sequential API内部自己调用的函数的实现。主要包含API消息的封装和处理函数

  • err.c: 错误管理模块

  • netbuf.c: 包含了上层数据包管理函数的实现。应用程序描述待发送数据和已接收数据的基本结构。该结构只是对内核 pbuf 的简单封装,避免了数据的拷贝。缓冲区不能在多个线程之间共享。

  • netdb.c: 包含与主机名字转换相关的函数,主要在 socket 中被使用到

  • netifapi.c: 包含了上层网络接口管理函数的实现

  • sockets.c: 包含了 Socket API 函数的实现

tcpip.c: 包含了上层 API 与协议栈内核交互的函数,它是整个上层 API 功能得以实现的一个枢纽,其实现的功能可以简单理解为:从 API 函数处接收消息,然后将消息递交给内核函数,内核函数根据消息做出相应的处理。

apps目录

使用lwIP低级raw API编写的高层应用程序。

core目录

TCP/IP 协议栈的核心部分。主要包含协议实现、内存和缓冲区管理以及底层raw API的实现。它包含了IP、ICMP、IGMP、TCP、UDP 等核 心协议以及建立在它们基础上的 DNS、DHCP、SNMP 等上层应用协议。内核源代码可以单独运行,且不需要操作系统的支持。即:直接使用 raw API 编程。

  • ipv4目录: 包含了IPv4 标准中与IP层数据包处理相关的所有代码
  • autoip.c: 这是lwIP TCP / IP协议栈的AutoIP实现。 它旨在符合RFC 3927。
  • dhcp.c: 实现了DHCP 客户端的所有代码,DHCP 称为动态主机配置协议,DHCP 可以使计算机使用者不必为主机的IP 地址的分配问题而烦恼。DHCP 也是一个上层应 用程序, 通常DHCP客户端通过使用UDP提供的功能来实现与DHCP服务器的通信, 从DHCP 服务器处获得一个有效的IP 地址
  • etharp.c: 包含了ARP 协议实现的相关函数,ARP 协议是以太网通信中的重要部分, 主要用来实现主机以太网物理地址到IP 地址的映射。这点是非常必要的,以太网中底层数据包的发送是基于网卡物理地址的,而不是主机的IP地址。 通过ARP协议, 主机可以发送请求, 得到邻居节点的IP 地址与物理地址等信息,为以太网数据包交互提供保证。
  • icmp.c: 包含了ICMP 协议实现的相关函数,ICMP 协议为IP 数据包传递过程中的差错 报告、差错纠正以及目的地址可达性测试提供了支持,常见的Ping 命令就属于ICMP 应用的 一种
  • igmp.c: 包含了网络组管理协议IGMP 的实现,IGMP 为网络中的多播数据传输提供了 支持,主机加入某个多播组后,可以接收到该组的UDP 多播数据
  • ip4_addr.c: 实现了几个比较简单 的IP 地址处理函数,如判断一个IP 地址是否为广播地址的函数,以及32 位IP 地址与点分十 进制地址间的转换函数等
  • ip4_frag.c: 提供了IP 层数据包分片与重组相关的函数的实现。
  • Ip4.c: 包含了IPv4 协议实现的相关函数,如数据包的接收、递交、发送等
  • ipv6目录: 包含了IPv6 标准中和IP层数据包处理相关的所有代码
  • mld6.c: IPv6的多播侦听器发现。旨在符合RFC 2710。
  • nd6.c: IPv6的邻居发现和无状态地址自动配置。 旨在符合RFC 4861(邻居发现)和RFC 4862(地址自动配置)。
  • Iinet6.c: 目前没有啥实际内容。

其他文件与IPv4目录下的功能相同,不过是在IPv6版上的实现

  • def.c: 文件包含了IP 层使用到的一些功能函数的定义,如IP 地址的转换、网络字节序与 主机字节序转换等
  • dns.c: 实现了DNS 客户端的所有代码,DNS 称为域名系统,通常用户要访问某个外 部的主机时,可能只知道该主机的名字,而不知道该主机的IP 地址。常理也是这样,用户可 以简单地记得某个主机的名字,如www.baidu.com,却很难记得这个主机的IP 地址。通过使 用DNS,可以解决这个问题,通过访问DNS 服务器,我们可以得到与主机名对应的IP 地址, 这为用户的使用带来了方便。值得指出的是,DNS 也是一个上层应用程序,它通常基于UDP 来传输数据。
  • inet_chksum.c: 这些是校验和算法的一些参考实现,其目标是简单,正确和完全便携。 Checksumming是您希望为您的平台优化的第一件事。 如果您创建自己的版本,请将其链接到cc.h中
  • init.c: 主要包含了一个与LwIP 协议栈初始化密切相关的函数,以及一些 协议栈配置信息的检查与输出
  • ip.c: IPv4和IPv6共用的代码。

LwIP协议栈源码说明_第1张图片

  • netif.c: 包含了协议栈网络接口管理的相关函数,协议栈支持多个网络接口,例如以太网接口、SLIP接口等,协议栈内部对每个接口用一个对应的netif数据结构进行描述,并通过使用netif.c中的函数进行统一管理。同时,netif.c还包含了环回接口管理和数据处理的相关函数,使用环回接口可以实现同一主机上两个应用程序之间的数据交换。
  • pbuf.c: 包含了协议栈内核使用的数据包管理函数,数据包pbuf管理的实现是整个协议栈中很有特色的地方,采用特殊的数据包pbuf 结构,可以避免数据在各个层次之间递交时的拷贝,这既提高了数据递交效率,也节省了内存空间。
  • raw.c: 为应用层提供了一种直接和IP 数据包交互的方式,这类似于Socket 编程中原始套接字的概念,它同TCP、UDP 处于同一等级,享受IP 层提供的服务。使用原始套接字, 可以直接读取IP 层接收到的数据包,例如ICMP 包、UDP 包等,也可以自行构造ping包等, 为用户的程序编写提供了很大的方便。这是LwIP最底层的API部分。使用这一级别的api进行编程需要对TCP/IP相当了解。
  • stats.c: 包含了协议栈内部数据统计与显示的相关函数,如内存使用状况、邮箱、信号量等信息。
  • sys.c: 实现了一个简单的函数void sys_msleep(u32_t ms);,它借助操作系统模拟层的信号量机制完成睡眠一定时间的功能,该函数主要在PPP 中使用。前面曾提到过,若需要使用协议栈的Sequential API和Socket API,则必须使用底层操作系统提供的邮箱与信号量机制,这时内核要求移植者提供一个称为sys_arch.c的操作系统模拟层文件,该文件主要完成对操作系统中邮 箱与信号量函数的封装。需要注意,只有在提供文件sys_arch.c 的基础上,文件`sys.c 才有效,换句话说,在无操作系统环境下运行LwIP 时,sys.c文件都不会被编译。
     
  • tcp_in.c: 包含了TCP 协议中数据接收、处理相关的函数,最重要的TCP 状态机函数也在这个文件中
  • tcp_out.c: 包含了TCP 中数据发送相关的函数,例如数据包发送函数、超时重传函数等。
  • tcp: 包含了对TCP 控制块操作的函数,也包括了TCP 定时处理函数
  • timeouts.c: 统一完成了对内核各个协议定时事件处理函数的封装,同时对各个注册的定时事件进行处理。在有无操作系统模拟层的环境下,timeouts.c 采用不同的方法来实现定时:在无操作系统模拟层时,timeouts.c 使用系统时钟函数sys_now(不同的平台的都需要移植该函数)来获得当前系统时间,从而可以判断出各个事件是否超时;在有操作系统模拟层时,timers.c 实现了对操作系统模拟层邮箱等待函数的再次封装,得到一个具有协议栈特色的邮箱操作函数。 所谓特色,就是在邮箱等待函数中加入一种机制,在邮箱上等待消息的同时,可以同时实现协议栈中各个定时事件的正确处理。

       在2.0.0之前的版本中,该文件名为timer.c。新的timeouts.c对原来的内容进行了一定的封装,简化。

  • udp.c: 包含了实现UDP 协议的相关函数,包括UDP 控制块管理、UDP 数据包发送函数、UDP 数据包接收函数等
     

include目录

LwIP使用的各种头文件。与各源码目录相对应。

  • netif文件夹: 主要是针对netif目录中源文件的各种头文件。
  • posix文件夹: 主要是针对POSIX标准,进行的封装,里面的文件非常简单,基本都是对外部的引用。
  • lwip文件夹: LwIP的各种头文件,其中需要注意的有opt.h 文件,它包含了所有LwIP内核参数的默认配置值;还有init.h 文件,它包含了与当前 LwIP 源代码信息相关的宏定义,如协议版本号、是否为官方版等。
  • apps文件夹: 主要是针对源码中 app目录的各头文件。
  • priv文件夹: LwIP内部使用的头文件,禁止外部使用
  • prot文件夹: 这个文件夹中主要是针对TCP/IP规约的各种定义。与netif文件夹中同名文件区别在于netif文件夹中的文件均为对外提供的API,本目录才是对规约层各种结构的定义。

LwIP协议栈源码说明_第2张图片

 

你可能感兴趣的:(STM32)