1. 项目背景与需求分析
在嵌入式视频监控系统中,Nginx作为高性能的Web服务器和反向代理服务器,能够为视频流提供稳定可靠的传输服务。STM32MP157作为一款双核Cortex-A7 + Cortex-M4的异构处理器,具备运行完整Linux系统的能力,这为Nginx的移植提供了硬件基础。
选择Nginx而非其他Web服务器的核心考量在于:
- 轻量级:内存占用小,适合资源受限的嵌入式环境
- 高并发:epoll机制支持大量视频流并发访问
- 模块化:可通过裁剪功能模块减少体积
- 稳定性:长期运行不崩溃,适合7×24小时监控场景
实际项目中,我们需要将Nginx移植到基于STM32MP157的开发板上,主要实现以下功能:
- 视频流的HTTP/RTMP传输
- 用户认证和访问控制
- 负载均衡(多摄像头场景)
- 日志记录和系统监控
2. 开发环境准备
2.1 硬件配置清单
- STM32MP157D-DK1开发板(双核A7@800MHz,1GB DDR3)
- 500万像素摄像头模块(OV5640)
- 16GB Class10 TF卡
- 千兆以太网转接器
- 5V/3A电源适配器
2.2 软件依赖项
bash复制# 交叉编译工具链
sudo apt-get install gcc-arm-linux-gnueabihf
# 基础库
sudo apt-get install libpcre3-dev zlib1g-dev openssl libssl-dev
# 文件系统工具
sudo apt-get install genext2fs
2.3 内核配置调整
由于标准Nginx需要较多的系统调用支持,需要重新配置内核:
bash复制make ARCH=arm menuconfig
关键配置项:
code复制[*] Networking support →
Networking options →
[*] TCP/IP networking
[*] IP: multicasting
[*] IP: advanced router
[*] IP: kernel level autoconfiguration
File systems →
[*] /proc file system support
[*] Virtual memory file system support
3. Nginx交叉编译实战
3.1 源码获取与配置
下载Nginx稳定版(以1.20.2为例):
bash复制wget http://nginx.org/download/nginx-1.20.2.tar.gz
tar zxvf nginx-1.20.2.tar.gz
cd nginx-1.20.2
配置编译参数(关键优化项):
bash复制./configure \
--prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-http_auth_request_module \
--with-threads \
--with-stream \
--with-stream_ssl_module \
--with-mail \
--with-mail_ssl_module \
--with-file-aio \
--with-http_v2_module \
--with-cc-opt="-O2 -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4" \
--crosscompile=arm-linux-gnueabihf
3.2 编译优化技巧
- 修改objs/Makefile,添加内存优化参数:
makefile复制CFLAGS = -pipe -O2 -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -fomit-frame-pointer -fstack-protector-strong
- 减少worker进程数(针对STM32MP157的双核特性):
bash复制sed -i 's/worker_processes 1;/worker_processes 2;/g' objs/nginx.conf
- 编译并安装:
bash复制make -j4
make install DESTDIR=`pwd`/build
4. 移植到STM32MP157
4.1 文件系统集成
将编译产物复制到根文件系统:
bash复制cp -r build/usr/local/nginx /mnt/rootfs/usr/local/
创建必要的目录和符号链接:
bash复制mkdir -p /mnt/rootfs/var/log/nginx
ln -s /usr/local/nginx/sbin/nginx /mnt/rootfs/usr/bin/nginx
4.2 初始化脚本
创建/etc/init.d/nginx启动脚本:
bash复制#!/bin/sh
DAEMON=/usr/local/nginx/sbin/nginx
PIDFILE=/var/run/nginx.pid
case "$1" in
start)
echo -n "Starting nginx: "
start-stop-daemon -S -q -x $DAEMON
echo "done"
;;
stop)
echo -n "Stopping nginx: "
start-stop-daemon -K -q -x $DAEMON
echo "done"
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit 0
设置可执行权限并添加自启动:
bash复制chmod +x /mnt/rootfs/etc/init.d/nginx
ln -s ../init.d/nginx /mnt/rootfs/etc/rc3.d/S90nginx
5. 视频监控专用配置
5.1 nginx.conf核心配置
nginx复制worker_processes 2;
events {
worker_connections 1024;
use epoll;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
# 视频流服务器配置
server {
listen 8080;
server_name localhost;
# 摄像头视频流
location /cam1 {
flv_live on;
gop_cache on;
access_log off;
# 用户认证
auth_basic "Camera Access";
auth_basic_user_file /usr/local/nginx/conf/htpasswd;
}
# 状态监控
location /status {
stub_status on;
access_log off;
allow 192.168.1.0/24;
deny all;
}
}
}
5.2 性能优化参数
- 调整内核参数(/etc/sysctl.conf):
conf复制net.core.rmem_max=4194304
net.core.wmem_max=4194304
net.ipv4.tcp_rmem=4096 87380 4194304
net.ipv4.tcp_wmem=4096 65536 4194304
- Nginx事件模型优化:
nginx复制events {
worker_connections 1024;
use epoll;
multi_accept on;
accept_mutex off;
}
6. 实际测试与问题排查
6.1 压力测试结果
使用JMeter进行并发测试(开发板通过千兆网卡连接):
- 100并发:CPU占用率65%,内存占用120MB
- 200并发:CPU占用率92%,内存占用180MB
- 300并发:出现部分请求超时
优化方案:
- 启用TCP Fast Open:
nginx复制http {
fastopen = 3;
}
- 调整内核积压队列:
bash复制echo 2048 > /proc/sys/net/core/somaxconn
6.2 常见问题解决方案
- 启动时报错:"bind() to 0.0.0.0:80 failed"
bash复制# 检查端口占用
netstat -tulnp | grep 80
# 或者修改Nginx监听端口
sed -i 's/listen 80;/listen 8080;/g' /usr/local/nginx/conf/nginx.conf
- 视频流卡顿问题排查:
bash复制# 查看网络延迟
ping -c 10 <摄像头IP>
# 检查Nginx worker进程CPU占用
top -p `pgrep -d',' nginx`
- 内存泄漏检测:
bash复制valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all nginx
7. 进阶功能扩展
7.1 RTMP模块集成
- 下载并编译nginx-rtmp-module:
bash复制git clone https://github.com/arut/nginx-rtmp-module.git
- 重新配置Nginx:
bash复制./configure --add-module=../nginx-rtmp-module [其他原有参数]
- 配置RTMP服务:
nginx复制rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
record off;
# 硬件加速
exec_static ffmpeg -i rtmp://localhost/$app/$name
-c:v h264_omx -b:v 2M
-f flv rtmp://localhost/hls/$name;
}
}
}
7.2 硬件加速配置
利用STM32MP157的GPU加速:
bash复制# 安装OpenMAX库
sudo apt-get install gstreamer1.0-omx
# FFmpeg编译时启用OMX支持
./configure --enable-omx --enable-omx-rpi
Nginx配置调整:
nginx复制location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /tmp;
add_header Cache-Control no-cache;
# 硬件加速转码
ffmpeg -i rtmp://localhost/live/$name
-c:v h264_omx -b:v 1M
-c:a aac -f flv rtmp://localhost/hls/$name;
}
