zoukankan      html  css  js  c++  java
  • 28、从零写UVC驱动之实现设置属性

    1. 先看APP以确定需要实现哪些接口
    xawtv.c:
      grabber_scan
        ng_vid_open//根据链表的设置和读取可以在xawtv中找到是调用v4l2_driver.open
          v4l2_driver.open // v4l2_open
            get_device_capabilities(h);
              // 调用VIDIOC_QUERYCTRL ioctl确定是否支持某个属性
              /* controls */
              for (i = 0; i < MAX_CTRL; i++) {
                h->ctl[i].id = V4L2_CID_BASE+i;
                if (-1 == xioctl(h->fd, VIDIOC_QUERYCTRL, &h->ctl[i], EINVAL) ||
                (h->ctl[i].flags & V4L2_CTRL_FLAG_DISABLED))
                h->ctl[i].id = -1;//不支持会在这赋值-1,以后看到这个-1就表示不支持了
              }
    怎么去获得/设置属性?
    看drv0-v4l2.c
    可见这2个函数:
    v4l2_read_attr : VIDIOC_G_CTRL
    v4l2_write_attr : VIDIOC_S_CTRL

    所以: 视频驱动里要实现3个ioctl:
    VIDIOC_QUERYCTRL
    VIDIOC_G_CTRL
    VIDIOC_S_CTRL


    2. 硬件上怎么设置属性?
    2.1 UVC规范里定义了哪些属性 : uvc_ctrl.c里数组: static struct uvc_control_info uvc_ctrls[]

    {
    .entity = UVC_GUID_UVC_PROCESSING, // 属于哪了个entity(比如PU)
    .selector = PU_BRIGHTNESS_CONTROL, // 用于亮度
    .index = 0, // 对应Processing Unit Descriptor的bmControls[0]
    .size = 2, // 发给硬件的数据长度为2字节
    .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
    | UVC_CONTROL_RESTORE,
    },

    里面的每一项都对应一个属性,entity表示那个单元,这里是表示PU,selector 用于区分PU里面的那个功能属性,index是这个功能属性的位置

    2.2 我们的设备支持哪些属性
    这需要去看描述符, 比如 Processing Unit Descriptor的bmControls的值为7f 14
    可知BIT0为1,表示支持BRIGHTNESS

    在代码里:
    uvc_drvier.c
    uvc_ctrl_init_device
      // 对于每一个entity(IT,PU,SU,OT等)
        list_for_each_entry(entity, &dev->entities, list) {
          // 取出bmControls
          bmControls = ....

          // 计算bmControls里位值为1的个数,就是支持的属性个数
          ncontrols += hweight8(bmControls[i]);

          // 为每一个属性分配一个struct uvc_control,这些ctrl都在controls指向的buf中
          entity->controls = kzalloc(ncontrols *sizeof(*ctrl))

          // 设置这些struct uvc_control
          ctrl = entity->controls;
          for (...)
          {
            ctrl->entity = entity;
            ctrl->index = i;
          }

          // 把uvc_control和uvc_control_info挂构
          uvc_ctrl_add_ctrl(dev, info);
            ctrl->info = 某个uvc_control_info数组项(同属于一个entity, index相同)

    2.3 怎么去操作这些属性
      参考 uvc_query_v4l2_ctrl(应用程序会传下来一个id值,程序根据这个id值找到mapping结构体)
      uvc_find_control
        找到一个uvc_control_mapping结构体: uvc_ctrl.c里有static struct uvc_control_mapping uvc_ctrl_mappings[]
          {
            .id = V4L2_CID_BRIGHTNESS, // APP根据ID来找到对应的属性
            .name = "Brightness",
            .entity = UVC_GUID_UVC_PROCESSING, // 属于哪了个entity(比如PU)
            .selector = PU_BRIGHTNESS_CONTROL, // 用于亮度
            .size = 16, // 数据占多少位
            .offset = 0, // 从哪位开始
            .v4l2_type = V4L2_CTRL_TYPE_INTEGER, // 属性类别,用于应用图形显示怎么控制属性,是下拉还是滑动图标等
            .data_type = UVC_CTRL_DATA_TYPE_SIGNED,// 数据类型,用于用户下发控制属性的数据类型
           },

        uvc_control_mapping结构体 用来更加细致地描述属性

      uvc_query_ctrl
        usb_control_msg


    举例说明: 要设置亮度,怎么操作?
    a. 根据PU的描述符的bmControls, 从它的bit0等于1知道它支持调节亮度
    b. 在uvc_ctrls数组中根据entity和index找到这一项:
      {
        .entity = UVC_GUID_UVC_PROCESSING,
        .selector = PU_BRIGHTNESS_CONTROL,
        .index = 0,
        .size = 2,
        .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
            | UVC_CONTROL_RESTORE,
      },

    知道了:这个设备支持SET_CUR, GET_CUR, GET_MIN等
    要设置时,可以向PU的selector发数据, 发的数据是2字节

    c. 在uvc_ctrl_mappings数组中根据ID找到对应的数组项
    从而知道了更加细致的信息,
    然后使用usb_control_msg读写数据

    3. 怎么写代码?
    实现3个ioctl: vidioc_queryctrl/vidioc_g_ctrl/vidioc_s_ctrl
    vidioc_queryctrl : 发起USB控制传输获得亮度的最小值、最大值、默认值、步进值
    vidioc_s_ctrl : 把APP传入的亮度值通过USB传输发给硬件
    vidioc_g_ctrl : 发起USB传输获得当前亮度值

    要点:数据发给谁?发给usb_device的
                VideoControl Interface
                  里面的Processing Unit
                    里面的PU_BRIGHTNESS_CONTROL

  • 相关阅读:
    【第3版emWin教程】第41章 emWin6.x窗口管理器基础知识(重要)
    【第3版emWin教程】第40章 emWin6.x支持的颜色格式
    【第3版emWin教程】第39章 emWin6.x指针输入设备(摇杆)
    H7-TOOL迎来新版固件V2.08,Modbus助手,RTT波形展示和时间戳上线,新增美仁半导体,NXP MKE系列,华大F460系列等脱机烧录支持
    【第3版emWin教程】第38章 emWin6.x多任务设计
    嵌入式新闻早班车-第27期
    【第3版emWin教程】第37章 emWin6.x抗锯齿
    【STM32H7的DSP教程】第49章 STM32H7的自适应滤波器实现,无需Matlab生成系数(支持实时滤波)
    【STM32F429的DSP教程】第49章 STM32F429的自适应滤波器实现,无需Matlab生成系数(支持实时滤波)
    【STM32F407的DSP教程】第49章 STM32F407的自适应滤波器实现,无需Matlab生成系数(支持实时滤波)
  • 原文地址:https://www.cnblogs.com/liusiluandzhangkun/p/8748013.html
Copyright © 2011-2022 走看看