嵌入式 lwip http server makefsdata

news2025/2/21 9:08:55

背景:

基于君正X2000 MCU Freertos+lwip架构 实现HTTP server服务,MCU作为HTTP服务器通过网口进行数据包的传输,提供网页服务。其中设计到LWIP提供的工具makefsdata,常用于将文件或目录结构转换为适合嵌入到固件中的二进制格式。

一、 lwip 源码和资源

1. 1 源码资源下载链接

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

lwip官方网站下载地址:https://download.savannah.nongnu.org/releases/lwip/

下载解压打开后文件目录大致是这个样子

在这里插入图片描述

1.2 资源目录介绍:

fs用于存放网页资源诸如HTML、CSS、JavaScript等文件。makefsdata是官网提供的工具用于将fs中网页资源转换为适合嵌入到固件中的二进制格式,使用makefsdata生成fsdata.c方便集成到嵌入式系统当中。其他是一些http实现的接口及头文件。

二 、makefsdata工具使用

2.1 makefsdata转换工具有俩种实现方式:

2. 1. 1使用makefsdata脚本

使用源码makefsdata文件夹下的makefsdata脚本直接解释运行,使用脚本只需要添加运行权限,直接运行即可快捷方便的生成fsdata.c集成到嵌入式系统中。但是缺乏一些扩展功能,使用不够灵活且无法使用压缩,这对于资源有限的嵌入式设备来说是不可接受的。

lwip源码资源下载后存放网页资源的fs脚本在makefsdata脚本的上层目录,而makefsdata脚本默认将当前目录下的文件资源转换生成fsdata.c。故对脚本做一些修改。将脚本中的chdir(“fs”); ——> chdir(“…/fs”);

添加文件复制移动命令将生成的fsdata.c自动替换成上层旧文件方便生成后编译

在这里插入图片描述

下面是修改后的完整makefsdata脚本

#!/usr/bin/perl

use File::Copy;

open(OUTPUT, "> fsdata.c");

chdir("../fs");
open(FILES, "find . -type f |");

while($file = <FILES>) {

    # Do not include files in CVS directories nor backup files.
    if($file =~ /(CVS|~)/) {
    	next;
    }
    
    chop($file);
    
    open(HEADER, "> /tmp/header") || die $!;
    if($file =~ /404/) {
	print(HEADER "HTTP/1.0 404 File not found\r\n");
    } else {
	print(HEADER "HTTP/1.0 200 OK\r\n");
    }
    print(HEADER "Server: lwIP/pre-0.6 (http://www.sics.se/~adam/lwip/)\r\n");
    if($file =~ /\.html$/) {
	print(HEADER "Content-type: text/html\r\n");
    } elsif($file =~ /\.gif$/) {
	print(HEADER "Content-type: image/gif\r\n");
    } elsif($file =~ /\.png$/) {
	print(HEADER "Content-type: image/png\r\n");
    } elsif($file =~ /\.jpg$/) {
	print(HEADER "Content-type: image/jpeg\r\n");
    } elsif($file =~ /\.class$/) {
	print(HEADER "Content-type: application/octet-stream\r\n");
    } elsif($file =~ /\.ram$/) {
	print(HEADER "Content-type: audio/x-pn-realaudio\r\n");    
    } else {
	print(HEADER "Content-type: text/plain\r\n");
    }
    print(HEADER "\r\n");
    close(HEADER);

    unless($file =~ /\.plain$/ || $file =~ /cgi/) {
	system("cat /tmp/header $file > /tmp/file");
    } else {
	system("cp $file /tmp/file");
    }
    
    open(FILE, "/tmp/file");
    unlink("/tmp/file");
    unlink("/tmp/header");

    $file =~ s/\.//;
    $fvar = $file;
    $fvar =~ s-/-_-g;
    $fvar =~ s-\.-_-g;
    print(OUTPUT "static const unsigned char data".$fvar."[] = {\n");
    print(OUTPUT "\t/* $file */\n\t");
    for($j = 0; $j < length($file); $j++) {
	printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1)));
    }
    printf(OUTPUT "0,\n");
    
    
    $i = 0;
    while(read(FILE, $data, 1)) {
        if($i == 0) {
            print(OUTPUT "\t");
        }
        printf(OUTPUT "%#02x, ", unpack("C", $data));
        $i++;
        if($i == 10) {
            print(OUTPUT "\n");
            $i = 0;
        }
    }
    print(OUTPUT "};\n\n");
    close(FILE);
    push(@fvars, $fvar);
    push(@files, $file);
}

for($i = 0; $i < @fvars; $i++) {
    $file = $files[$i];
    $fvar = $fvars[$i];

    if($i == 0) {
        $prevfile = "NULL";
    } else {
        $prevfile = "file" . $fvars[$i - 1];
    }
    print(OUTPUT "const struct fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, ");
    print(OUTPUT "data$fvar + ". (length($file) + 1) .", ");
    print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) .", FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT}};\n\n");
}

chdir("../makefsdata");
move("fsdata.c", "../fsdata.c");

print(OUTPUT "#define FS_ROOT file$fvars[$i - 1]\n\n");
print(OUTPUT "#define FS_NUMFILES $i\n");

2.1.2 编译makefsdata.c后使用可执行文件生成fsdata.c

博主在windows下使用vscode+mingw编译生成makefsdata.exe,进而使用该程序生成fsdata.c。相较于脚本使用多了一步编译生成的步骤,但是多了许多扩展功能且可以进行zlib压缩网页资源文件。对于资源有限的嵌入式设备压缩功能就十分必要。编译好的makefsdata.exe放在置顶,可以直接在windows下命令行运行。

编译参考博客 使用vscode编译makefsdata 如果需要压缩功能需要额外下载第三方库如zlip。压缩转换命令如下,可配合-XC排除不需要压缩的文件。官网提供的网页资源不经压缩转换后fsdata.c大小为21KB,经过-defl:5参数压缩转换后为14KB。压缩比例约为66KB,不同压缩等级,网页资源经过压缩后压缩比例不尽相同。

makefsdata.exe -defl:5   //  Windows下命令行运行,-defl表示使用压缩,5表示压缩等级(1-10)默认10

扩展功能参考资源文件下的readme.txt,更多功能可以参考源码或者makefsdata -help查看user page。

This directory contains a script ('makefsdata') to create C code suitable for
httpd for given html pages (or other files) in a directory.

There is also a plain C console application doing the same and extended a bit.

Usage: htmlgen [targetdir] [-s] [-i]s
   targetdir: relative or absolute path to files to convert
   switch -s: toggle processing of subdirectories (default is on)
   switch -e: exclude HTTP header from file (header is created at runtime, default is on)
   switch -11: include HTTP 1.1 header (1.0 is default)

  if targetdir not specified, makefsdata will attempt to
  process files in subdirectory 'fs'.

The C version of this program can optionally store the none-SSI files in
a compressed form in which they are also sent to the web client (which
must support the Deflate content encoding). Files that grow during compression
(due to being not compressible well), will stored umcompressed automatically.
In order to do so, compile the program with MAKEFS_SUPPORT_DEFLATE set to 1. You must
manually download minizip.c for this to work. As an alternative, you can additionally
define MAKEFS_SUPPORT_DEFLATE_ZLIB to use your system's zlib instead.
Compression of .html, .js, .css and .svg files usually yields very good compression
rates and is a great way of reducing your program's size.

makefsdata.c实现的扩展功能。

static void print_usage(void)
{
  printf(" Usage: htmlgen [targetdir] [-s] [-e] [-11] [-nossi] [-ssi:<filename>] [-c] [-f:<filename>] [-m] [-svr:<name>] [-x:<ext_list>] [-xc:<ext_list>" USAGE_ARG_DEFLATE NEWLINE NEWLINE);
  printf("   targetdir: relative or absolute path to files to convert" NEWLINE);
  printf("   switch -s: toggle processing of subdirectories (default is on)" NEWLINE);
  printf("   switch -e: exclude HTTP header from file (header is created at runtime, default is off)" NEWLINE);
  printf("   switch -11: include HTTP 1.1 header (1.0 is default)" NEWLINE);
  printf("   switch -nossi: no support for SSI (cannot calculate Content-Length for SSI)" NEWLINE);
  printf("   switch -ssi: ssi filename (ssi support controlled by file list, not by extension)" NEWLINE);
  printf("   switch -c: precalculate checksums for all pages (default is off)" NEWLINE);
  printf("   switch -f: target filename (default is \"fsdata.c\")" NEWLINE);
  printf("   switch -m: include \"Last-Modified\" header based on file time" NEWLINE);
  printf("   switch -svr: server identifier sent in HTTP response header ('Server' field)" NEWLINE);
  printf("   switch -x: comma separated list of extensions of files to exclude (e.g., -x:json,txt)" NEWLINE);
  printf("   switch -xc: comma separated list of extensions of files to not compress (e.g., -xc:mp3,jpg)" NEWLINE);
#if MAKEFS_SUPPORT_DEFLATE
  printf("   switch -defl: deflate-compress all non-SSI files (with opt. compr.-level, default=10)" NEWLINE);
  printf("                 ATTENTION: browser has to support \"Content-Encoding: deflate\"!" NEWLINE);
#endif
  printf("   if targetdir not specified, htmlgen will attempt to" NEWLINE);
  printf("   process files in subdirectory 'fs'" NEWLINE);
}

三、集成fsdata.c到嵌入式设备

3.1 概述:君正X2000芯片提供2个网口驱动,不同芯片架构平台网口实现大同小异不是本文核心内容不做赘述。本次实验将设备默认静态IP设置为192.168.3.120。将生成的fsdata.c替换后编译生成固件烧录至开发板后即可展示网页资源。

3.2 调用LWIP实现HTTP server

调用LWIP实现最基础的网页展示十分简单,只需要将生成fsdata.c替换后在主程序头部包含LWIP头文件

#include "lwip/apps/httpd.h"

在主程序中调用httpd_init即可启动http server。

httpd_init();		// 初始化 HTTPD SERVER

嵌入式设备通过网线连接到PC,打开浏览器输入192.168.3.120(端口号会默认80)即可展示网页资源左上角图片为替换验证后的图片资源(与LWIP官方提供的默认图片资源不一样)。

在这里插入图片描述

3.3 http server实际应用功能待更新。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2300869.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

qemu-kvm源码解析-cpu虚拟化

背景 Qemu 虚拟化中&#xff0c;CPU&#xff0c;内存&#xff0c;中断是虚拟化的核心板块。本章主要对CPU虚拟化源码进行分析 而随着技术的发展包括CPU、内存、网卡等常见外设。硬件层面的虚拟化现在已经是云计算的标配。形成了&#xff0c;qemu作为cpu外层控制面&#xff0c…

数据治理中 大数据处理一般都遵循哪些原则

在数据治理中&#xff0c;大数据处理通常遵循以下原则&#xff1a; 最小化原则&#xff1a;企业应只收集实现特定目的所需的数据&#xff0c;避免数据冗余和安全风险。 合法性原则&#xff1a;企业必须遵守相关法律法规&#xff0c;确保数据处理符合法律要求&#xff0c;降低法…

【Python pro】基本数据类型

一、数字类型 1.1 数字类型的组成 1.1.1 整数 &#xff08;1&#xff09;十进制&#xff0c;二进制0b&#xff0c;八进制0o&#xff0c;十六进制0x print(16 0b10000 0o20 0x10) # 输出&#xff1a;True&#xff08;2&#xff09;十进制转其他进制 a bin(16) b oct(1…

sql server查询IO消耗大的排查sql诊断语句

原文链接&#xff1a; sql server查询IO消耗大的排查sql诊断语句-S3软件[code]select top 50 (total_logical_reads/execution_count) as avg_logical_reads , (total_logical_writes/execution_count) as avg_logical_writes , (tota ... https://blog.s3.sh.cn/thread-120-1…

kubernetes源码分析 kubelet

简介 从官方的架构图中很容易就能找到 kubelet 执行 kubelet -h 看到 kubelet 的功能介绍&#xff1a; kubelet 是每个 Node 节点上都运行的主要“节点代理”。使用如下的一个向 apiserver 注册 Node 节点&#xff1a;主机的 hostname&#xff1b;覆盖 host 的参数&#xff1…

Golang学习笔记_33——桥接模式

Golang学习笔记_30——建造者模式 Golang学习笔记_31——原型模式 Golang学习笔记_32——适配器模式 文章目录 桥接模式详解一、桥接模式核心概念1. 定义2. 解决的问题3. 核心角色4. 类图 二、桥接模式的特点三、适用场景1. 多维度变化2. 跨平台开发3. 动态切换实现 四、与其他…

【js逆向_入门】图灵爬虫练习平台 第四题

(base64解码&#xff09;地址&#xff1a;aHR0cHM6Ly9zdHUudHVsaW5ncHl0b24uY24vcHJvYmxlbS1kZXRhaWwvNC8 请求接口带有加密参数&#xff1a; 全局搜索Sign,找到参数生成位置 一目了然&#xff0c;知道参数是怎么构造生成的 调试代码 测试验证思路是否正确 时间&#xff1a; …

Mybatis后端数据库查询多对多查询解决方案

问题场景&#xff1a; 我开发的是一个论文选择系统。 后端用一个论文表paper来存储论文信息。 论文信息中&#xff0c;包含前置课程&#xff0c;也就是你需要修过这些课程才能选择这个论文。 而一个论文对应的课程有很多个。 这样就造成了一个数据库存储的问题。一个paper…

【MySQL排错 】mysql: command not found 数据库安装后无法加载的解决办法

【MySQL排错 】mysql: command not found 数据库安装后无法加载的解决办法 A Solution to Solve Error - mysql: command not found After The Installation of MySQL Community Server By JacksonML 本文简要介绍如何在macOS安装完毕MySQL数据库服务器后&#xff0c;针对无…

分享一款AI绘画图片展示和分享的小程序

&#x1f3a8;奇绘图册 【开源】一款帮AI绘画爱好者维护绘图作品的小程序 查看Demo 反馈 github 文章目录 前言一、奇绘图册是什么&#xff1f;二、项目全景三、预览体验3.1 截图示例3.2 在线体验 四、功能介绍4.1 小程序4.2 服务端 五、安装部署5.1 快速开始~~5.2 手动部…

大模型知识蒸馏技术(4)——离线蒸馏

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl离线蒸馏概述 离线蒸馏是知识蒸馏中最早被提出且最为常见的实现方式,其核心在于教师模型和学生模型的训练是分阶段进行的。具体而言,教师模型首先在训练集上进行充分训练,直至收敛,然后利用教…

解决DeepSeek服务器繁忙的有效方法

全球42%的企业遭遇过AI工具服务器过载导致内容生产中断&#xff08;数据来源&#xff1a;Gartner 2025&#xff09;。当竞品在凌晨3点自动发布「智能家居安装指南」时&#xff0c;你的团队可能正因DeepSeek服务器繁忙错失「净水器保养教程」的流量黄金期⏳。147SEO智能调度系统…

BT401双模音频蓝牙模块如何开启ble的透传,有什么注意事项

BT401音频蓝牙模块如何开启ble的透传&#xff1f; 首先BT401的蓝牙音频模块&#xff0c;分为两个版本&#xff0c;dac版本和iis数字音频版本 DAC版本&#xff1a;就是BT401蓝牙模块【9和10脚】直接输出模拟音频信号&#xff0c;也就是说&#xff0c;直接推动耳机可以听到声音 …

基于SSM框架的宠物之家系统(有源码+论文!!!)

这个系统可以帮助大家去做设计或者学习,大家可以管我要word版论文🥰这里具体论文内照片、e-r图等等加载不进来, 大家如果想要源码+论文+制定+调试,可以私信我!!(可改别的系统,例如调查问卷系统等等) 目录 第1章 绪论 1.1开发背景 1.2开发工具及语言 第2章 宠物之家系…

网工项目理论1.7 设备选型

本专栏持续更新&#xff0c;整一个专栏为一个大型复杂网络工程项目。阅读本文章之前务必先看《本专栏必读》。 一.交换机选型要点 制式:盒式交换机/框式交换机。功能:二层交换机/三层交换机。端口密度:每交换机可以提供的端口数量。端口速率:百兆/千兆/万兆。交换容量:交换矩阵…

Gateway中的Filter机制

Gateway中的Filter机制 文章目录 Gateway中的Filter机制Gateway中的Filter机制Gateway Filter 机制的概述核心思想与设计Filter 的两种类型过滤器的生命周期Gateway Filter 的特点Gateway Filter 的意义Gateway Filter 的工作原理核心架构与执行流程执行流程解析过滤器类型的角…

顺序表常用操作和笔试题

1、顺序表的常用操作 1.1 顺序表的创建 如下代码所示&#xff1a;创建了一个默认空间为10的整型顺序表&#xff0c;如果空间不足则会以1.5倍扩容。 List<Integer> list new ArrayList<>(); 创建一个空间为15的整型顺序表 List<Integer> list2 new ArrayL…

二.数据治理流程架构

1、数据治理流程架构核心思想&#xff1a; 该图描绘了一个以数据标准规范体系为核心&#xff0c;大数据生命周期管理为主线&#xff0c;数据资源中心为依托&#xff0c;并辅以数据质量管理和大数据安全与隐私管理的数据治理流程架构。它旨在通过规范化的流程和技术手段&#x…

解锁机器学习核心算法 | 线性回归:机器学习的基石

在机器学习的众多算法中&#xff0c;线性回归宛如一块基石&#xff0c;看似质朴无华&#xff0c;却稳稳支撑起诸多复杂模型的架构。它是我们初涉机器学习领域时便会邂逅的算法之一&#xff0c;其原理与应用广泛渗透于各个领域。无论是预测房价走势、剖析股票市场波动&#xff0…

CSS 底部颗粒磨砂特效

参考&#xff1a;element-plus的顶部效果 background-image: radial-gradient(transparent 1px, var(--bg-color) 1px); background-size: 4px 4px; backdrop-filter: saturate(50%) blur(4px); 注意点&#xff1a;var(--bg-color) 改为跟你背景色相同的即可。 其他自己看情况…