在Visual Studio 2012下编译lwip-2.1.3 httpd的makefsdata

22 篇文章 2 订阅

步骤一 建立空白工程

新建一个工程,项目名称起名为makefsdata。
因为mkfsdata是一个控制台程序,所以我们要选择Win32 Console Application。

这里很重要,必须要勾选“Empty Project”选项,建立空项目:

建好的解决方案目录是C:\Users\Octopus\Desktop\makefsdata,工程目录是C:\Users\Octopus\Desktop\makefsdata\makefsdata。

步骤二 解压lwip-2.1.3的部分头文件和源文件

去官网下载lwip-2.1.3.zip,解压下列文件到工程目录
lwip-2.1.3.zip\lwip-2.1.3\src\include ---> 工程目录\lwip-2.1.3\include(解压整个文件夹,以及所有文件)
lwip-2.1.3.zip\lwip-2.1.3\src\core\def.c ---> 工程目录\lwip-2.1.3\core\def.c
lwip-2.1.3.zip\lwip-2.1.3\src\core\inet_chksum.c ---> 工程目录\lwip-2.1.3\core\inet_chksum.c
lwip-2.1.3.zip\lwip-2.1.3\src\apps\http\mkfsdata ---> 工程目录\lwip-2.1.3\apps\http\mkfsdata(整个文件夹)
lwip-2.1.3.zip\lwip-2.1.3\src\apps\http\httpd_structs.h ---> 工程目录\lwip-2.1.3\apps\http\httpd_structs.h

步骤三 建立配置文件

建立“工程目录\lwip-2.1.3\include\arch\cc.h”,内容如下:
这里涉及到一个很重要的知识点:如何在Visual Studio下定义__packed关键字。

#ifndef LWIP_ARCH_CC_H
#define LWIP_ARCH_CC_H

#define LWIP_RAND() ((u32_t)rand())
#define PACK_STRUCT_BEGIN __pragma(pack(push, 1))
#define PACK_STRUCT_END __pragma(pack(pop))

#pragma warning(disable:4996) // 允许使用strcpy等不带_s后缀的函数
#define snprintf _snprintf

#endif

建立“工程目录\lwip-2.1.3\include\lwipopts.h”,内容如下:

#ifndef LWIP_LWIPOPTS_H
#define LWIP_LWIPOPTS_H

#define NO_SYS 1 // 无操作系统
#define SYS_LIGHTWEIGHT_PROT 0 // 不进行临界区保护

#define LWIP_NETCONN 0
#define LWIP_SOCKET 0

#define MEM_ALIGNMENT 4 // STM32单片机是32位的单片机, 因此是4字节对齐的
#define MEM_SIZE 10240 // lwip的mem_malloc函数使用的堆内存的大小

// 配置TCP
#define TCP_MSS 1500
#define LWIP_TCP_SACK_OUT 1 // 允许选择性确认

// 配置DHCP
#define LWIP_DHCP 1
#define LWIP_NETIF_HOSTNAME 1

// 配置DNS
#define LWIP_DNS 1

// 广播包过滤器
// 如果打开了这个过滤器, 那么就需要在套接字上设置SOF_BROADCAST选项才能收发广播数据包
//#define IP_SOF_BROADCAST 1
//#define IP_SOF_BROADCAST_RECV 1

// 配置IPv6
#define LWIP_IPV6 1
#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS LWIP_DNS // 允许SLAAC获取DNS服务器的地址

#endif

建立“工程目录\lwip-2.1.3\include\inttypes.h”,内容如下:
(该文件出处为http://msinttypes.googlecode.com/files/msinttypes-r26.zip

// ISO C9x  compliant inttypes.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
// 
//  Copyright (c) 2006 Alexander Chemeris
// 
// 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 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.
// 
///

#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]

#ifndef _MSC_INTTYPES_H_ // [
#define _MSC_INTTYPES_H_

#if _MSC_VER > 1000
#pragma once
#endif

#include "stdint.h"

// 7.8 Format conversion of integer types

typedef struct {
   intmax_t quot;
   intmax_t rem;
} imaxdiv_t;

// 7.8.1 Macros for format specifiers

#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [   See footnote 185 at page 198

// The fprintf macros for signed integers are:
#define PRId8       "d"
#define PRIi8       "i"
#define PRIdLEAST8  "d"
#define PRIiLEAST8  "i"
#define PRIdFAST8   "d"
#define PRIiFAST8   "i"

#define PRId16       "hd"
#define PRIi16       "hi"
#define PRIdLEAST16  "hd"
#define PRIiLEAST16  "hi"
#define PRIdFAST16   "hd"
#define PRIiFAST16   "hi"

#define PRId32       "I32d"
#define PRIi32       "I32i"
#define PRIdLEAST32  "I32d"
#define PRIiLEAST32  "I32i"
#define PRIdFAST32   "I32d"
#define PRIiFAST32   "I32i"

#define PRId64       "I64d"
#define PRIi64       "I64i"
#define PRIdLEAST64  "I64d"
#define PRIiLEAST64  "I64i"
#define PRIdFAST64   "I64d"
#define PRIiFAST64   "I64i"

#define PRIdMAX     "I64d"
#define PRIiMAX     "I64i"

#define PRIdPTR     "Id"
#define PRIiPTR     "Ii"

// The fprintf macros for unsigned integers are:
#define PRIo8       "o"
#define PRIu8       "u"
#define PRIx8       "x"
#define PRIX8       "X"
#define PRIoLEAST8  "o"
#define PRIuLEAST8  "u"
#define PRIxLEAST8  "x"
#define PRIXLEAST8  "X"
#define PRIoFAST8   "o"
#define PRIuFAST8   "u"
#define PRIxFAST8   "x"
#define PRIXFAST8   "X"

#define PRIo16       "ho"
#define PRIu16       "hu"
#define PRIx16       "hx"
#define PRIX16       "hX"
#define PRIoLEAST16  "ho"
#define PRIuLEAST16  "hu"
#define PRIxLEAST16  "hx"
#define PRIXLEAST16  "hX"
#define PRIoFAST16   "ho"
#define PRIuFAST16   "hu"
#define PRIxFAST16   "hx"
#define PRIXFAST16   "hX"

#define PRIo32       "I32o"
#define PRIu32       "I32u"
#define PRIx32       "I32x"
#define PRIX32       "I32X"
#define PRIoLEAST32  "I32o"
#define PRIuLEAST32  "I32u"
#define PRIxLEAST32  "I32x"
#define PRIXLEAST32  "I32X"
#define PRIoFAST32   "I32o"
#define PRIuFAST32   "I32u"
#define PRIxFAST32   "I32x"
#define PRIXFAST32   "I32X"

#define PRIo64       "I64o"
#define PRIu64       "I64u"
#define PRIx64       "I64x"
#define PRIX64       "I64X"
#define PRIoLEAST64  "I64o"
#define PRIuLEAST64  "I64u"
#define PRIxLEAST64  "I64x"
#define PRIXLEAST64  "I64X"
#define PRIoFAST64   "I64o"
#define PRIuFAST64   "I64u"
#define PRIxFAST64   "I64x"
#define PRIXFAST64   "I64X"

#define PRIoMAX     "I64o"
#define PRIuMAX     "I64u"
#define PRIxMAX     "I64x"
#define PRIXMAX     "I64X"

#define PRIoPTR     "Io"
#define PRIuPTR     "Iu"
#define PRIxPTR     "Ix"
#define PRIXPTR     "IX"

// The fscanf macros for signed integers are:
#define SCNd8       "d"
#define SCNi8       "i"
#define SCNdLEAST8  "d"
#define SCNiLEAST8  "i"
#define SCNdFAST8   "d"
#define SCNiFAST8   "i"

#define SCNd16       "hd"
#define SCNi16       "hi"
#define SCNdLEAST16  "hd"
#define SCNiLEAST16  "hi"
#define SCNdFAST16   "hd"
#define SCNiFAST16   "hi"

#define SCNd32       "ld"
#define SCNi32       "li"
#define SCNdLEAST32  "ld"
#define SCNiLEAST32  "li"
#define SCNdFAST32   "ld"
#define SCNiFAST32   "li"

#define SCNd64       "I64d"
#define SCNi64       "I64i"
#define SCNdLEAST64  "I64d"
#define SCNiLEAST64  "I64i"
#define SCNdFAST64   "I64d"
#define SCNiFAST64   "I64i"

#define SCNdMAX     "I64d"
#define SCNiMAX     "I64i"

#ifdef _WIN64 // [
#  define SCNdPTR     "I64d"
#  define SCNiPTR     "I64i"
#else  // _WIN64 ][
#  define SCNdPTR     "ld"
#  define SCNiPTR     "li"
#endif  // _WIN64 ]

// The fscanf macros for unsigned integers are:
#define SCNo8       "o"
#define SCNu8       "u"
#define SCNx8       "x"
#define SCNX8       "X"
#define SCNoLEAST8  "o"
#define SCNuLEAST8  "u"
#define SCNxLEAST8  "x"
#define SCNXLEAST8  "X"
#define SCNoFAST8   "o"
#define SCNuFAST8   "u"
#define SCNxFAST8   "x"
#define SCNXFAST8   "X"

#define SCNo16       "ho"
#define SCNu16       "hu"
#define SCNx16       "hx"
#define SCNX16       "hX"
#define SCNoLEAST16  "ho"
#define SCNuLEAST16  "hu"
#define SCNxLEAST16  "hx"
#define SCNXLEAST16  "hX"
#define SCNoFAST16   "ho"
#define SCNuFAST16   "hu"
#define SCNxFAST16   "hx"
#define SCNXFAST16   "hX"

#define SCNo32       "lo"
#define SCNu32       "lu"
#define SCNx32       "lx"
#define SCNX32       "lX"
#define SCNoLEAST32  "lo"
#define SCNuLEAST32  "lu"
#define SCNxLEAST32  "lx"
#define SCNXLEAST32  "lX"
#define SCNoFAST32   "lo"
#define SCNuFAST32   "lu"
#define SCNxFAST32   "lx"
#define SCNXFAST32   "lX"

#define SCNo64       "I64o"
#define SCNu64       "I64u"
#define SCNx64       "I64x"
#define SCNX64       "I64X"
#define SCNoLEAST64  "I64o"
#define SCNuLEAST64  "I64u"
#define SCNxLEAST64  "I64x"
#define SCNXLEAST64  "I64X"
#define SCNoFAST64   "I64o"
#define SCNuFAST64   "I64u"
#define SCNxFAST64   "I64x"
#define SCNXFAST64   "I64X"

#define SCNoMAX     "I64o"
#define SCNuMAX     "I64u"
#define SCNxMAX     "I64x"
#define SCNXMAX     "I64X"

#ifdef _WIN64 // [
#  define SCNoPTR     "I64o"
#  define SCNuPTR     "I64u"
#  define SCNxPTR     "I64x"
#  define SCNXPTR     "I64X"
#else  // _WIN64 ][
#  define SCNoPTR     "lo"
#  define SCNuPTR     "lu"
#  define SCNxPTR     "lx"
#  define SCNXPTR     "lX"
#endif  // _WIN64 ]

#endif // __STDC_FORMAT_MACROS ]

// 7.8.2 Functions for greatest-width integer types

// 7.8.2.1 The imaxabs function
#define imaxabs _abs64

// 7.8.2.2 The imaxdiv function

// This is modified version of div() function from Microsoft's div.c found
// in %MSVC.NET%\crt\src\div.c
#ifdef STATIC_IMAXDIV // [
static
#else // STATIC_IMAXDIV ][
_inline
#endif // STATIC_IMAXDIV ]
imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
{
   imaxdiv_t result;

   result.quot = numer / denom;
   result.rem = numer % denom;

   if (numer < 0 && result.rem > 0) {
      // did division wrong; must fix up
      ++result.quot;
      result.rem -= denom;
   }

   return result;
}

// 7.8.2.3 The strtoimax and strtoumax functions
#define strtoimax _strtoi64
#define strtoumax _strtoui64

// 7.8.2.4 The wcstoimax and wcstoumax functions
#define wcstoimax _wcstoi64
#define wcstoumax _wcstoui64


#endif // _MSC_INTTYPES_H_ ]

步骤四 将文件添加到Visual Studio 2012工程中

工程中只添加mkfsdata.c文件,其余的文件一律不添加

步骤五 编译生成32位Release版程序

要求:生成的程序能够在刚安装好的纯净版Windows XP系统上直接运行,不需要安装任何运行时库。

首先切换到Release模式:

打开项目属性:

选择Visual Studio 2012 - Windows XP (v110_xp)模式:

添加lwip-2.1.3的头文件路径:

选择多线程模式(/MT),不依赖于任何Runtime库的DLL。

编译程序:

1>------ Build started: Project: makefsdata, Configuration: Release Win32 ------
1>  makefsdata.c
1>  Generating code
1>  Finished generating code
1>  makefsdata.vcxproj -> C:\Users\Octopus\Desktop\makefsdata\Release\makefsdata.exe
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

程序就编译出来了。把这个程序放到单片机lwip工程的apps/http文件夹下就可以用了。
程序的功能是把fs文件夹下的所有网页和图片文件,整合成一个fsdata.c文件。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
lwip(轻量级IP协议栈)是一个开源的TCP/IP协议栈,旨在用于嵌入式系统和实时应用。移植lwip 2.1.3到特定的嵌入式系统需要以下步骤: 1. 下载和解压缩lwip软件包:首先,从lwip官方网站上下载最新版本的lwip 2.1.3软件包。然后,将软件包解压缩到本地目录。 2. 配置lwip:进入lwip软件包所在的目录,找到lwipopts.h头文件。通过修改该头文件中的宏定义,根据嵌入式系统的需求配置lwip。可能需要设置的选项包括:IP地址、子网掩码、网关地址、最大数据包长度等。 3. 移植硬件驱动:lwip需要硬件驱动程序来与底层网络接口进行通信。嵌入式系统通常有自己的网络接口硬件,所以需要移植特定的硬件驱动程序。根据硬件接口和规范,实现网络驱动程序和相关函数。 4. 移植操作系统适配层(optional):如果嵌入式系统使用操作系统,如RTOS(实时操作系统),则需要移植操作系统适配层以支持lwip的多线程和并发操作。根据具体的操作系统规范,实现适配层函数和功能。 5. 编译和链接:使用适当的交叉编译工具链,将lwip源代码以及硬件驱动程序和适配层代码编译成目标平台的可执行文件。然后,将生成的目标文件链接到嵌入式系统的应用程序中。 6. 调试和测试:在嵌入式系统上运行编译和链接后的 lwip软件,并进行相应的调试和测试。确保lwip在特定的嵌入式环境下能够正常工作,并实现所期望的网络功能。 总之,移植lwip 2.1.3到嵌入式系统需要进行配置、移植硬件驱动程序、可能的操作系统适配层移植、编译和链接等步骤。通过这些步骤,lwip可以在嵌入式系统上实现TCP/IP网络功能,并提供轻量级的网络通信能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巨大八爪鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值