Книга: Microsoft Windows Embedded CE 6.0 Exam Preparation Kit

Dynamic Interrupt Mappings

Dynamic Interrupt Mappings

The good news is that you do not need to hardcode SYSINTR values into the OAL if you call KernelIoControl in your device drivers with an IO control code of IOCTL_HAL_REQUEST_SYSINTR to register IRQ/SYSINTR mappings. The call eventually ends in the OALIntrRequestSysIntr function, which dynamically allocates a new SYSINTR for the given IRQ, and then registers the IRQ and SYSINTR mappings in the kernel's interrupt mapping arrays. Locating a free SYSINTR value up to SYSINTR_MAXUMUM is more flexible than static SYSINTR assignments because this mechanism does not require any modifications to the OAL when you add new drivers to the BSP.

When calling KernelIoControl with IOCTL_HAL_REQUEST_SYSINTR, you establish a 1:1 relationship between IRQ and SYSINTR. If the IRQ-SYSINTR mapping table already has an entry for the specified IRQ, OALIntrRequestSysIntr will not create a second entry. To remove an entry from the interrupt mapping tables, such as when unloading a driver, call KernelIoControl with an IO control code of IOCTL_HAL_REQUEST_SYSINTR. IOCTL_HAL_RELEASE_SYSINTR dissociates the IRQ from the SYSINTR value.

The following code sample illustrates the use of IOCTL_HAL_REQUEST_SYSINTR and IOCTL_HAL_RELEASE_SYSINTR. It takes a custom value (dwLogintr) and passes this value to the OAL to be translated into a SYSINTR value, and then associates this SYSINTR with an IST event.

DWORD dwLogintr = IRQ_VALUE;
DWORD dwSysintr = 0;
HANDLE hEvent = NULL;
BOOL bResult = TRUE;
// Create event to associate with the interrupt
m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (m_hDetectionEvent == NULL) {
 return ERROR_VALUE;
}
// Ask the kernel (OAL) to associate an SYSINTR value to an IRQ
bResult = KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,
 &dwLogintr, sizeof(dwLogintr),
 &dwSysintr, sizeof(dwSysintr), 0);
if (bResult == FALSE) {
 return ERROR_VALUE;
}
// Initialize interrupt and associate the SYSINTR value with the event.
bResult = InterruptInitialize(dwSysintr, hEvent,0,0);
if (bResult == FALSE) {
 return ERROR_VALUE;
}
// Interrupt management loop
while(!m_bTerminateDetectionThread) {
 // Wait for the event associated to the interrupt
 WaitForSingleObject(hEvent,INFINITE);
 // Add actual IST processing here
 // Acknowledge the interrupt
 InterruptDone(m_dwSysintr);
}
// Deinitialize interrupts will mask the interrupt
bResult = InterruptDisable(dwSysintr);
// Unregister SYSINTR
bResult = KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,
 &dwSysintr, sizeof(dwSysintr), NULL, 0, 0);
// Close the event object
CloseHandle(hEvent);

Оглавление книги


Генерация: 1.076. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз