第二部分
v4l2使用時的**執行過程的分析
**********==
open操作:
當使用者呼叫open介面開啟/dev/videox時,會呼叫vdev->cdev->ops = &v4l2_fops;裡面設定的ops。
static const struct file_operations v4l2_fops = ;
static int v4l2_open(struct inode *inode, struct file *filp)
/* and increase the device refcount */
video_get(vdev);
mutex_unlock(&videodev_lock);
if (vdev->fops->open)
if (video_is_registered(vdev))
ret = vdev->fops->open(filp);
// 執行video device 的open操作,但是必須是通過__video_register_device註冊或video_register_device註冊的裝置
上文分析了,fimc的capture裝置和感測器子裝置被這樣註冊了,子裝置不是以video命名的。還有m2m capture裝置被註冊了,這兩個裝置是以video命名的。
else
ret = -enodev;
if (vdev->lock)
mutex_unlock(vdev->lock);
}err:
/* decrease the refcount in case of an error */
if (ret)
video_put(vdev);
return ret;
}在註冊m2m裝置是設定的是
vfd->fops = &fimc_m2m_fops;
在註冊capture裝置時,設定的是
vfd->fops = &fimc_capture_fops;
vfd->ioctl_ops = &fimc_capture_ioctl_ops;
先看看m2m裝置的操作
static int fimc_m2m_open(struct file *file)
if (fimc->m2m.refcnt++ == 0)
set_bit(st_m2m_run, &fimc->state); // 第一次open的時候設定此標誌
return 0;
error_c:
fimc_ctrls_delete(ctx);
error_fh:
v4l2_fh_del(&ctx->fh);
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
return ret;
}**********=
下面看看ioctl操作是如何進行的,
應用程式呼叫系統呼叫介面ioctl,進入核心後呼叫v4l2對應的unlock_ioctl函式,unlock_ioctl會呼叫__video_do_ioctl,如下
static long __video_do_ioctl(struct file *file,
unsigned int cmd, void *arg)
if ((vfd->debug & v4l2_debug_ioctl) &&
!(vfd->debug & v4l2_debug_ioctl_arg))
if (test_bit(v4l2_fl_uses_v4l2_fh, &vfd->flags))
if (use_fh_prio)
ret_prio = v4l2_prio_check(vfd->prio, vfh->prio);
switch (cmd)
static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = ;
m2m裝置streamon,啟動了dma,裡面設定了source位址和dest 位址,然後啟動dma。
***************=
下面看看capture裝置的相關操作
static const struct v4l2_file_operations fimc_capture_fops = ;
static int fimc_capture_open(struct file *file)
ret = fimc_capture_ctrls_create(fimc);
if (!ret && !fimc->vid_cap.user_subdev_api)
ret = fimc_capture_set_default_format(fimc);
}return ret;
}static int __fimc_pipeline_initialize(struct fimc_dev *fimc,
struct media_entity *me, bool prep)
int fimc_pipeline_initialize(struct fimc_dev *fimc, struct media_entity *me,
bool prep)
void fimc_pipeline_prepare(struct fimc_dev *fimc, struct media_entity *me)
}int fimc_capture_ctrls_create(struct fimc_dev *fimc)
int fimc_ctrls_create(struct fimc_ctx *ctx)
int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
struct v4l2_ctrl_handler *add)
mutex_unlock(&add->lock);
return ret;
}static int fimc_capture_set_default_format(struct fimc_dev *fimc),};
return fimc_capture_set_format(fimc, &fmt); // 設定一系列的型別,plane sensor........,挺多,這裡就不分析了。
}接下來看看streamon操作
static int fimc_cap_streamon(struct file *file, void *priv,
enum v4l2_buf_type type)
return vb2_streamon(&fimc->vid_cap.vbq, type);
}int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
if (type != q->type)
if (q->streaming)
/** if any buffers were queued before streamon,
* we can now pass them to driver for processing.
*/list_for_each_entry(vb, &q->queued_list, queued_entry)
__enqueue_in_driver(vb);
/** let driver notice that streaming state has been enabled.
*/ret = call_qop(q, start_streaming, q, atomic_read(&q->queued_count));
if (ret)
q->streaming = 1;
dprintk(3, "streamon successful\n");
return 0;
}static int start_streaming(struct vb2_queue *q, unsigned int count)
return 0;
error:
fimc_capture_state_cleanup(fimc, false);
return ret;
}static int fimc_init_capture(struct fimc_dev *fimc) // 操作暫存器了,
spin_unlock_irqrestore(&fimc->slock, flags);
return ret;
}所有的v4l2相關**就分析到此位置,如果有能幫得上忙的那說明我的努力沒有白費。有些地方有可能會有不當之處,還請指出。有什麼其他的問題也可一起**。
V4L2框架分析
uvc probe uvc driver.c硬體相關層,定會分配設定向核心層註冊一結構體 v4l2 device register uvc register chains uvc register terms uvc register video struct video device vdev v...
V4L2的學習筆記
學習的時候最好參看官方的v4l2開發文件,是英文,更詳細透徹。借鑑 一.什麼是 video4linux 1.開啟裝置檔案。vidioc s std,vidioc s fmt,struct v4l2 std id,struct v4l2 format 5.向驅動申請幀緩衝,一般不超過5個。struct...
V4L2程式設計
include include include include include include include include include include typedef struct buftype buftype user buf int n buffer 0 開啟攝像頭裝置 int ope...