1. 嵌入式 WebServer:让开发板变身迷你网站服务器
嵌入式 WebServer 是在资源有限的微控制器上运行轻量级网络服务程序。它能够理解来自电脑或手机浏览器的 HTTP 请求,并返回一个网页。通过这个网页,就能远程监控设备状态,比如实时查看传感器读数,或者直接点击网页上的按钮来控制硬件开关、蜂鸣器鸣叫。这就像是给硬件设备开了一个'管理后台',而且这个后台是跨平台的,任何有浏览器的设备都能访问。
该功能的应用场景非常广泛。例如智能家居控制器,通过网页配置 Wi-Fi 参数、查看室内环境数据;或者工业数据采集终端,现场人员用手机扫个码就能看到设备运行状态,免去了开发专用 APP 的麻烦。
实现这个功能的核心主要靠两样东西:lwIP 协议栈和HTTP 服务器(httpd)。lwIP 是一个为嵌入式系统量身定制的轻量级 TCP/IP 协议栈,它让 STM32 这类芯片也能具备完整的网络通信能力。而 HTTP 服务器,则是 lwIP 提供的一个应用层组件,它负责处理'打开网页'这个动作背后的所有网络对话。CGI 和 SSI,就是构建在这个 HTTP 服务器之上的两把'瑞士军刀',专门用来实现网页与硬件之间的双向交互。
2. 核心概念拆解:CGI 与 SSI 到底能干什么?
在开始动手写代码之前,需要搞清楚 CGI 和 SSI 这两个概念。它们分工明确,一个主'外',一个主'内'。
CGI(通用网关接口),你可以把它想象成网页发给开发板的一条指令通道。当你在网页上点击一个'打开 LED'的按钮,这个点击动作会被浏览器包装成一个 HTTP 请求,发送到开发板。板子上的 HTTP 服务器收到后,发现这个请求的地址(如 /led_on.cgi)是一个 CGI 链接,就会唤醒对应的 CGI 处理函数。这个函数就像是一个命令解析器,它会解析请求中的参数,然后直接调用底层的硬件驱动函数,比如 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET),把 LED 点亮。最后,CGI 函数会返回一个结果,告诉浏览器指令执行成功了。所以,CGI 的核心是'控制',是网页对硬件设备的下发命令。
SSI(服务器端包含),它的角色则更像一个数据填充器。它的工作发生在服务器准备发送网页内容给浏览器之前。我们预先编写好的网页文件里,会埋藏一些特殊的标签,格式是 <!--#tag_name-->。当开发板收到请求,要发送这个网页时,它会逐行扫描文件内容,一旦发现这些 SSI 标签,就会调用我们预先注册好的 SSI 处理函数。这个函数根据标签的名字,去读取当前 ADC 转换的电压值,然后用这个真实的数值字符串,替换掉网页文件中的标签。替换完成后,一整份包含了实时数据的完整 HTML 代码,才被发送给浏览器显示。因此,SSI 的核心是'显示',是把硬件采集的实时数据上传并动态嵌入到网页中。
在实际项目中,通常用 CGI 来处理表单提交,比如修改系统参数、发送控制命令;用 SSI 来刷新仪表盘上的数值,比如实时刷新 CPU 占用率、网络流量或者传感器波形图。分清楚它们的职责,代码结构会清晰很多。
3. 实战第一步:搭建 lwIP 与 HTTP 服务器基础工程
理论讲得差不多了,现在开始实施。第一步,当然是准备一个能跑通网络的基础工程。此处以 STM32F407 开发板为例,它搭载了以太网 PHY 芯片,硬件基础很好。
3.1 工程配置与 lwIP 初始化
首先,你需要一个已经移植好 lwIP 协议栈的工程模板。官方例程里通常有'网络实验'相关的工程,直接拿来用是最快的。如果你是从零开始,那需要确保以下几点:
- 底层 HAL 库的 ETH(以太网)驱动正确配置,能完成 PHY 芯片的初始化和链路状态检测。
- lwIP 的
opt.h配置文件选项正确。对于 WebServer,以下选项必须启用:

