File: oem.c 1// 2// Copyright (c) Microsoft Corporation. All rights reserved. 3// 4// 5// Use of this source code is subject to the terms of the Microsoft end-user 6// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT. 7// If you did not accept the terms of the EULA, you are not authorized to use 8// this source code. For a copy of the EULA, please see the LICENSE.RTF on your 9// install media. 10// 11//------------------------------------------------------------------------------ 12// 13// File: oem.c 14// 15// This file implements a standard implementation of OEMInterrupt functions 16// relating to enabling, disabling and finishing interrupts. 17// 18#include <windows.h> 19#include <nkintr.h> 20#include <oal.h> 21 22 23//------------------------------------------------------------------------------ 24// 25// Function: OEMInterruptEnable 26// 27// This function enables the IRQ given its corresponding SysIntr value. 28// Function returns true if SysIntr is valid, else false. 29// 30BOOL OEMInterruptEnable(DWORD sysIntr, LPVOID pvData, DWORD cbData) 31{ 32 BOOL rc = FALSE; 33const UINT32 *pIrqs; 34 UINT32 count; 35 36 OALMSG(OAL_INTR&&OAL_VERBOSE, 37 (L"+OEMInterruptEnable(%d, 0x%x, %d)\r\n", sysIntr, pvData, cbData 38 )); 39 40// SYSINTR_VMINI & SYSINTR_TIMING are special cases 41if (sysIntr == SYSINTR_VMINI || sysIntr == SYSINTR_TIMING) { 42 rc = TRUE; 43goto cleanUp; 44 } 45 46// Obtain the SYSINTR's underlying IRQ number 47if (!OALIntrTranslateSysIntr(sysIntr, &count, &pIrqs)) { 48// Indicate invalid SysIntr 49 OALMSG(OAL_ERROR, ( 50 L"ERROR: OEMInterruptEnable: IRQs are undefined for SysIntr %d\r\n", 51 sysIntr 52 )); 53goto cleanUp; 54 } 55 56// Enable the interrupt 57 rc = OALIntrEnableIrqs(count, pIrqs); 58 59cleanUp: 60 OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OEMInterruptEnable(rc = 1)\r\n")); 61return rc; 62} 63 64 65//------------------------------------------------------------------------------ 66// 67// Function: OEMInterruptDisable(DWORD sysIntr) 68// 69// This function disables the IRQ given its corresponding SysIntr value. 70// 71// 72VOID OEMInterruptDisable(DWORD sysIntr) 73{ 74const UINT32 *pIrqs; 75 UINT32 count; 76 77 OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+OEMInterruptDisable(%d)\r\n", sysIntr)); 78 79// Obtain the SYSINTR's underlying IRQ number 80if (!OALIntrTranslateSysIntr(sysIntr, &count, &pIrqs)) { 81// Indicate invalid SysIntr 82 OALMSG(OAL_ERROR, ( 83 L"ERROR: OEMInterruptEnable: IRQs are undefined for SysIntr %d\r\n", 84 sysIntr 85 )); 86goto cleanUp; 87 } 88 89// Disable the interrupt 90 OALIntrDisableIrqs(count, pIrqs); 91 92cleanUp: 93// Indicate exit 94 OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OEMInterruptDisable\r\n")); 95} 96 97 98//------------------------------------------------------------------------------ 99// 100// Function: OEMInterruptDone 101// 102// OEMInterruptDone is called by the kernel when a device driver 103// calls InterruptDone(). The system is not preemtible when this 104// function is called. 105// 106VOID OEMInterruptDone(DWORD sysIntr) 107{ 108const UINT32 *pIrqs; 109 UINT32 count; 110 111 OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+OEMInterruptDone(%d)\r\n", sysIntr)); 112if (OALIntrTranslateSysIntr(sysIntr, &count, &pIrqs)) { 113 OALIntrDoneIrqs(count, pIrqs); 114 } 115 OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OEMInterruptDone\r\n")); 116} 117 118//------------------------------------------------------------------------------ 119
看OALIntrTranslateSysIntr,
OALIntrTranslateSysIntr 1//------------------------------------------------------------------------------ 2// 3// Function: OALIntrTranslateSysIntr 4// 5// This function maps a SYSINTR to its corresponding IRQ. It is typically used 6// in OEMInterruptXXX to obtain IRQs for given SYSINTR. 7// 8BOOL OALIntrTranslateSysIntr( 9 UINT32 sysIntr, UINT32 *pCount, const UINT32 **ppIrqs 10) { 11 BOOL rc; 12 13 OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+OALTranslateSysIntr(%d)\r\n", sysIntr)); 14 15// Valid SYSINTR? 16if (sysIntr >= SYSINTR_MAXIMUM) { 17 rc = FALSE; 18goto cleanUp; 19 } 20*pCount =1; 21*ppIrqs =&g_oalSysIntr2Irq[sysIntr]; 22 rc = TRUE; 23 24cleanUp: 25 OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OALTranslateSysIntr(rc = %d)\r\n", rc)); 26return rc; 27} 28
This function initializes a hardware interrupt with the kernel. This initialization allows the device driver to register an event and enable the interrupt.
[in] Interrupt identifier to be associated with this interrupt service thread (IST).
hEvent
[in] Event to be signaled when the interrupt is triggered.
pvData
[in] This parameter can be used as a pointer to a block of data that is passed to
. The block of data can be initialization data, scratch space, and so on.
cbData
[in] Size of data pointed to by
pvData.
Return Values
TRUE indicates success; FALSE indicates failure.
Remarks
This function must be called before using the hEvent parameter, which provides a link between the idInt parameter and the SYSINTR value returned by an ISR.
The hEvent parameter can only be used in a WaitForSingleObject call to wait for the event to be triggered by the kernel.
A WaitForMultipleObjects call with hEvent will fail.
If you use hEvent in a call to WaitForSingleObject before you call InterruptInitialize, InterruptInitialize will fail.
Requirements
OS Versions: Windows CE 2.10 and later. Header: Pkfuncs.h. Link Library: Coredll.lib.——郁闷,不开源的。
从PB帮助可以知道,这个
This function initializes a hardware interrupt with the kernel. This initialization allows the device driver to register an event and enable the interrupt.
[in] Interrupt identifier to be associated with this interrupt service thread (IST).
hEvent
[in] Event to be signaled when the interrupt is triggered.
pvData
[in] This parameter can be used as a pointer to a block of data that is passed to
. The block of data can be initialization data, scratch space, and so on.
cbData
[in] Size of data pointed to by
pvData.
Return Values
TRUE indicates success; FALSE indicates failure.
Remarks
This function must be called before using the hEvent parameter, which provides a link between the idInt parameter and the SYSINTR value returned by an ISR.
The hEvent parameter can only be used in a WaitForSingleObject call to wait for the event to be triggered by the kernel.
A WaitForMultipleObjects call with hEvent will fail.
If you use hEvent in a call to WaitForSingleObject before you call InterruptInitialize, InterruptInitialize will fail.
Requirements
OS Versions: Windows CE 2.10 and later. Header: Pkfuncs.h. Link Library: Coredll.lib.——郁闷,不开源的。
[in] I/O control code, which should support the OAL I/O controls. For a list of these I/O controls, see
.
lpInBuf
[out] Pointer to a buffer that contains the data required to perform the operation.
Set to NULL if the dwIoControlCode parameter specifies an operation that does not require input data.
nInBufSize
[in] Size, in bytes, of the buffer pointed to by
lpInBuf.
lpOutBuf
[out] Pointer to a buffer that receives the output data for the operation.
Set to NULL if the dwIoControlCode parameter specifies an operation that does not produce output data.
nOutBufSize
[in] Size, in bytes, of the buffer pointed to by
lpOutBuf.
lpBytesReturned
[in] Long pointer to a variable that receives the size, in bytes, of the data stored in the buffer pointed to by
lpOutBuf. Even when an operation produces no output data, and
lpOutBuf is NULL, the
KernelIoControl function uses the variable pointed to by
lpBytesReturned. After such an operation, the value of the variable has no meaning.
Return Values
TRUE indicates success; FALSE indicates failure.
Remarks
The kernel calls the
function when a device driver or application calls the kernel function KernelIoControl and passes an I/O control code. ——这个很关键,关于
函数我在CSDN博客有介绍。这是实现中断转换的关键函数
This function is also called when the
function is called with SPI_GETOEMINFO or SPI_GETPLATFORMINFO.
The system is fully preemptible when this function is called. The kernel does no processing, but it passes all parameters directly to the function supplied by you.
This function is provided solely to allow your device driver or application to communicate with an OAL and its specific functionality.