米尔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架构的优化编译和链接选项比如-mcpucortex-a53crc就指定了具体的CPU型号并开启了CRC扩展指令集支持能生成性能更优的代码。注意这个环境设置脚本特别检查了LD_LIBRARY_PATH变量。如果这个变量被设置脚本会报错并拒绝激活。这是因为LD_LIBRARY_PATH会干扰SDK自身库的查找是一个潜在的“坏习惯”。如果你之前的环境有设置需要先执行unset LD_LIBRARY_PATH。激活后你可以通过which aarch64-poky-linux-gcc和aarch64-poky-linux-gcc --version来验证交叉编译器是否就绪。我这里的版本是9.2.0对C11/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 bs1M count1024 convfdatasyncif/dev/zero输入文件是“零设备”提供全零数据流。of/tmp/testfile输出文件到/tmp目录下的testfile。注意/tmp目录在我的测试中挂载在eMMC上。bs1M块大小为1兆字节。count1024块数量为1024总计1024MB1GB数据。convfdatasync这是关键参数。它要求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 bs1M count1024echo 3 /proc/sys/vm/drop_caches这个命令清除了页缓存、目录项和inode缓存确保接下来的读取是真正的磁盘读取而不是从内存缓存中读取。if/tmp/testfile从刚才生成的文件读取。of/dev/null输出到“空设备”即丢弃数据只测试读取速度。这次不需要convfdatasync。测试结果显示读取1GB数据仅耗时约4.3秒读取速度高达238 MB/s。这个读取速度非常出色远超写入速度这是eMMC存储的典型特征。高速读取对于系统启动、应用启动和媒体播放等场景至关重要。3.2 性能解读与选型思考这个“读写不对称”的性能表现读快写慢完全符合eMMC的设计特点。eMMC内部是一个NAND闪存芯片加上一个集成的控制器其写入过程涉及复杂的擦除、编程操作而读取则简单得多。对于MYS-8MMX的目标应用视频监控高速读取能力可以保证多路视频流回放、历史录像检索的流畅性。写入速度36.8MB/s也足以应对多路1080p视频的同步录制估算一路H.264 1080p30fps码流约4-8MB/s。边缘计算网关模型文件加载读取速度飞快有利于AI推理任务的快速启动。数据日志的写入速度也能满足常规需求。工业HMI系统界面资源、历史数据的加载会非常迅速提升用户体验。实操心得dd测试是一个快速参考但实际应用场景往往是随机读写混合。如果你开发的是数据库类或频繁进行小文件读写的应用建议使用fio工具进行更全面的随机读写、IOPS每秒输入输出操作次数测试。命令如fio --namerandwrite --ioenginelibaio --rwrandwrite --bs4k --size256M --numjobs1 --runtime60 --time_based --group_reporting。这能帮你更准确地评估存储子系统在特定负载下的表现。4. 实战项目构建网络视频监控系统纸上得来终觉浅绝知此事要躬行。为了充分体验MYS-8MMX在多媒体和网络方面的能力我决定在其上搭建一个网络视频监控系统。核心是利用一个支持UVCUSB Video Class的USB摄像头通过流媒体服务器将视频推送到网络实现远程查看。我选择了经典且轻量的MJPG-streamer作为服务器软件。4.1 为什么选择MJPG-streamer市面上流媒体方案很多如GStreamer管道、VLC、Motion等。选择MJPG-streamer基于以下几点考量轻量高效核心功能专注在M-JPEG流的抓取和传输上代码简洁资源占用小非常适合在嵌入式设备上运行。协议简单基于HTTP传输M-JPEG图片流客户端兼容性极佳任何现代浏览器Chrome, Firefox, Edge无需插件即可直接观看。插件化架构输入如从摄像头抓图、输出如通过HTTP发布功能分离为插件可以根据需要灵活组合。例如可以同时将视频流输出到浏览器和保存到文件。低延迟M-JPEG流本质是一系列连续的JPEG图片处理延迟相对于H.264/H.265编码再解码要低很多适合对实时性要求较高的监控预览。4.2 交叉编译依赖库与MJPG-streamerMJPG-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 --hostaarch64-poky-linux --prefix/home/yourname/work/jpeg_install make make install--host参数告诉配置脚本我们是为ARM64架构的Linux交叉编译。编译完成后在/home/yourname/work/jpeg_install目录下会得到include/和lib/文件夹里面就是交叉编译好的头文件和库。2. 编译MJPG-streamer从GitHubhttps://github.com/jacksonliam/mjpg-streamer下载源码。解压后进入目录。 关键的编译步骤是修改Makefile或通过命令行参数指定交叉编译器和依赖库路径。最直接的方法是在执行make时传递参数make CCaarch64-poky-linux-gcc LDLIBS-L/home/yourname/work/jpeg_install/lib -ljpeg CFLAGS-I/home/yourname/work/jpeg_install/includeCC指定交叉编译器。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.so和output_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界面文件目录./wwwMJPG-streamer自带一个简单的网页。启动成功后在局域网内的任何设备的浏览器中输入http://开发板IP:8080即可访问控制页面。点击“Stream”或直接访问http://开发板IP:8080/?actionstream就能看到实时视频流。访问http://开发板IP:8080/?actionsnapshot则可以获取一张静态的JPEG快照。更酷的玩法利用命令行工具curl可以轻松实现远程抓图这对于自动化监控、图像采集非常有用。# 在另一台Linux主机或Windows PowerShell上 curl http://192.168.1.120:8080/?actionsnapshot -o snapshot.jpg这条命令会从开发板的摄像头抓取当前画面并保存为snapshot.jpg。你可以将此命令放入定时任务cron实现定时抓拍或者结合图像分析脚本实现简单的移动侦测。5. 开发板试用深度解析与避坑指南经过从环境搭建到实际项目部署的完整流程我对米尔MYS-8MMX开发板有了更立体的认识。它不仅仅是一块性能不错的硬件其背后由米尔提供的软件支持BSP、SDK、文档才是让开发者能够快速上手的真正关键。5.1 软件生态与资源评估米尔为i.MX 8M Mini平台适配的Linux BSPBoard Support Package基于NXP官方的L5.4.47_2.2.0内核版本并整合了Yocto Zeus (3.0)构建系统。这套软件栈的优点是长期支持内核和Yocto版本都属于长期支持LTS版本社区和维护周期有保障。功能完整包含了GPUVivante、VPU视频编解码、音频等所有核心硬件的驱动开箱即用。易于定制Yocto项目使得深度定制文件系统、裁剪或添加软件包变得有章可循。然而对于新手来说Yocto的学习曲线可能比较陡峭。如果你只需要运行一些现成的应用程序米尔提供的预编译镜像完全足够。但如果你想修改内核配置、添加自定义驱动、或者优化系统服务就必须投入时间学习Yocto的层Layer、配方Recipe和比特巴克BitBake工作流程。5.2 常见问题与排查实录在实际测评和开发过程中我遇到并总结了一些典型问题及其解决方法问题一USB摄像头无法识别或MJPG-streamer报错“不能打开视频设备”。排查步骤首先在开发板上运行ls /dev/video*检查设备节点是否存在。如果不存在可能是摄像头驱动未加载或摄像头供电不足。使用lsusb命令查看USB设备列表确认摄像头已被系统识别。安装v4l-utils工具包Yocto中可以通过添加v4l-utils包来包含使用v4l2-ctl --list-devices查看详细的V4L2设备信息。尝试使用v4l2-ctl --device/dev/video0 --all查看摄像头的支持格式、分辨率等信息确认摄像头是否支持MJPEG或YUYV等格式。可能原因与解决供电不足部分高清摄像头功耗较大尝试使用带外部供电的USB HUB连接。格式不支持MJPG-streamer的UVC插件默认可能寻找特定格式。尝试在启动参数中明确指定格式如-y使用YUYV格式而非MJPEG。注意使用YUYV格式需要CPU进行软压缩负载会增高。权限问题确保运行程序的用户有访问/dev/video0的权限通常是video用户组。可以将用户加入video组或者直接以root运行不推荐生产环境。问题二交叉编译的程序在开发板上运行时提示“找不到动态库”。排查步骤在开发板上使用ldd 你的程序命令查看程序依赖哪些动态库以及这些库在板子上的路径是否都能找到。对比编译时链接的库可以通过readelf -d 你的程序 | grep NEEDED查看和板子上实际存在的库版本是否兼容。解决方案将编译时依赖的所有动态库包括交叉编译工具链中的目标系统库和自行编译的第三方库一起拷贝到开发板。在开发板上通过export LD_LIBRARY_PATH/path/to/your/libs:$LD_LIBRARY_PATH临时指定库路径或将其写入启动脚本。最佳实践在Yocto中为你的应用程序创建一个自定义的Recipe将依赖的库作为DEPENDS声明让Yocto在构建根文件系统时自动包含它们并打包到最终的镜像中。问题三网络摄像头视频流在浏览器中卡顿或延迟高。分析方向网络带宽高分辨率如1080p、高帧率30fps的MJPEG流对网络带宽要求很高。确保开发板和客户端处于同一局域网且没有网络瓶颈。可以尝试降低分辨率-r 640x480或帧率-f 15。开发板CPU负载运行top命令查看mjpg_streamer进程的CPU占用率。如果使用YUYV格式并进行软编码CPU负载会非常重。尽量使用摄像头硬件支持的MJPEG格式。客户端性能浏览器渲染大量连续的JPEG图片也可能成为瓶颈。可以尝试不同的浏览器或者使用专用的客户端软件如VLC media player打开网络串流http://.../?actionstream。5.3 进阶探索与项目延伸建议基于MYS-8MMX搭建一个简单的网络摄像头只是起点它的潜力远不止于此。结合其硬件特性可以探索的方向包括硬编码视频流媒体i.MX 8M Mini集成了强大的VPU支持H.264和H.265的1080p60或4Kp30编解码。你可以使用GStreamer框架利用imxv4l2videosrc插件捕获摄像头数据通过vpuenc_h264插件进行硬件编码再通过rtph264pay和udpsink输出为RTP/UDP流或者用tcpserversink输出为TCP流。这将大幅提升视频压缩效率降低网络带宽占用并支持更远的传输距离和更复杂的播放器客户端。AI视觉应用集成在视频流的基础上可以接入AI推理框架。例如使用OpenCV已包含在米尔提供的镜像中抓取MJPG-streamer的快照snapshotURL进行图像处理和目标检测。更进一步可以部署TensorFlow Lite或ONNX Runtime运行轻量级神经网络模型如MobileNet SSD在视频流中实现实时的人脸检测、物体识别等功能构建真正的智能摄像头。系统服务化与稳定性优化将MJPG-streamer或GStreamer流水线配置为系统服务systemd service实现开机自启、崩溃自动重启。同时需要考虑日志管理、远程配置、多摄像头支持等生产环境所需的功能。米尔MYS-8MMX开发板以其均衡的性能、丰富的接口和成熟的软件支持为开发者提供了一个绝佳的嵌入式多媒体应用验证和开发平台。从开箱上电到完成一个可演示的网络监控项目整个过程遇到的障碍大多有迹可循社区和官方资源也能提供有效支持。对于希望踏入或深耕于边缘AIoT、智能视觉领域的开发者来说它是一块值得投入时间研究的“练功石”。