fimc-dev.c 是Samsung FIMC 设备的V4L2 驱动。上层应用直接操作这个设备,进行capture,图片处理,以及overlay输出
http://blog.csdn.net/cxw3506/article/details/8476263
43 int fimc_dma_alloc(struct fimc_control *ctrl, struct fimc_buf_set *bs,
44 int i, int align)
45 {
46 dma_addr_t end, *curr;
47
48 mutex_lock(&ctrl->alloc_lock);
49
50 end = ctrl->mem.base + ctrl->mem.size;
51 curr = &ctrl->mem.curr;
52
53 if (!bs->length[i])
54 return -EINVAL;
55
56 if (!align) {
57 if (*curr + bs->length[i] > end) {
58 goto overflow;
59 } else {
60 bs->base[i] = *curr;
61 bs->garbage[i] = 0;
62 *curr += bs->length[i];
63 }
64 } else {
65 if (ALIGN(*curr, align) + bs->length[i] > end)
66 goto overflow;
67 else {
68 bs->base[i] = ALIGN(*curr, align);
69 bs->garbage[i] = ALIGN(*curr, align) - *curr;
70 *curr += (bs->length[i] + bs->garbage[i]);
71 }
72 }
73
74 mutex_unlock(&ctrl->alloc_lock);
75
76 return 0;
77
78 overflow:
79 bs->base[i] = 0;
80 bs->length[i] = 0;
81 bs->garbage[i] = 0;
82
83 mutex_unlock(&ctrl->alloc_lock);
84
85 return -ENOMEM;
86 }
这个函数很简单,之所以提出来说下,是因为我在DMA对齐问题上卡了一个多星期
FIMC使用预分配的物理内存来申请DMA buffer,参数中的align指明申请buffer的对齐方式,对于FIMC capture来说,似乎output DMA要求4k对齐(尽管我没有在datasheet中找到),如果给定的DMA地址没有4K对齐,FIMC DMA控制器会很聪明的从4K对齐的地址开始传送数据,这会导致了帧数据偏移。
@i 参数指定了plane数,FIMC 输出支持很多种格式,有单层的比如YUYV,两层的V4L2_PIX_FMT_NV12,还有三层的V4L2_PIX_FMT_NV12T
单层格式输出申请一个buffer,两层格式输出申请两个buffer,三层则需申请三个buffer。
88 void fimc_dma_free(struct fimc_control *ctrl, struct fimc_buf_set *bs, int i)
89 {
90 int total = bs->length[i] + bs->garbage[i];
91 mutex_lock(&ctrl->alloc_lock);
92
93 if (bs->base[i]) {
94 if (ctrl->mem.curr - total >= ctrl->mem.base)
95 ctrl->mem.curr -= total;
96
97 bs->base[i] = 0;
98 bs->length[i] = 0;
99 bs->garbage[i] = 0;
100 }
101
102 mutex_unlock(&ctrl->alloc_lock);
103 }
这个函数有问题,93 ~ 95 成立的条件是bs->base[i]所占的地址必须在ctrl->mem.base最后面,这就要求释放顺序必须从bs的最后一个节点向前释放。
655 static inline int fimc_mmap_cap(struct file *filp, struct vm_area_struct *vma)
656 {
657 struct fimc_prv_data *prv_data =
658 (struct fimc_prv_data *)filp->private_data;
659 struct fimc_control *ctrl = prv_data->ctrl;
660 u32 size = vma->vm_end - vma->vm_start;
661 u32 pfn, idx = vma->vm_pgoff;
662
663 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
664 vma->vm_flags |= VM_RESERVED;
665
666 /*
667 * page frame number of the address for a source frame
668 * to be stored at.
669 */
670 pfn = __phys_to_pfn(ctrl->cap->bufs[idx].base[0]);
671
672 if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED)) {
673 fimc_err('%s: writable mapping must be sharedn', __func__);
674 return -EINVAL;
675 }
676
677 if (remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot)) {
678 fimc_err('%s: mmap failn', __func__);
679 return -EINVAL;
680 }
681
682 return 0;
683 }
fimc capture 设备的mmap实现,ctrl->cap->bufs[idx]是fimc capture设备申请的buffer,mmap就是把这个buffer映射到应用程序空间
661 vma->vm_pgoff 表示vm_file内以PAGE_SIZE为单位的偏移,但是在这里应用层和内核使用另外一种约定的含义,buffer ID, 应用层调用mmap接口对fimc capture设备的buffer进行映射
700 static u32 fimc_poll(struct file *filp, poll_table *wait)
701 {
702 struct fimc_prv_data *prv_data =
703 (struct fimc_prv_data *)filp->private_data;
704 struct fimc_control *ctrl = prv_data->ctrl;
705 struct fimc_capinfo *cap = ctrl->cap;
706 u32 mask = 0;
707
708 if (cap) {
709 if (cap->irq || (ctrl->status != FIMC_STREAMON)) {
710 mask = POLLIN | POLLRDNORM;
711 cap->irq = 0;
712 } else {
713 poll_wait(filp, &ctrl->wq, wait);
714 }
715 }
716
717 return mask;
718 }
fimc_poll向上层应用提供了等待机制,应用程序poll fimc设备并阻塞,直到cap或者output中断处理函数唤醒
732 u32 fimc_mapping_rot_flip(u32 rot, u32 flip)
733 {
734 u32 ret = 0;
735
736 switch (rot) {
737 case 0:
738 if (flip & FIMC_XFLIP)
739 ret |= FIMC_XFLIP;
740
741 if (flip & FIMC_YFLIP)
742 ret |= FIMC_YFLIP;
743 break;
744
745 case 90:
746 ret = FIMC_ROT;
747 if (flip & FIMC_XFLIP)
748 ret |= FIMC_XFLIP;
749
750 if (flip & FIMC_YFLIP)
751 ret |= FIMC_YFLIP;
752 break;
753
754 case 180:
755 ret = (FIMC_XFLIP | FIMC_YFLIP);
756 if (flip & FIMC_XFLIP)
757 ret &= ~FIMC_XFLIP;
758
759 if (flip & FIMC_YFLIP)
760 ret &= ~FIMC_YFLIP;
761 break;
762
763 case 270:
764 ret = (FIMC_XFLIP | FIMC_YFLIP | FIMC_ROT);
765 if (flip & FIMC_XFLIP)
766 ret &= ~FIMC_XFLIP;
767
768 if (flip & FIMC_YFLIP)
769 ret &= ~FIMC_YFLIP;
770 break;
771 }
772
773 return ret;
774 }
rot会影响flip的结果,该函数映射(合并)rot和 flip操作
static int fimc_open(struct file *filp)
{
struct fimc_control *ctrl;
struct s3c_platform_fimc *pdata;
struct fimc_prv_data *prv_data;
上一篇:s5pv210移植Minigui3.0.12
下一篇:X210(s5pv210)中断系统
推荐阅读最新更新时间:2026-03-13 22:29
- BGA3015 - 5 至 300MHz、15dB 反向放大器应用
- led-panel:白光LED的LED面板分线板
- EVAL6480H,L6480 大功率步进电机驱动器演示板
- KIT33816FRDMEVM,MC33816 Freedom Board KL25Z 评估套件,喷油器
- STA333BW,用于数字音频功率放大器电视和便携式应用的评估板
- 使用 Analog Devices 的 LTC1439CG 的参考设计
- 使用 2 速时钟的 7.5us 模数转换器
- LDK130C33R 3.3V、300 mA 低静态电流、极低噪声 LDO 的典型应用固定版本电路
- LX7172、1.4MHz、1.2A 同步降压转换器的典型应用
- MIC2755 的典型应用:电池系统监控器



【Follow me第三季第4期】CY8CPROTO-063-BLE开发任务汇总代码
TYPE C3.0测试标准
使用PIC单片机控制心电前端ADS1192的实现单导心电测量
现代雷达系统的信号设计
LM311M
BFR340T






京公网安备 11010802033920号