各位英雄:
小弟最近研究摄像头驱动(WINCE5.0+PXA270+OV9650),涉及到DMA中断。
BSP中至少有两个驱动使用DMA中断:
其一就是音频,在\Src\Kernel\Oal\intr.c文件中使用OALIntrStaticTranslate(SYSINTR_AUDIO, IRQ_DMAC);函数静态映射;
其二就是摄像头驱动,在驱动加载时使用KernelIoControl、LoadIntChainHandler等函数动态映射。
现在的问题时,我的摄像头驱动中收不到DMA中断。
问题请教:
1、IRQ和SYSINTR是不是只能是一对一?应该可以一对多吧?
2、多个设备同时使用IRQ_DMAC,而逻辑中断号SYSINTR各不相同;系统运行并产生DMA中断时,会不会因为映射关系混乱而导致部分设备不能接收中断?中断到来时,系统是如何区分它是哪个设备的DMA中断?或者说如何保证每个设备都能正常的接收到DMA中断信号?
3、OEMInterruptHandler函数和常说的ISR是什么关系?还有可安装的GIISR呢?
另外,SYSINTR_AUDIO为25,摄像头驱动调用KernelIoControl返回的SYSINTR为16。
1.通常我们会说IRQ和SYSINTR是一对一的;但这个IRQ并不严格指系统的中断号;
比如一个芯片把GPIO分成两个大集合:GPIOA,GPIOB,IRQ号分别为IRQ_GPIOA, IRQ_GPIOB;
实际上在GPIOA中,一共有32根GPIO,每根GPIO都可以产生一个系统中断,但系统中断号都为IRQ_GPIOA;
实际上这32个GPIO的每个中断都可以将其映射成为一个SYSINTR;
2.当然映射一定要正确;如果如你所说的系统里只有一个物理IRQ_DMAC,那么一定会在ISR中将不同DMA通道产生的中断区分开,并返回对应的逻辑中断号;这部分是BSP需要实现的;
3.通常我们会在OEMInterruptHandler中实现ISR的功能,所以这部分的执行时间不能太长,特别不能输出太多打印语句;GIISR实际上是被挂载在ISR处理链上;
另外,系统硬件使用的逻辑中断通常从SYSINTR_FIRMWARE开始,它的值等于16;
在OEMInterruptHandler函数中,调用了NKCallIntChain函数,是不是说,DMA中断到来时,系统默认先处理成ISR处理链,如果返回的是SYSINTR_CHAIN,再处理成静态映射的DMA中断?
ULONG OEMInterruptHandler(ULONG ra)
{
UINT32 irq = OAL_INTR_IRQ_UNDEFINED;
UINT32 sysIntr = SYSINTR_NOP;
...
// First find if IRQ is claimed by chain
sysIntr = (UINT16)NKCallIntChain((UCHAR)irq);
if (sysIntr == (UINT16)SYSINTR_CHAIN || !NKIsSysIntrValid(sysIntr))
{
// IRQ wasn't claimed, use static mapping
sysIntr = OALIntrTranslateIrq(irq);
}
...
return (sysIntr);
}
另外,KernelIoControl返回的SYSINTR为16,也即是SYSINTR_FIRMWARE,是不是说明返回有误?因为BSP中,系统中断号都是从SYSINTR_FIRMWARE+1开始的。
如:
// Static SYSINTR Mapping for driver.
#define SYSINTR_OHCI (SYSINTR_FIRMWARE+1) // 17
#define SYSINTR_TOUCH (SYSINTR_FIRMWARE+2) // 18
#define SYSINTR_TOUCH_CHANGED (SYSINTR_FIRMWARE+3) // 19
#define SYSINTR_KEYPAD (SYSINTR_FIRMWARE+4) // 20
另外附加一个问题:哪位英雄有PXA270下OV9650的标准寄存器配置啊?