Here is another really informative article by the Windows CE Base team.:)http://blogs.msdn.com/ce_base/archive/2007/11/26/How-does-Windows-Embedded-CE-6.0-start_3F00_.aspx

"Exceptions are generated by internal and external sources to cause the processor to handle an event, such as an externally generated interrupt or an attempt to execute an Undefined instruction."- I took it from the arm reference manual, couldn't put it in any better way myself:)
- Reset
- Undefined Instruction
- Software Interrupt
- Prefetch Abort
- Data Abort
- IRQ
- FIQ
Labels: interrupt, kernel, wince 0 comments
In my previous post, I have explained how to add an interrupt when source code is available.
Now I will explain how to handle an interrupt by writing an IST in the driver. For the reason of continuity, I am using the same power button driver and the Wireless Activity Interrupt (as I explain with in post "Adding Interrupt in OAL").
1. Create an even to be associated with the interrupt HANDLE g_WlanActiveEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if( !g_WlanActiveEvent)
{
RETAILMSG(1, (TEXT("WlanActivityMonitorStart: Failed to create Intterupt Event\r\n")));
goto CleanUp;
}
2. Associate the Interrupt with the event using SYSINTR valueUINT32 g_SysIntr = SYSINTR_WLAN;
......
result = InterruptInitialize(g_SysIntr, g_WlanActiveEvent, NULL, 0);
if(!result)
{
RETAILMSG(1, (TEXT("WlanActivityMonitorStart: InterruptInitialize() failed. GetLastError=0x%x\r
\n"),GetLastError()));
goto CleanUp;
}
3. Start a thread for handling the interrupt.g_WlanThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) WlanThread, NULL, 0, NULL);
if ( g_WlanThread == NULL )
{
RETAILMSG(1, (TEXT("WlanActivityMonitorStart: Failed to create WlanActive
Intterupt Thread\r\n")));
goto CleanUp;
}
4. In the thread, wait for the event to happen using the WaitForSingleObject or WaitForMultipleObjects API.INT WlanThread (VOID)
{
while(!g_FlagExitThrd)
{
WaitForSingleObject(g_WlanActiveEvent, INFINITE);
.............
}
return ERROR_SUCCESS;
}
5. Perform the necessary operations to service that interrupt. Here I am pulsing another event to notify some other sets of appication.
WaitForSingleObject(g_WlanActiveEvent, INFINITE);6. Signal the completion of interrupt handling using InterruptDone
InterruptMask(g_SysIntr,TRUE);
if (g_WlanEvent)
{
RETAILMSG(1, (TEXT("WlanThread: Intterupt \r\n")));
PulseEvent(g_WlanEvent);
}
Sleep (1000); // Sleep to ignore some activity as this line toggles a lot
InterruptMask(g_SysIntr,FALSE);
InterruptDone(g_SysIntr);
Labels: drivers, interrupt, wince 3 comments
When we are having the whole BSP source, there will be cases in which we may need to add interrupt in OAL. This can be accommodate a new driver or add a new functionality to the existing one.
For explaining the procedure I am using the Mainstone BSP that is available in windows ce. Lets assume that we want to add an interrupt for Wireless LAN activity. This interrupt line will be a GPIO line which is mapped to GPIO 91 of PXA.
These are the files that need modification:
* bsp_cfg.h (Src\Inc)
* intr.c (OAL)
In 'bsp_cfg.h', you need to define a SYSINTR (if needed) for the new interrupt that you are about to add.
.............
#define SYSINTR_PWRBTN (SYSINTR_FIRMWARE+14) // 30
#define SYSINTR_WLANACTIVE (SYSINTR_FIRMWARE+15) // 31 - The new interrupt
................
Now in OAL, intr.c, make the following changes:
1. In BSPIntrInit() function, add a call to OALIntrStaticTranslate() to map the
the new SYSINTR v alue to the GPIO.
...............
OALIntrStaticTranslate (SYSINTR_WLAN,IRQ_GPIOXX_2_GPIO91);
...............
2. In BSPIntrEnableIrq(), add the case of enabling the GPIO Interrupt
.................
else if (irq == IRQ_GPIOXX_2_GPIO91)
{
EnableGPIO91Irq(); // define this function for enabling falling or rising
//edge detect and clear edge detect
}
.................
3. In BSPIntrDisableIrq(), add the case of enabling the GPIO Interrupt
.................
else if (irq == IRQ_GPIOXX_2_GPIO91)
{
DisableGPIO91Irq(); // define this function for clearing falling rising
//edge detect so that interrupt wont come
}
.................
4. Define the functions for enabling and disabling the gpio interrupt
............
//~~ Function for disabling gpio91 interrupt
static void EnableGPIO91Irq(void)
{
SETREG32((PULONG)&g_pGPIORegs->GRER2, XLLP_BIT_27);
}
//~~ Function for enabling gpio91 interrupt
static void DisableGPIO91Irq(void)
{
CLRREG32((PULONG)&g_pGPIORegs->GEDR2, XLLP_BIT_27);
CLRREG32((PULONG)&g_pGPIORegs->GRER2, XLLP_BIT_27);
}
This is how we add a new interrupt in OAL.
My friend mukesh has written in his blog, how to dynamically add an interrupt handler, when OAL source code is not available.
In the next posts, I will explain how to add an IST (Interrupt Service Thread) to take care of this interrupt.
Labels: interrupt, oal, wince 0 comments