一开始郁闷v4l2的应用程序调用VIDIOC_S_CTRL设置camera的曝光和增益参数时一直返回失败,跟踪发现并没有调用到sensor驱动的s_ctrl,最后跟踪发现,连v4l2驱动的ioctl里面的VIDIOC_S_CTRLswitch也没有进去,最后在ioctl接口中打印cmd数值发现,应用传下来的VIDIOC_S_CTRL和驱动里面的VIDIOC_S_CTRL值都不相同,如下图:
最后跟踪发现是全志自己在内核的v4l2_control结构体中添加了自己的参数,如下图:
而标准的v4l2_control定义如下:
而VIDIOC_S_CTRL定义如下:
#define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control)
#define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control)
#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOC(dir,type,nr,size) \
(((dir) << _IOC_DIRSHIFT) | \
((type) << _IOC_TYPESHIFT) | \
((nr) << _IOC_NRSHIFT) | \
((size) << _IOC_SIZESHIFT))
#define _IOC_TYPECHECK(t) \
((sizeof(t) == sizeof(t[1]) && \
sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
sizeof(t) : __invalid_size_argument_for_IOC)
#define _IOC_NRBITS 8
#define _IOC_TYPEBITS 8
/*
* Let any architecture override either of the following before
* including this file.
*/
#ifndef _IOC_SIZEBITS
# define _IOC_SIZEBITS 14
#endif
#ifndef _IOC_DIRBITS
# define _IOC_DIRBITS 2
#endif
#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
#define _IOC_NRSHIFT 0
#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
其中发现cmd的第16~19位数据不同,根据cmd的构造原理发现是sizeof(v4l2_control)的结果导致,全志内核的v4l2_control算出来的结果是12即C,而标准的v4l2_control计算的结果是8,而应用层使用的是标准的v4l2_control,导致应用程序传递下来的VIDIOC_S_CTRL和VIDIOC_G_CTRL和内核计算出来的结果不一致,所以设置camera参数失败导致。
解决办法,修改标准的v4l2_control定义,添加类似全志平台的用户指针参数。