——————/
file_operations中函式會呼叫到v4l2_file_operations中的函式uvc_probe //uvc_driver.c硬體相關層,定會分配設定向核心層註冊一結構體
v4l2_device_register
uvc_register_chains
uvc_register_terms
uvc_register_video
struct video_device *vdev=video_device_alloc();
vdev->fops = &uvc_fops;
video_register_device(vdev,…… //核心v4l2_dev.c
static const struct file_operations v4l2_fops =
——————/
vivi_init
vivi_create_instance
v4l2_device_register //初始化
//struct vivi_dev *dev; struct v4l2_ctrl*volume;
dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops, //新增新的標準ctrl
v4l2_cid_audio_volume, 0, 255, 1, 200); //id,最小最大預設
…………
dev->button =v4l2_ctrl_new_custom(hdl, &vivi_ctrl_button, null);
…………
struct video_device *vfd=video_device_alloc;//分配
*vfd = vivi_template; //設定
vfd->v4l2_dev = &dev->v4l2_dev;
video_register_device(struct video_device *vdev,int type, int nr) //註冊
__video_register_device
switch (type) ;
static const struct v4l2_file_operations vivi_fops = ;
——————/分析讀寫過程
v4l2_open
struct video_device *vdev = video_devdata(filp);
//據次…從陣列中得到video_device結構體
return video_device[iminor(file->f_path.dentry->d_inode)];
if (vdev->fops->open)
……//若存在則呼叫,實際呼叫v4l2_file_operations的v4l2_fh_open
read、write過程同上
——————/
v4l2_ioctl
struct video_device *vdev = video_devdata(filp);
if (vdev->fops->unlocked_ioctl)
vdev->fops->unlocked_ioctl(filp, cmd, arg);
video_ioctl2
return video_usercopy(file, cmd, arg, __video_do_ioctl);
__video_do_ioctl(struct file *file,unsigned int cmd, void *arg)
struct video_device *vfd = video_devdata(file);
switch (cmd)
case vidioc_querycap:
……——————/
怎麼寫v4l2驅動?
① 分配/設定/註冊v4l2_device結構:v4l2_device_register
② 分配video_device:video_device_alloc
設定(包含v4l2_device指標,使其指向①所分配設定的)
註冊——————/
v4l2_ctrl_handler使用過程:vivi_create_instance
struct video_device *vfd;
struct vivi_dev *dev;
struct v4l2_ctrl_handler *hdl;
hdl = &dev->ctrl_handler;
v4l2_ctrl_handler_init(hdl, 11); //初始化ctrl_handler
dev->brightness = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,v4l2_cid_brightness, 0, 255, 1, 127);
dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,v4l2_cid_audio_volume, 0, 255, 1, 200);
…………
//handler含煉表頭,用v4l2_ctrl_new_std、v4l2_ctrl_new_custom向其新增v4l2_ctrl(屬性)
dev->v4l2_dev.ctrl_handler = hdl; //與v4l2_device關聯
vfd->v4l2_dev = &dev->v4l2_dev;
__video_register_device開頭
struct video_device *vdev;
if (vdev->ctrl_handler == null)
vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler;
static const struct v4l2_ioctl_ops vivi_ioctl_ops = ;
__video_do_ioctl
struct video_device *vfd = video_devdata(file);
const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
switch (cmd)
case vidioc_querycap:
ops->vidioc_querycap(file, fh, cap); //部分情況直接呼叫
……case vidioc_queryctrl:
if (vfd->ctrl_handler)
ret = v4l2_queryctrl(vfd->ctrl_handler, p);
struct v4l2_ctrl *ctrl;
struct v4l2_ctrl_ref *ref;
ref = find_ref(hdl, id); //據id從v4l2_ctrl_handler找到v4l2_ctrl
ctrl = ref->ctrl;
qc->minimum = ctrl->minimum; //返回其最小最大值預設值
qc->maximum = ctrl->maximum;
V4L2驅動框架
v4l2驅動框架 主裝置號 81 次裝置號 0 63 64 67 192 223 224 255 dev videox 應用層 char驅動 v4l2 具體的驅動 硬體應用層的操作都需要有底層v4l2驅動的支援。核心中有一些非常完善的例子。比如 linux 2.6.26核心目錄drivers med...
V4L2程式設計框架
v4l2較v4l有較大的改動,並已成為2.6的標準介面,函蓋video dvb fm 多數驅動都在向v4l2遷移。更好地了解v4l2先從應 來實現。用非阻塞模式開啟攝像頭裝置int camerafd camerafd open dev video0 o rdwr o nonblock,0 如果用阻塞...
V4L2程式設計框架( )
用非阻塞模式開啟攝像頭裝置 int camerafd camerafd open dev video0 o rdwr o nonblock,0 如果用阻塞模式開啟攝像頭裝置,上述 變為 camerafd open dev video0 o rdwr,0 int ioctl int fd,unsign...