当前位置: 首页 > news >正文

米尔MYS-8MMX开发板实战:从交叉编译到网络视频监控系统搭建

1. 开箱与初体验:米尔MYS-8MMX开发板印象

作为一名在嵌入式领域摸爬滚打多年的开发者,拿到一块新的开发板,那种感觉就像老木匠看到一块上好的木料,总想立刻上手试试它的“成色”。米尔电子这次推出的MYS-8MMX开发板,基于NXP i.MX 8M Mini这颗明星处理器,在圈内早就引起了不小的关注。当我有机会拿到实物进行深度测评时,第一印象是它的“工整”与“扎实”。板子布局非常清晰,核心的处理器、内存、eMMC、电源管理芯片各居其位,接口排布也充分考虑到了开发调试的便利性。板载的8GB eMMC和2GB LPDDR4内存,对于大多数边缘计算和多媒体应用来说,已经是一个相当充裕的起跑线了。最让我感兴趣的是它丰富的多媒体接口和强大的编解码能力,这直接指向了智能视觉、流媒体服务器、工业HMI等热门应用场景,也是我这次测评想要重点挖掘的方向。

2. 开发环境搭建:从SDK到交叉编译工具链

拿到板子,点亮系统只是第一步,真正的开发始于一个稳定、高效的开发环境。米尔为MYS-8MMX提供了基于Yocto项目构建的完整SDK,这大大降低了开发者的入门门槛。Yocto项目就像一个高度可定制的“Linux发行版工厂”,它允许你从源码开始,精确地构建出包含所需所有软件包、驱动和配置的完整根文件系统、内核以及配套的交叉编译工具链。米尔提供的SDK就是这个“工厂”产出的一个成熟“产品包”,里面已经为我们配置好了针对i.MX 8M Mini处理器(Cortex-A53核心)的优化选项。

2.1 SDK安装与环境变量配置

按照官方手册的指引,SDK的安装过程非常标准化。通常,你会得到一个以.sh结尾的安装脚本文件。在Ubuntu这样的Linux主机上,执行它即可。

./fsl-imx-xwayland-5.4-zeus.sh

安装过程会提示你选择安装路径。安装完成后,最关键的一步是“激活”这个SDK环境。SDK目录下会有一个名为environment-setup-aarch64-poky-linux的环境设置脚本。你需要source这个脚本,它会为当前终端会话设置一整套交叉编译所需的环境变量。

source /path/to/your/sdk/sysroots/x86_64-pokysdk-linux/environment-setup-aarch64-poky-linux

这个脚本做了哪些事呢?我们简单解读几个核心变量:

  • CC,CXX,AS,LD等:这些变量被设置为指向交叉编译工具链中的对应命令(如aarch64-poky-linux-gcc)。当你后续执行make时,Makefile会读取这些变量,自动调用正确的编译器。
  • SDKTARGETSYSROOT:这是目标系统(开发板)的根文件系统在主机上的镜像路径。编译器在链接时会到这里寻找库文件和头文件,确保编译出的程序能在板子上运行。
  • PATH:将交叉编译工具链的路径添加到系统PATH的最前面,确保命令行优先找到我们的交叉工具。
  • CFLAGS,LDFLAGS等:预设了针对ARM64架构的优化编译和链接选项,比如-mcpu=cortex-a53+crc就指定了具体的CPU型号并开启了CRC扩展指令集支持,能生成性能更优的代码。

注意:这个环境设置脚本特别检查了LD_LIBRARY_PATH变量。如果这个变量被设置,脚本会报错并拒绝激活。这是因为LD_LIBRARY_PATH会干扰SDK自身库的查找,是一个潜在的“坏习惯”。如果你之前的环境有设置,需要先执行unset LD_LIBRARY_PATH

激活后,你可以通过which aarch64-poky-linux-gccaarch64-poky-linux-gcc --version来验证交叉编译器是否就绪。我这里的版本是9.2.0,对C++11/14标准支持良好,为现代应用开发打下了基础。

2.2 工具链选择与构建系统集成

米尔提供的这个工具链是基于OpenEmbedded/Yocto的poky构建的,稳定性和与系统镜像的兼容性是最佳的。对于简单的应用,手动调用交叉编译器编译即可。但对于复杂的项目,更推荐使用CMake这类现代构建系统。

一个典型的CMake交叉编译工具链文件(例如命名为toolchain-aarch64.cmake)可以这样配置:

# 设置系统名称和目标处理器 set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR aarch64) # 指定交叉编译器路径(如果PATH已设置,通常只需指定前缀) set(CMAKE_C_COMPILER aarch64-poky-linux-gcc) set(CMAKE_CXX_COMPILER aarch64-poky-linux-g++) # 指定sysroot路径,这是关键! set(CMAKE_SYSROOT $ENV{SDKTARGETSYSROOT}) set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) # 只在sysroot中查找库和头文件 set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

然后在构建时指定这个工具链文件:

cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain-aarch64.cmake .. make

这样,CMake就会自动在SDKTARGETSYSROOT指向的目录下查找依赖库,生成能在MYS-8MMX上运行的可执行文件。

3. 核心性能摸底:存储与eMMC读写测试

开发板的基础性能决定了上层应用的“天花板”。MYS-8MMX板载的8GB eMMC是系统和数据存储的核心,它的读写速度直接影响系统启动、应用加载和文件操作的体验。在Linux下,我们常用dd命令结合time命令进行简单的磁盘性能测试。这虽然不能替代专业的IO基准测试工具(如fio),但能快速给出一个直观的参考。

3.1 测试方法与命令解析

测试通常分为顺序写入和顺序读取。为了减少文件系统缓存的影响,测试文件大小应远大于系统内存(这里为2GB)。我选择了一个约1GB的文件进行测试。

写入测试:测量从内存(通过/dev/zero生成数据)写入eMMC的速度。

time dd if=/dev/zero of=/tmp/testfile bs=1M count=1024 conv=fdatasync
  • if=/dev/zero:输入文件是“零设备”,提供全零数据流。
  • of=/tmp/testfile:输出文件到/tmp目录下的testfile。注意,/tmp目录在我的测试中挂载在eMMC上。
  • bs=1M:块大小为1兆字节。
  • count=1024:块数量为1024,总计1024MB(1GB)数据。
  • conv=fdatasync这是关键参数。它要求dd在命令结束前,将数据真正同步写入物理存储设备,而不是仅仅写到内核的页面缓存。这能反映真实的写入性能。
  • time命令会输出实际、用户和系统时间,我们主要看“real”实际耗时。

在我的测试中,写入1GB数据耗时约27.8秒,计算得出写入速度约为36.8 MB/s。这个速度对于eMMC 5.0或5.1规格来说,属于正常且不错的水平,能够保证系统流畅运行和大文件写入。

读取测试:测量从eMMC读取数据到内存(并丢弃到/dev/null)的速度。

# 首先清除内存缓存,让测试更准确 echo 3 > /proc/sys/vm/drop_caches time dd if=/tmp/testfile of=/dev/null bs=1M count=1024
  • echo 3 > /proc/sys/vm/drop_caches:这个命令清除了页缓存、目录项和inode缓存,确保接下来的读取是真正的磁盘读取,而不是从内存缓存中读取。
  • if=/tmp/testfile:从刚才生成的文件读取。
  • of=/dev/null:输出到“空设备”,即丢弃数据,只测试读取速度。
  • 这次不需要conv=fdatasync

测试结果显示,读取1GB数据仅耗时约4.3秒,读取速度高达238 MB/s。这个读取速度非常出色,远超写入速度,这是eMMC存储的典型特征。高速读取对于系统启动、应用启动和媒体播放等场景至关重要。

3.2 性能解读与选型思考

这个“读写不对称”的性能表现(读快写慢)完全符合eMMC的设计特点。eMMC内部是一个NAND闪存芯片加上一个集成的控制器,其写入过程涉及复杂的擦除、编程操作,而读取则简单得多。对于MYS-8MMX的目标应用:

  • 视频监控:高速读取能力可以保证多路视频流回放、历史录像检索的流畅性。写入速度36.8MB/s也足以应对多路1080p视频的同步录制(估算一路H.264 1080p@30fps码流约4-8MB/s)。
  • 边缘计算网关:模型文件加载(读取)速度飞快,有利于AI推理任务的快速启动。数据日志的写入速度也能满足常规需求。
  • 工业HMI:系统界面资源、历史数据的加载会非常迅速,提升用户体验。

实操心得dd测试是一个快速参考,但实际应用场景往往是随机读写混合。如果你开发的是数据库类或频繁进行小文件读写的应用,建议使用fio工具进行更全面的随机读写、IOPS(每秒输入输出操作次数)测试。命令如fio --name=randwrite --ioengine=libaio --rw=randwrite --bs=4k --size=256M --numjobs=1 --runtime=60 --time_based --group_reporting。这能帮你更准确地评估存储子系统在特定负载下的表现。

4. 实战项目:构建网络视频监控系统

纸上得来终觉浅,绝知此事要躬行。为了充分体验MYS-8MMX在多媒体和网络方面的能力,我决定在其上搭建一个网络视频监控系统。核心是利用一个支持UVC(USB Video Class)的USB摄像头,通过流媒体服务器将视频推送到网络,实现远程查看。我选择了经典且轻量的MJPG-streamer作为服务器软件。

4.1 为什么选择MJPG-streamer?

市面上流媒体方案很多,如GStreamer管道、VLC、Motion等。选择MJPG-streamer基于以下几点考量:

  1. 轻量高效:核心功能专注在M-JPEG流的抓取和传输上,代码简洁,资源占用小,非常适合在嵌入式设备上运行。
  2. 协议简单:基于HTTP传输M-JPEG图片流,客户端兼容性极佳,任何现代浏览器(Chrome, Firefox, Edge)无需插件即可直接观看。
  3. 插件化架构:输入(如从摄像头抓图)、输出(如通过HTTP发布)功能分离为插件,可以根据需要灵活组合。例如,可以同时将视频流输出到浏览器和保存到文件。
  4. 低延迟:M-JPEG流本质是一系列连续的JPEG图片,处理延迟相对于H.264/H.265编码再解码要低很多,适合对实时性要求较高的监控预览。

4.2 交叉编译依赖库与MJPG-streamer

MJPG-streamer的编译依赖JPEG库(用于图像编码/解码)。因此我们需要先交叉编译libjpeg

1. 编译libjpeg库:首先从官网(http://www.ijg.org/)下载源码,例如jpegsrc.v9d.tar.gz

tar -xvf jpegsrc.v9d.tar.gz cd jpeg-9d

在交叉编译前,务必确保已source了MYS-8MMX的SDK环境脚本,这样CC等环境变量已正确设置。然后配置、编译并安装到自定义目录,避免污染主机系统。

./configure --host=aarch64-poky-linux --prefix=/home/yourname/work/jpeg_install make make install

--host参数告诉配置脚本我们是为ARM64架构的Linux交叉编译。编译完成后,在/home/yourname/work/jpeg_install目录下会得到include/lib/文件夹,里面就是交叉编译好的头文件和库。

2. 编译MJPG-streamer:从GitHub(https://github.com/jacksonliam/mjpg-streamer)下载源码。解压后进入目录。 关键的编译步骤是修改Makefile或通过命令行参数指定交叉编译器和依赖库路径。最直接的方法是在执行make时传递参数:

make CC=aarch64-poky-linux-gcc LDLIBS+="-L/home/yourname/work/jpeg_install/lib -ljpeg" CFLAGS+="-I/home/yourname/work/jpeg_install/include"
  • CC:指定交叉编译器。
  • LDLIBS:添加链接库的路径和库名(-ljpeg)。
  • CFLAGS:添加头文件包含路径。

编译成功后,在plugins/input_uvc/plugins/output_http/等目录下会生成对应的.so插件文件,根目录下会生成mjpg_streamer可执行文件。

注意事项:如果编译过程中遇到关于linux/videodev.h头文件的错误,这是因为MJPG-streamer旧版本依赖V4L1的头文件,而现代Linux内核(MYS-8MMX使用的)主要使用V4L2。你需要确保使用的是支持V4L2的MJPG-streamer分支(如jacksonliam的版本),并在编译时可能需要定义USE_V4L2宏。有时需要修改源码,将#include <linux/videodev.h>替换为#include <linux/videodev2.h>

4.3 部署、运行与效果验证

将编译好的mjpg_streamer可执行文件、所需的.so插件(主要是input_uvc.sooutput_http.so)以及libjpeg.so库文件,一起拷贝到开发板上。我通常使用NFS网络文件系统挂载开发板的目录,这样在主机上编译后,开发板能直接运行,极大提高调试效率。

在开发板终端上,进入程序所在目录,运行以下命令启动流媒体服务器:

export LD_LIBRARY_PATH=$(pwd) # 将当前目录加入库搜索路径 ./mjpg_streamer -i "./input_uvc.so -d /dev/video0 -r 1280x720 -f 30" -o "./output_http.so -p 8080 -w ./www"
  • -i:指定输入插件。input_uvc.so从USB摄像头读取数据。-d指定设备节点(通常是/dev/video0),-r设置分辨率,-f设置帧率。
  • -o:指定输出插件。output_http.so启动一个Web服务器。-p设置端口号(8080),-w指定Web界面文件目录(./www,MJPG-streamer自带一个简单的网页)。

启动成功后,在局域网内的任何设备的浏览器中,输入http://<开发板IP>:8080即可访问控制页面。点击“Stream”或直接访问http://<开发板IP>:8080/?action=stream就能看到实时视频流。访问http://<开发板IP>:8080/?action=snapshot则可以获取一张静态的JPEG快照。

更酷的玩法:利用命令行工具curl,可以轻松实现远程抓图,这对于自动化监控、图像采集非常有用。

# 在另一台Linux主机或Windows PowerShell上 curl http://192.168.1.120:8080/?action=snapshot -o snapshot.jpg

这条命令会从开发板的摄像头抓取当前画面并保存为snapshot.jpg。你可以将此命令放入定时任务(cron),实现定时抓拍;或者结合图像分析脚本,实现简单的移动侦测。

5. 开发板试用深度解析与避坑指南

经过从环境搭建到实际项目部署的完整流程,我对米尔MYS-8MMX开发板有了更立体的认识。它不仅仅是一块性能不错的硬件,其背后由米尔提供的软件支持(BSP、SDK、文档)才是让开发者能够快速上手的真正关键。

5.1 软件生态与资源评估

米尔为i.MX 8M Mini平台适配的Linux BSP(Board Support Package)基于NXP官方的L5.4.47_2.2.0内核版本,并整合了Yocto Zeus (3.0)构建系统。这套软件栈的优点是:

  • 长期支持:内核和Yocto版本都属于长期支持(LTS)版本,社区和维护周期有保障。
  • 功能完整:包含了GPU(Vivante)、VPU(视频编解码)、音频等所有核心硬件的驱动,开箱即用。
  • 易于定制:Yocto项目使得深度定制文件系统、裁剪或添加软件包变得有章可循。

然而,对于新手来说,Yocto的学习曲线可能比较陡峭。如果你只需要运行一些现成的应用程序,米尔提供的预编译镜像完全足够。但如果你想修改内核配置、添加自定义驱动、或者优化系统服务,就必须投入时间学习Yocto的层(Layer)、配方(Recipe)和比特巴克(BitBake)工作流程。

5.2 常见问题与排查实录

在实际测评和开发过程中,我遇到并总结了一些典型问题及其解决方法:

问题一:USB摄像头无法识别或MJPG-streamer报错“不能打开视频设备”。

  • 排查步骤
    1. 首先在开发板上运行ls /dev/video*,检查设备节点是否存在。如果不存在,可能是摄像头驱动未加载或摄像头供电不足。
    2. 使用lsusb命令查看USB设备列表,确认摄像头已被系统识别。
    3. 安装v4l-utils工具包(Yocto中可以通过添加v4l-utils包来包含),使用v4l2-ctl --list-devices查看详细的V4L2设备信息。
    4. 尝试使用v4l2-ctl --device=/dev/video0 --all查看摄像头的支持格式、分辨率等信息,确认摄像头是否支持MJPEG或YUYV等格式。
  • 可能原因与解决
    • 供电不足:部分高清摄像头功耗较大,尝试使用带外部供电的USB HUB连接。
    • 格式不支持:MJPG-streamer的UVC插件默认可能寻找特定格式。尝试在启动参数中明确指定格式,如-y(使用YUYV格式而非MJPEG)。注意,使用YUYV格式需要CPU进行软压缩,负载会增高。
    • 权限问题:确保运行程序的用户有访问/dev/video0的权限(通常是video用户组)。可以将用户加入video组,或者直接以root运行(不推荐生产环境)。

问题二:交叉编译的程序在开发板上运行时提示“找不到动态库”。

  • 排查步骤
    1. 在开发板上使用ldd <你的程序>命令,查看程序依赖哪些动态库,以及这些库在板子上的路径是否都能找到。
    2. 对比编译时链接的库(可以通过readelf -d <你的程序> | grep NEEDED查看)和板子上实际存在的库版本是否兼容。
  • 解决方案
    • 将编译时依赖的所有动态库(包括交叉编译工具链中的目标系统库和自行编译的第三方库)一起拷贝到开发板。
    • 在开发板上,通过export LD_LIBRARY_PATH=/path/to/your/libs:$LD_LIBRARY_PATH临时指定库路径,或将其写入启动脚本。
    • 最佳实践:在Yocto中为你的应用程序创建一个自定义的Recipe,将依赖的库作为DEPENDS声明,让Yocto在构建根文件系统时自动包含它们,并打包到最终的镜像中。

问题三:网络摄像头视频流在浏览器中卡顿或延迟高。

  • 分析方向
    1. 网络带宽:高分辨率(如1080p)、高帧率(30fps)的MJPEG流对网络带宽要求很高。确保开发板和客户端处于同一局域网,且没有网络瓶颈。可以尝试降低分辨率(-r 640x480)或帧率(-f 15)。
    2. 开发板CPU负载:运行top命令查看mjpg_streamer进程的CPU占用率。如果使用YUYV格式并进行软编码,CPU负载会非常重。尽量使用摄像头硬件支持的MJPEG格式。
    3. 客户端性能:浏览器渲染大量连续的JPEG图片也可能成为瓶颈。可以尝试不同的浏览器,或者使用专用的客户端软件(如VLC media player打开网络串流http://.../?action=stream)。

5.3 进阶探索与项目延伸建议

基于MYS-8MMX搭建一个简单的网络摄像头只是起点,它的潜力远不止于此。结合其硬件特性,可以探索的方向包括:

  1. 硬编码视频流媒体:i.MX 8M Mini集成了强大的VPU,支持H.264和H.265的1080p60或4Kp30编解码。你可以使用GStreamer框架,利用imxv4l2videosrc插件捕获摄像头数据,通过vpuenc_h264插件进行硬件编码,再通过rtph264payudpsink输出为RTP/UDP流,或者用tcpserversink输出为TCP流。这将大幅提升视频压缩效率,降低网络带宽占用,并支持更远的传输距离和更复杂的播放器客户端。

  2. AI视觉应用集成:在视频流的基础上,可以接入AI推理框架。例如,使用OpenCV(已包含在米尔提供的镜像中)抓取MJPG-streamer的快照(snapshot)URL,进行图像处理和目标检测。更进一步,可以部署TensorFlow Lite或ONNX Runtime,运行轻量级神经网络模型(如MobileNet SSD),在视频流中实现实时的人脸检测、物体识别等功能,构建真正的智能摄像头。

  3. 系统服务化与稳定性优化:将MJPG-streamer或GStreamer流水线配置为系统服务(systemd service),实现开机自启、崩溃自动重启。同时,需要考虑日志管理、远程配置、多摄像头支持等生产环境所需的功能。

米尔MYS-8MMX开发板以其均衡的性能、丰富的接口和成熟的软件支持,为开发者提供了一个绝佳的嵌入式多媒体应用验证和开发平台。从开箱上电到完成一个可演示的网络监控项目,整个过程遇到的障碍大多有迹可循,社区和官方资源也能提供有效支持。对于希望踏入或深耕于边缘AIoT、智能视觉领域的开发者来说,它是一块值得投入时间研究的“练功石”。

http://www.jsqmd.com/news/828814/

相关文章:

  • 2026年苏州企业定制酱酒深度指南:盈贵人酒业与茅台镇源头品牌横评 - 精选优质企业推荐官
  • Java SE 在电商场景中的应用:面试官与燕双非的技术对话
  • PSpider最佳实践:从代码规范到部署运维的完整指南
  • 终极指南:3分钟学会用Onekey下载Steam游戏清单,告别手动烦恼
  • 浙江依米书院柯桥金地校区暑假班——家门口的学霸孵化器,做社区里最靠谱的教育好邻居 - 浙江教育测评
  • 终极指南:如何在macOS上解锁原生视频预览的全部潜力
  • 如何用Excalidraw虚拟白板彻底改变团队协作与创意表达?
  • 如何通过3大创新实现高精度纸张智能感知系统?
  • 3步开启iStoreOS容器之旅:路由器秒变家庭服务器的终极指南
  • 电感系数AL公式推导:从电磁学原理到磁芯选型设计
  • 2026年武汉企业商务用酒与封坛酱酒定制全攻略:盈贵人酒业直营模式深度解读 - 精选优质企业推荐官
  • 北京欧米茄表主必修课:欧米茄陶瓷表带“娇贵”易碎是谎言还是真相?2026最近养护与碎裂急救秘笈 - 亨得利官方维修中心
  • 运放电路分析核心:虚断与虚短原理及经典应用
  • 2026年昆山极致环保装修公司红黑榜与选型指南(母婴老人家庭必看) - 元点智创
  • Ryujinx游戏存档管理终极指南:从基础备份到高级恢复技巧
  • 基于全志T527开发板的手势识别:OpenCV部署与轮廓匹配实战
  • 别再让定位柱顶飞你的板子!AD2019里用Board Cutout正确挖元器件定位孔(附嘉立创等板厂差异说明)
  • 2026 流量卡副业全解析:佣金来源、套餐避坑、正规渠道|浩卡官方推荐码 111666 - 172号卡
  • AutoX.js实战:巧用OpenCV模板匹配应对多分辨率屏幕适配
  • 实测Taotoken多模型路由的稳定性与延迟体感观察
  • 2026年江苏省常州市隐形车衣与改色膜横向测评白皮书 - GrowthUME
  • 3小时从零部署WMS仓库管理系统:中小企业库存管理终极解决方案
  • 2026郑州企业定制酱酒怎么选?茅台镇源头直营品牌对标飞天性价比秘诀全解 - 精选优质企业推荐官
  • 在个人知识管理场景中集成多模型AI助手提升效率
  • 2026年在柯桥给娃找幼小衔接辅导班,我踩过的坑和最后的选择 - 奔跑123
  • 2026年成都酱酒定制与茅台镇源头品牌深度选购指南:从商务接待到招商加盟的完整破局方案 - 精选优质企业推荐官
  • RK3568工业核心板深度评测:性能、压力与温度边界全解析
  • 北京华江宏业建设工程机械:大兴正规的升降车租赁公司找哪家 - LYL仔仔
  • C语言入门指南:从核心概念到实战项目,掌握指针与内存管理
  • KS-Downloader完整指南:快手无水印视频批量下载终极方案