硬件软件系统方案应用范例智能车大赛技术支持学习园地关于我们恩智浦官网

V4L2篇(2)V4L2应用程序的编译和运行

云实验室-V4L2应用程序的编译和运行

本文档涉及案例包括:

•        Linux V4L2最简单程序的编译和运行

•        i.MX 相机和显示Unit_test程序的编译和运行

执行步骤:

1.1       Linux V4L2最简单程序的编译和运行

先写一个最简单的v4l2的程序simple_v4l2_compile_test.c

首先需要包含v4l2的基本头文件,它提供了视频设备编程所需的定义和接口。

#include <linux/videodev2.h>

程序下一步打开了相机的设备节点,即/dev/video0,获取到该设备的句柄

fd = open("/dev/video0", O_RDONLY);

下一步使用ioctl函数,通过宏VIDIOC_QUERYCAP检查设备的能力

ioctl(fd, VIDIOC_QUERYCAP, &cap)

最后对该设备的部分cap进行打印,并关闭该设备。

完整代码如下:

/*
* Copyright 2025 NXP 
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
 
#include <linux/videodev2.h>
 
int main() {
    int fd;
    struct v4l2_capability cap;
 
    fd = open("/dev/video0", O_RDONLY);
    if (fd < 0) {
        perror("open");
        return 1;
    }
 
    if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
        perror("VIDIOC_QUERYCAP");
        close(fd);
        return 1;
    }
 
    printf("Driver: %s\nCard: %s\nBus: %s\n",
           cap.driver, cap.card, cap.bus_info);
 
    close(fd);
    return 0;
}

保存文件并退出后,尝试使用gcc进行编译:

gcc -o v4l2_example test.c -lv4l2

发现无法找到v4l2的库:

https://api.aiotcloud.nxp.com.cn/static/2025-3-13/eyyRdeRFkx图片1.png  

为解决该报错,这里尝试在文件系统根目录下搜索v4l2相关的文件

root@imx8mpevk:/# find -name "*v4l*"

打印log如下:

 

 https://api.aiotcloud.nxp.com.cn/static/2025-3-13/tWPMiMwhEn图片2.png

https://api.aiotcloud.nxp.com.cn/static/2025-3-13/yjXSzzwCaF图片3.png

之前编译篇中提到过:

如果库文件不在上述目录中,你需要使用 -L 参数指定库文件的路径。

例如,假设你有一个名为 libmylib.so 的库文件位于 /opt/mylib/lib 目录下,链接时应该这样写:

gcc -o myprogram myprogram.c -L/opt/mylib/lib -lmylib

这里 -lmylib 告诉 GCC 链接名为 mylib 的库,它会查找名为 libmylib.so 的文件。

log中可以看出,因命名区别,文件系统中确实没有叫做libv4l2.so的库文件,但是有许多名称类似的V4L2库文件。此时需要手动的将libv4l2.so.0复制一份名为libv4l2.so的文件

cp /usr/lib/libv4l2.so.0 /usr/lib/libv4l2.so

并进行重新编译,可以看到编译成功并能够正常运行

 https://api.aiotcloud.nxp.com.cn/static/2025-3-13/2sRPtCMAYY图片4.png

1.2       官网unit的下载和编译

在本机,用户可以通过git命令在github上抓取到i.MX系列MPU使用的测试工程

git clone https://github.com/nxp-imx/imx-test

或者直接通过网页浏览器访问github的imx-test工程,路径同上https://github.com/nxp-imx/imx-test

然后找到路径imx-test\test\mxc_v4l2_test下的mx8_v4l2_cap_drm.c文件。该文件是i.MX8/9系列的摄像头和显示的测试程序。可以通过直接鼠标复制,或者使用云服务器上传功能,将代码上传至云服务器上的i.MX93 EVK开发板中。

值得注意的是,为简化编译流程,需要注释掉soc检查相关的代码:  

https://api.aiotcloud.nxp.com.cn/static/2025-3-13/Hzk8K7843Z图片5.png  

https://api.aiotcloud.nxp.com.cn/static/2025-3-13/jwp2XiRBfW图片6.png

以及chipident的相关代码:

https://api.aiotcloud.nxp.com.cn/static/2025-3-13/4pzFQJXiNP图片7.png  

在完成以上两部分修改后,保存并退出代码编辑,下面将开始程序的编译过程。如果没有重命名v4l2的lib则需要重新命名一遍

cp /usr/lib/libv4l2.so.0 /usr/lib/libv4l2.so

因为改代码中不仅涉及到了V4L2的相关库,同样也包含有显示的功能,需要参考之前DRM编译的相关流程,加入libdrm的库文件。编译的命令如下:

gcc -o output mx8_v4l2_cap_drm.c -lv4l2 -I /usr/include/drm -ldrm

可以看到编译完成,之后可以直接运行程序,在没有参数输入的情况下,可以看到相关的帮助信息:

 https://api.aiotcloud.nxp.com.cn/static/2025-3-13/pczJhJcsPe图片8.png

这里先考虑最简单的测试参数。-cam可以指定使用的/dev/video标号,对于默认的i.MX93 MIPI-CSI相机AP1302而言,需要指定video0,使用-cam命令传递参数1即可,意味着使用第一个(即标号0)的V4L2设备。

在运行该程序之前请先关闭weston程序,让weston让出显示设备的控制权限。随后传递参数运行程序:

=> killall weston
=> ./output -cam 1

Log如下,程序正常运行:

 https://api.aiotcloud.nxp.com.cn/static/2025-3-13/xzTAiSrEJs图片9.png

并且可以通过摄像头看到,屏幕上可以看到AP1302 preview的动态图像:

https://api.aiotcloud.nxp.com.cn/static/2025-3-13/bGfmCNZwsB图片10.png