我用的是sangsun2440,号称是WINCE5.0 BSP的开发板.现因处理一按键(对应EINT19)中断.陷入迷惑.
BSP里面的OEMinit函数如下:
void OEMInit()
{
volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
// Instead of calling OEMWriteDebugString directly, call through exported
// function pointer. This will allow these messages to be seen if debug
// message output is redirected to Ethernet or the parallel port. Otherwise,
// lpWriteDebugStringFunc == OEMWriteDebugString.
lpWriteDebugStringFunc(TEXT("\nWindows CE Firmware Init\r\n"));
//if(!B)
//lpWriteDebugStringFunc(TEXT("HookInterrupt Failed...\r\n"));
#ifdef MODULE_CERTIFY
//
// Set the module signature verification hooks
//
pOEMLoadInit = OEMLoadInit;
pOEMLoadModule = OEMLoadModule;
//
// Init the signature verification public key
//
InitPubKey(g_bSignPublicKeyBlob,sizeof(g_bSignPublicKeyBlob));
#endif
//
// Set up translation constant for GetIdleTime() (1 ms units).
// Note: Since curridlehigh, curridlelow is counting in ms, and GetIdleTime()
// reports in ms, the conversion ratio is one. If curridlehigh, curridlelow
// were using other units (like ticks), then the conversion would be calculated
// from the clock frequency.
//
idleconv = 1;
// Initialize interrupts.
//
lpWriteDebugStringFunc(TEXT("INFO: Initializing system interrupts...\r\n"));
OEMInitInterrupts(); //出此函数源码贴在下面
// Initialize the system clock(s).
//
lpWriteDebugStringFunc(TEXT("INFO: Initializing system clock(s)...\r\n"));
InitClock();
// Initialize driver globals area.
//
lpWriteDebugStringFunc(TEXT("INFO: Initializing driver globals area...\r\n"));
memset((PVOID)DRIVER_GLOBALS_ZEROINIT_START, 0, DRIVER_GLOBALS_ZEROINIT_SIZE);
// Initialize S2440X01 LCD controller
InitDisplay();
#ifdef YL_2440_SUPPORT
HzhInitPIO();
#endif
// Initialize debug Ethernet (KITL) connection.
//
// InitDebugEther();
// Initialize GPIO /// ;;; SHL
s2440IOP->rPAD9 = (1<<12) | (0<<11); // what is rPAD9? hzh
//s2440IOP->rGPJCON = 0x016aaaa;
//s2440IOP->rGPJUP = ~((0<<12) | (1<<11));
s2440IOP->rGPHCON = (s2440IOP->rGPHCON & ~(0xf<<18)) | (1<<20) | (1<<18); // CLKOUT1, CLKOUT0
s2440IOP->rDSC0 = 0x3ff;
s2440IOP->rDSC1 = 0x3fffffff;
// camera
//Camera_Initialize();
//s2440IOP->rGPJCON = 0x2aaaaaa;
// s2440IOP->rGPJUP = 0x1fff;
InitSDMMC();
// Initialize the ROM chain (multi-region).
//
// InitRomChain();
lpWriteDebugStringFunc(TEXT("OEMInit Done...\r\n"));
lpWriteDebugStringFunc(TEXT("fhg******************************\r\n"));
}
static void OEMInitInterrupts(void) // for KITL 030828
{
volatile INTreg *s2440INT = (INTreg *)INT_BASE;
volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
// Configure EINT14 for DM9000 interrupt.
s2440IOP->rGPGCON = (s2440IOP->rGPGCON & ~(0x3 << 12)) | (0x2 << 12); // GPG6 == EINT14.
s2440IOP->rGPGUP = (s2440IOP->rGPGUP | (0x1 << 6)); // Disable pull-up.
s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0xf << 24)) | (0x1 << 24); // Level-high triggered.
// Configure EINT9 for CS8900 interrupt.
s2440IOP->rGPGCON = (s2440IOP->rGPGCON & ~(0x3 << 0x2)) | (0x2 << 0x2); // GPG1 == EINT9.
s2440IOP->rGPGUP = (s2440IOP->rGPGUP | (0x1 << 0x1)); // Disable pull-up.
s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0xf << 0x4)) | (0x1 << 0x4); // Level-high triggered.
#ifndef YL_2440_SUPPORT
// Configure EINT8 for PD6710 interrupt.
//
s2440IOP->rGPGCON = (s2440IOP->rGPGCON & ~(0x3 << 0x0)) | (0x2 << 0x0); // GPG0 == EINT8.
s2440IOP->rGPGUP = (s2440IOP->rGPGUP | (0x1 << 0x0)); // Disable pull-up.
s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0xf << 0x0)) | (0x1 << 0x0); // Level-high triggered.
#endif
// Mask and clear all peripheral interrupts (these come through a second-level "GPIO" interrupt register).
//
s2440IOP->rEINTMASK = BIT_ALLMSK; // Mask all EINT interrupts.
s2440IOP->rEINTPEND = BIT_ALLMSK; // Clear pending EINT interrupts.
// Mask and clear all interrupts.
//
s2440INT->rINTMSK = BIT_ALLMSK; // Mask all interrupts (reset value).
s2440INT->rINTMSK &= ~BIT_BAT_FLT;
s2440INT->rSRCPND = BIT_ALLMSK; // Clear pending interrupts.
s2440INT->rINTPND = s2440INT->rINTPND; // S3C2440X developer notice (page 4) warns against writing a 1 to any
// 0 bit field in the INTPND register. Instead we'll write the INTPND value itself.
}
我的问题是:从OEMinit函数看,此BSP并没有实现5.0所说的关于中断的几个函数(如: OALIntrInit(),OALIntrMapInit()等)
若归为4.2BSP(疑惑1:按理也该在OEMinit函数里调用HookInterrupt函数实现ISQ与ISR(OEMInterruptHandler)关联啊,可也没有),则若要自定义一中断方法可为下:
1、在BSP的oalintr.h里定义自定义中断的逻辑中断值,如:
#define SYSINTR_MYINTR (SYSINTR_FIRMWARE + 10)
2、修改KERNEL\HAL\cfw.c中的以下三个函数
OEMInterruptEnable(), OEMInterruptDisable(), OEMInterruptDone()
3、修改KERNEL\HAL\ARM\armint.c中的OEMInterruptHandler(),对irq返回逻辑中断号
5、在IST里用InterruptInitialize()将自定义中断和Event关联起来,并WaitForSingleObject()。
疑惑2:我按上面的方法编了一按键驱动,结果是驱动正常加载,可就是在WaitForSingleObject()中等不到与自定义的逻辑中断号SYSINTR_SW9相关联的事件发生(测试过按键是好的). 而也是按此方法实现的 BSP里自带的PWR按键处理却可以正常工作.
请各位高人不吝赐教!!!
引用: 引用楼主 ystcreatcom 的帖子:
1、在BSP的oalintr.h里定义自定义中断的逻辑中断值,如:
#define SYSINTR_MYINTR (SYSINTR_FIRMWARE + 10)
2、修改KERNEL\HAL\cfw.c中的以下三个函数
OEMInterruptEnable(), OEMInterruptDisable(), OEMInterruptDone()
3、修改KERNEL\HAL\ARM\armint.c中的OEMInterruptHandler(),对irq返回逻辑中断号
5、在IST里用InterruptInitialize()将自定义中断和Event关联起来,并WaitForSingleObject()。
疑惑2:我按上面的方法编了一按键驱动,结果是驱动正常加载,可就是在WaitForSingleObject()中等不到与自定义的逻辑中断号SYSINTR_SW9相关联的事件发生(测试过按键是好的). 而也是按此方法实现的 BSP里自带的PWR按键处理却可以正常工作.
你的 是4.2BSP啊,5.0BSP不是这样的。
关于4.2BSP的中断,网上很多文章,算是比较好办的。
如果不能产生中断,那么用一些应用程序读出相关的寄存器看看,是否设置正确。
good luck!
从代码看像优龙提供的4.2BSP。
5.0的看看我的博客。
4.2的网上很多介绍。
5.0的中断处理可以用2种方法,4.2的那种也可以用,不过不推荐。
是4.2的BSP.现在问题是:我按大家说的添加自定义中断的方法怎么就不行呢?是哪里出问题了?
步骤如下:
1.在BSP的oalintr.h里定义自定义中断的逻辑中断值,如:
#define SYSINTR_MYINTR (SYSINTR_FIRMWARE + 10)
2、修改KERNEL\HAL\cfw.c中的以下三个函数
OEMInterruptEnable(), OEMInterruptDisable(), OEMInterruptDone()
3、修改KERNEL\HAL\ARM\armint.c中的OEMInterruptHandler(),对irq返回逻辑中断号
5、在IST里用InterruptInitialize()将自定义中断和Event关联起来,并WaitForSingleObject()。
按照你的步骤已经没有错误了。有可能是你初始化有些问题(把IO配置成中断模式,中断以何种方式触发等)。或者是你在上面的几个OEM函数配置不正确。甚至这个中断被别的驱动占用了,这个一般在用别人的BSP的时候要尤其小心。
我不是叫你写个应用程序读寄存器的值,看看是否正确吗?
sunrain_hjb牛人写了不少wince开发工具的。
http://blog.eeworld.net/gooogleman/archive/2009/02/05/3864269.aspx
http://blog.eeworld.net/gooogleman/archive/2009/03/02/3948503.aspx
按照你的步骤已经没有错误了。有可能是你初始化有些问题(把IO配置成中断模式,中断以何种方式触发等)。或者是你在上面的几个OEM函数配置不正确。甚至这个中断被别的驱动占用了,这个一般在用别人的BSP的时候要尤其小心。
我不是叫你写个应用程序读寄存器的值,看看是否正确吗?
sunrain_hjb牛人写了不少wince开发工具的。
http://blog.eeworld.net/gooogleman/archive/2009/02/05/3864269.aspx
http://blog.eeworld.net/gooogleman/archive/2009/03/02/3948503.aspx
你看看你驱动中间是不是alloc了IO空间就直接free了