从cimutils到内核-(5)一帧数据采集完成控制器响应中断处理函数

(1)

static irqreturn_t jz_camera_irq_handler(int irq, void *data) {

if(status & CIM_STATE_DMA_EOF) { //硬件发送这个EOF给控制器响应中断

/* clear dma interrupt status */

temp = readl(pcdev->base + CIM_STATE);

temp &= (~CIM_STATE_DMA_EOF);

writel(temp, pcdev->base + CIM_STATE);

if(pcdev->active) { //active判断,有数据

扫描二维码关注公众号,回复: 4219814 查看本文章

struct vb2_buffer *vb2 = &pcdev->active->vb2;

struct jz_buffer *buf = container_of(vb2, struct jz_buffer, vb2);

list_del_init(&buf->list);

v4l2_get_timestamp(&vb2->v4l2_buf.timestamp);

vb2->v4l2_buf.sequence = pcdev->sequence++;

vb2_buffer_done(vb2, VB2_BUF_STATE_DONE); //一帧数据采集完成,这个接口把采集完成的buffer从链表video_buffer_list加进done_list

/* start next dma frame. */

pcdev->active = list_entry(pcdev->video_buffer_list.next, struct jz_buffer, list);

}

void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)

{

list_add_tail(&vb->done_entry, &q->done_list);

wake_up(&q->done_wq); //唤醒进程

}

(2)

应用层调用select后,调用我们控制器驱动的接口jz_camera_poll

static unsigned int jz_camera_poll(struct file *file, poll_table *pt)

{

struct soc_camera_device *icd = file->private_data;

return vb2_poll(&icd->vb2_vidq, file, pt);

}

unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)

{

if (list_empty(&q->done_list))

poll_wait(file, &q->done_wq, wait); //done_list是空的话,poll_wait等待,等待中断唤醒

}

总结:

把有数据的buffer[0]加进done_list链表后,应用层调用dqbuf就能从视频缓存队列中取出数据

猜你喜欢

转载自blog.csdn.net/sinat_37817094/article/details/83849335
今日推荐