1. 程式人生 > >從cimutils到核心-(5)一幀資料採集完成控制器響應中斷處理函式

從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判斷,有資料

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就能從視訊快取佇列中取出資料