hi3536 uvc驱动配置

海思hi3536 usb摄像头驱动配置

Linux系统自带了usb摄像头驱动,在Linux系统中简称uvc驱动,有些系统中默认可能没有配置该驱动,或者需要进行裁剪,这个时候需要自己手动进行配置。配置过程如下:

  1. 在Device Drivers选项下选择Multimedia support

  1. 进入Multimedia support选项,选择Cameras/video grabbers support

  1. 进入Media USB Adapters选项,选中USB Video Class (UVC),可以根据实际需要将该模块编译进内核或者编程成ko文件。

上述步骤完成后可以编译出以下模块,然后用insmod命令加载模块:

insmod videodev.ko

insmod videobuf2-memops.ko

insmod videobuf2-vmalloc.ko

insmod videobuf2-core.ko

insmod uvcvideo.ko

 

加载成功后,会在板子上/dev目录下生成videoxx节点。然后就可以用Linux下v4l2那套接口采集视频。

下面附一段v4l2采集的demon程序。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <getopt.h>           
#include <fcntl.h>            
#include <unistd.h>
#include <errno.h>
#include <malloc.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>

#include <asm/types.h>        
#include <linux/videodev2.h>

#define CAMERA_DEVICE "/dev/video0"
#define CAPTURE_FILE "frame.jpg"

#define VIDEO_WIDTH 640
#define VIDEO_HEIGHT 480
#define VIDEO_FORMAT V4L2_PIX_FMT_YUYV
#define BUFFER_COUNT 4

typedef struct VideoBuffer {
    void   *start;
    size_t  length;
} VideoBuffer;


VideoBuffer framebuf[10];

int main()
{
    int i, ret;

    // 打开设备
    int fd;
    fd = open(CAMERA_DEVICE, O_RDWR, 0);
    if (fd < 0) {
        printf("Open %s failed\n", CAMERA_DEVICE);
        return -1;
    }

    // 获取驱动信息
    struct v4l2_capability cap;
    ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
    if (ret < 0) {
        printf("VIDIOC_QUERYCAP failed (%d)\n", ret);
        return ret;
    }
    // Print capability infomations
    printf("Capability Informations:\n");
    printf(" driver: %s\n", cap.driver);
    printf(" card: %s\n", cap.card);
    printf(" bus_info: %s\n", cap.bus_info);
    printf(" version: %08X\n", cap.version);
    printf(" capabilities: %08X\n", cap.capabilities);

    // 设置视频格式
    struct v4l2_format fmt;
    memset(&fmt, 0, sizeof(fmt));
    fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width       = VIDEO_WIDTH;
    fmt.fmt.pix.height      = VIDEO_HEIGHT;
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
    fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
    ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
    if (ret < 0) {
        printf("VIDIOC_S_FMT failed (%d)\n", ret);
        return ret;
    }

    // 获取视频格式
    ret = ioctl(fd, VIDIOC_G_FMT, &fmt);
    if (ret < 0) {
        printf("VIDIOC_G_FMT failed (%d)\n", ret);
        return ret;
    }
    // Print Stream Format
    printf("Stream Format Informations:\n");
    printf(" type: %d\n", fmt.type);
    printf(" width: %d\n", fmt.fmt.pix.width);
    printf(" height: %d\n", fmt.fmt.pix.height);
    char fmtstr[8];
    memset(fmtstr, 0, 8);
    memcpy(fmtstr, &fmt.fmt.pix.pixelformat, 4);
    printf(" pixelformat: %s\n", fmtstr);
    printf(" field: %d\n", fmt.fmt.pix.field);
    printf(" bytesperline: %d\n", fmt.fmt.pix.bytesperline);
    printf(" sizeimage: %d\n", fmt.fmt.pix.sizeimage);
    printf(" colorspace: %d\n", fmt.fmt.pix.colorspace);
    printf(" priv: %d\n", fmt.fmt.pix.priv);
    printf(" raw_date: %s\n", fmt.fmt.raw_data);

    // 请求分配内存
    struct v4l2_requestbuffers reqbuf;
    
    reqbuf.count = BUFFER_COUNT;
    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    reqbuf.memory = V4L2_MEMORY_MMAP;
    
    ret = ioctl(fd , VIDIOC_REQBUFS, &reqbuf);
    if(ret < 0) {
        printf("VIDIOC_REQBUFS failed (%d)\n", ret);
        return ret;
    }

    // 获取空间
    VideoBuffer*  buffers = calloc( reqbuf.count, sizeof(*buffers) );
    struct v4l2_buffer buf;

    for (i = 0; i < reqbuf.count; i++) 
    {
        buf.index = i;
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        ret = ioctl(fd , VIDIOC_QUERYBUF, &buf);
        if(ret < 0) {
            printf("VIDIOC_QUERYBUF (%d) failed (%d)\n", i, ret);
            return ret;
        }

        // mmap buffer
        framebuf[i].length = buf.length;
        framebuf[i].start = (char *) mmap(0, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
        if (framebuf[i].start == MAP_FAILED) {
            printf("mmap (%d) failed: %s\n", i, strerror(errno));
            return -1;
        }
    
        // Queen buffer
        ret = ioctl(fd , VIDIOC_QBUF, &buf);
        if (ret < 0) {
            printf("VIDIOC_QBUF (%d) failed (%d)\n", i, ret);
            return -1;
        }

        printf("Frame buffer %d: address=0x%x, length=%d\n", i, (unsigned int)framebuf[i].start, framebuf[i].length);
    }

    // 开始录制
    enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    ret = ioctl(fd, VIDIOC_STREAMON, &type);
    if (ret < 0) {
        printf("VIDIOC_STREAMON failed (%d)\n", ret);
        return ret;
    }

    // Process the frame
    FILE *fp = fopen(CAPTURE_FILE, "wb");
    if (fp < 0) {
        printf("open frame data file failed\n");
        return -1;
    }

    int cnt = 100;

    while(cnt--)
    {
        // Get frame
        ret = ioctl(fd, VIDIOC_DQBUF, &buf);
        if (ret < 0) {
            printf("VIDIOC_DQBUF failed (%d)\n", ret);
            return ret;
        }


        fwrite(framebuf[buf.index].start, 1, buf.length, fp);

        printf("Capture one frame saved in %s\n", CAPTURE_FILE);

        // Re-queen buffer
        ret = ioctl(fd, VIDIOC_QBUF, &buf);
        if (ret < 0) {
            printf("VIDIOC_QBUF failed (%d)\n", ret);
            return ret;
        }
    }

    fclose(fp);

    // Release the resource
    for (i=0; i< 4; i++) 
    {
        munmap(framebuf[i].start, framebuf[i].length);
    }

    close(fd);
    printf("Camera test Done.\n");
    return 0;
}

 

### 使用UVC协议与海思Hi3519DV500芯片进行视频捕获或流媒体 #### 海思Hi3519DV500简介 Hi3519DV500是一款专为视觉行业设计的超高清新智能SoC,能够支持高达4K@30fps的ISP图像处理能力,并具备多种高级特性如宽动态范围(WDR)、多级降噪、六轴防抖等功能[^2]。 #### UVC协议概述 USB Video Class (UVC) 是一种用于定义如何通过USB接口传输视频的标准。它允许设备无需安装特定驱动即可被操作系统识别并使用其内置摄像头或其他视频源的功能。对于基于Linux系统的嵌入式平台来说,实现UVC功能通常涉及到配置内核模块和支持库。 #### 实现步骤详解 ##### 准备工作环境 确保已经正确设置了开发环境,包括但不限于获取官方提供的SDK工具包,并按照文档说明完成必要的初始化操作。这一步骤至关重要,因为后续所有的开发活动都将依赖于此基础之上[^1]。 ##### 安装必要组件 为了让Hi3519DV500支持UVC功能,需要向目标板加载一些额外的支持文件,比如`libasound.so.2`及其关联的声音子系统资源(`alsa`)。这些软件包有助于构建完整的多媒体框架,从而使得硬件加速编码解码成为可能[^4]。 ##### 编译和部署应用程序 接下来就是编写具体的应用逻辑来控制摄像机的工作模式了。这里推荐采用官方样例工程中的`uvc_app`作为起点,因为它不仅实现了基本的数据采集流程,还展示了怎样调用API函数设置参数选项(例如分辨率大小)。值得注意的是,在实际运行前还需执行脚本命令`./ConfigUVC.sh`以激活相应的服务端口。 ```bash # 执行此命令启动UVC配置 ./ConfigUVC.sh start ``` ##### 运行测试案例 最后一步便是检验整个链路是否畅通无阻。可以通过连接一台PC主机来进行远程调试;当一切正常运作之后,则应该能够在宿主机侧看到来自远端设备传来的实时画面流。如果遇到任何异常情况,请参照错误提示信息逐步排查原因所在[^3]。 #### 注意事项 在整个过程中可能会碰到各种各样的挑战,特别是关于兼容性和性能优化方面的问题。建议密切跟踪社区论坛上的最新讨论帖,从中汲取宝贵的经验教训,同时也积极分享个人见解以便共同进步。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值