28从零写UVC驱动之实现设置属性
Posted 拉风摊主
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了28从零写UVC驱动之实现设置属性相关的知识,希望对你有一定的参考价值。
1. 先看APP以确定需要实现哪些接口
xawtv.c:
grabber_scan
ng_vid_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;
}
怎么去获得/设置属性?
看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,
},
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
entity->controls = kzalloc..
// 设置这些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
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
以上是关于28从零写UVC驱动之实现设置属性的主要内容,如果未能解决你的问题,请参考以下文章