嵌入式 lwip http server makefsdata

背景:

基于君正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实际应用功能待更新。。。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

架构设计系列(三):架构模式

一、概述 关于移动应用开发中常见的架构模式&#xff0c;这些模式是为了克服早期模式的局限性而引入。常见的 架构模式有&#xff1a; MVC, MVP, MVVM, MVVM-C, and VIPER 二、MVC, MVP, MVVM, MVVM-C, and VIPER架构模式 MVC、MVP、MVVM、MVVM-C 和 VIPER 是移动应用开发中…

CSS盒模

CSS盒模型就像一个快递包裹&#xff0c;网页上的每个元素都可以看成是这样一个包裹&#xff0c;它主要由以下几个部分组成&#xff1a; 内容&#xff08;content&#xff09;&#xff1a;就像包裹里真正装的东西&#xff0c;比如文字、图片等。在CSS里&#xff0c;可用width&a…

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

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

Zookeeper 和 Redis 哪种更好?

目录 前言 &#xff1a; 什么是Zookeeper 和 Redis &#xff1f; 1. 核心定位与功能 2. 关键差异点 (1) 一致性模型 (2) 性能 (3) 数据容量 (4) 高可用性 3. 适用场景 使用 Zookeeper 的场景 使用 Redis 的场景 4. 替代方案 5. 如何选择&#xff1f; 6. 常见误区 7. 总结 前言…

动态规划从入坟走向入坑

目录 1.动态规划的含义 2.动态规划的解题步骤(动规五部曲) 3.动态规划的题型 4.相关思路 1.动规基础(由于我看的博主讲的动规很简单,所以这里就不讲了) 2.背包问题 1.二维dp数组01背包 1.dp[i][j] 表示从下标为[0-i]的物品里任意取&#xff0c;放进容量为j的背包&#xf…

Golang学习笔记_34——组合模式

Golang学习笔记_31——原型模式 Golang学习笔记_32——适配器模式 Golang学习笔记_33——桥接模式 文章目录 一、核心概念1. 定义2. 解决的问题3. 核心角色4. 类图 二、特点分析三、适用场景1. 文件系统2. 图形界面3. 组织架构 四、代码示例&#xff08;Go语言&#xff09;五、…

vue+elementplus创建初始化安装

项目创建初始化 D:\Tool\mysql\education_vue 这个路径下cmd 或打开vscode&#xff0c;把项目丢进code中打开 安装element plus Container 布局容器 | Element Plus npm install element-plus --save 把项目初始文件Homeview AboutView删了&#xff0c;Router index.js中删一…

SQL 优化工具使用之 explain 详解

一、导读 对于大部分开发人员来说&#xff0c;平常接触的无非就是增删改查这些基本操作&#xff0c;创建存储过程&#xff0c;视图等等都是 DBA 该干的活&#xff0c;但是想要把这些基本操作写的近乎完美也是一件难事。 而 explain 显示了 MySQL 如何使用索引来处理 select 语…

仿 Sora 之形,借物理模拟之技绘视频之彩

来自麻省理工学院、斯坦福大学、哥伦比亚大学以及康奈尔大学的研究人员携手开源了一款创新的3D交互视频模型——PhysDreamer&#xff08;以下简称“PD”&#xff09;。PD与OpenAI旗下的Sora相似&#xff0c;能够借助物理模拟技术来生成视频&#xff0c;这意味着PD所生成的视频蕴…

Python的顺序结构和循环结构

文章目录 一、条件语句&#xff08;1&#xff09;条件语句的定义&#xff08;2&#xff09;条件语句的语法&#xff08;a&#xff09;单分支 if&#xff08;b&#xff09;双分支 if-else&#xff08;c&#xff09;多分支 if-elif-elif-...-else &#xff08;3&#xff09;注意事…

04 redis数据类型

文章目录 redis数据类型string类型hash类型list类型set类型zset类型 &#xff08;sortedset&#xff09;通用命令 redis数据类型 官方命令&#xff1a;&#xff1a;http://www.redis.cn/commands.html Redis 中存储数据是通过 key-value 格式存储数据的&#xff0c;其中 val…

AutoGen:玩转多智能体团队协作 (Teams)

&#x1f449;&#x1f449;&#x1f449;本人承接各类AI相关应用开发项目(包括但不限于大模型微调、RAG、AI智能体、NLP、机器学习算法、运筹优化算法、数据分析EDA等) !!!&#x1f449;&#x1f449;&#x1f449; 有意愿请私信!!! AutoGen 的 AgentChat 模块为我们提供了强大…

Python PyCharm DeepSeek接入

Python PyCharm DeepSeek接入 创建API key 首先进入DeepSeek官网&#xff0c;https://www.deepseek.com/ 点击左侧“API Keys”&#xff0c;创建API key&#xff0c;输出名称为“AI” 点击“创建"&#xff0c;将API key保存&#xff0c;复制在其它地方。 在PyCharm中下…

分享8款AI生成PPT的工具!含测评

随着人工智能技术的飞速进步&#xff0c;制作PPT变得愈发便捷&#xff0c;仅需输入主题指令&#xff0c;便能在瞬间获得一份完整的演示文稿。尤其在制作篇幅较长的PPT时&#xff0c;手动编写每一页内容并设计格式和排版&#xff0c;不仅效率低下&#xff0c;而且耗时耗力。 本…

50页PDF|数字化转型成熟度模型与评估(附下载)

一、前言 这份报告依据GBT 43439-2023标准&#xff0c;详细介绍了数字化转型的成熟度模型和评估方法。报告将成熟度分为五个等级&#xff0c;从一级的基础转型意识&#xff0c;到五级的基于数据的生态价值构建与创新&#xff0c;涵盖了组织、技术、数据、资源、数字化运营等多…

aistdio部署deepseek-r1纯教程

前言 笔者电脑未扩容&#xff0c;想玩玩本地化的deepseek&#xff0c;苦于&#x1f447;久矣&#xff0c; 想到之前老师介绍的百度云平台飞桨AI Studio星河社区-人工智能学习与实训社区 于是就开始尝试部署终端版deepseek. 一、新建项目 1.打开飞桨网站&#xff0c;创建not…

实现动态翻转时钟效果的 HTML、CSS 和 JavaScript,附源码

实现动态翻转时钟效果的 HTML、CSS 和 JavaScript 在现代网页设计中&#xff0c;动画效果可以极大地增强用户体验。本文将介绍如何利用 HTML、CSS 和 JavaScript 创建一个动态翻转时钟的效果&#xff0c;模拟经典机械翻页时钟的视觉效果。我们将通过详细的步骤讲解如何实现时钟…

RagFlow+Ollama 构建RAG私有化知识库

RagFlowOllama 构建RAG私有化知识库 关于RAG一、什么是RAGFlow一、RAGFlow 安装配置测服已有服务&#xff1a; mysql、redis、elasticsearch 二、RAGFlow 配置 ollama&#xff1a;本地运行大型语言模型的工具软件。用户可以轻松下载、运行和管理各种开源 LLM。降低使用门槛&…

JavaScript(JS)

介绍 JavaScript(简称:JS)是一门跨平台、面向对象的脚本语言。是用来控制网页行为的&#xff0c;它能使网页可交互 JavaScript 和Java 是完全不同的语言&#xff0c;不论是概念还是设计。但是基础语法类似 JS引入方式 内部脚本:将JS代码定义在HTML页面中 JavaScript代码…

LLM 架构

LLM 分类 : 自编码模型 (encoder) : 代表模型 : BERT自回归模型 (decoder) : 代表模型 : GPT序列到序列模型 (encoder-decoder) : 代表模型 : T5 自编码模型 (AutoEncoder model , AE) 代表模型 : BERT (Bidirectional Encoder Representation from Transformers)特点 : Enc…