-
- //------------------------------------------------------------------------------
- //
- // Function: OALIntrStaticTranslate
- //
- // This function sets static translation between IRQ and SYSINTR. In most
- // cases it should not be used. Only exception is mapping for
- // SYSINTR_RTC_ALARM and obsolete device drivers.
- //
- VOID OALIntrStaticTranslate(UINT32 sysIntr, UINT32 irq)
- {
- OALMSG(OAL_FUNC&&OAL_INTR, (
- L"+OALIntrStaticTranslate(%d, %d)/r/n", sysIntr, irq
- ));
- if (irq < OAL_INTR_IRQ_MAXIMUM && sysIntr < SYSINTR_MAXIMUM) {
- g_oalSysIntr2Irq[sysIntr] = irq;
- g_oalIrq2SysIntr[irq] = sysIntr;
- }
- OALMSG(OAL_FUNC&&OAL_INTR, (L"-OALIntrStaticTranslate/r/n"));
- }
- //
- // Function: OALIntrMapInit
- //
- // This function must be called from OALInterruptInit to initialize mapping
- // between IRQ and SYSINTR. It simply initialize mapping arrays.
- //
- VOID OALIntrMapInit()
- {
- UINT32 i;
- OALMSG(OAL_FUNC&&OAL_INTR, (L"+OALIntrMapInit/r/n"));
- // Initialize interrupt maps
- for (i = 0; i < SYSINTR_MAXIMUM; i++) {
- g_oalSysIntr2Irq[i] = OAL_INTR_IRQ_UNDEFINED;
- }
- for (i = 0; i < OAL_INTR_IRQ_MAXIMUM; i++) {
- g_oalIrq2SysIntr[i] = SYSINTR_UNDEFINED;
- }
- OALMSG(OAL_FUNC&&OAL_INTR, (L"-OALIntrMapInit/r/n"));
- }
wince学习手记
- //------------------------------------------------------------------------------
- //
- // Function: OALIntrTranslateSysIntr
- //
- // This function maps a SYSINTR to its corresponding IRQ. It is typically used
- // in OEMInterruptXXX to obtain IRQs for given SYSINTR.
- //
- BOOL OALIntrTranslateSysIntr(
- UINT32 sysIntr, UINT32 *pCount, const UINT32 **ppIrqs
- ) {
- BOOL rc;
- OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+OALTranslateSysIntr(%d)/r/n", sysIntr));
- // Valid SYSINTR?
- if (sysIntr >= SYSINTR_MAXIMUM) {
- rc = FALSE;
- goto cleanUp;
- }
- *pCount = 1;
- *ppIrqs = &g_oalSysIntr2Irq[sysIntr];
- rc = TRUE;
- cleanUp:
- OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OALTranslateSysIntr(rc = %d)/r/n", rc));
- return rc;
- }
- //------------------------------------------------------------------------------
- //
- // Function: OALIntrTranslateIrq
- //
- // This function maps a IRQ to its corresponding SYSINTR.
- //
- UINT32 OALIntrTranslateIrq(UINT32 irq)
- {
- UINT32 sysIntr = SYSINTR_UNDEFINED;
- OALMSG(OAL_FUNC&&OAL_VERBOSE, (L"+OALIntrTranslateIrq(%d)/r/n", irq));
- if (irq >= OAL_INTR_IRQ_MAXIMUM) goto cleanUp;
- sysIntr = g_oalIrq2SysIntr[irq];
- cleanUp:
- OALMSG(OAL_FUNC&&OAL_VERBOSE, (
- L"-OEMTranslateIrq(sysIntr = %d)/r/n", sysIntr
- ));
- return sysIntr;
- }
- //------------------------------------------------------------------------------
- //
- // Function: OALIntrRequestSysIntr
- //
- // This function allocate new SYSINTR for given IRQ and it there isn't
- // static mapping for this IRQ it will create it.
- //
- UINT32 OALIntrRequestSysIntr(UINT32 count, const UINT32 *pIrqs, UINT32 flags)
- {
- UINT32 irq, sysIntr;
- OALMSG(OAL_INTR&&OAL_FUNC, (
- L"+OALIntrRequestSysIntr(%d, 0x%08x, 0x%08x)/r/n", count, pIrqs, flags
- ));
- // Valid IRQ?
- if (count != 1 || pIrqs[0] >= OAL_INTR_IRQ_MAXIMUM) {
- sysIntr = SYSINTR_UNDEFINED;
- goto cleanUp;
- }
- irq = pIrqs[0];
- // If there is mapping for given irq check for special cases
- if (g_oalIrq2SysIntr[irq] != SYSINTR_UNDEFINED) {
- // If static mapping is requested we fail
- if ((flags & OAL_INTR_STATIC) != 0) {
- OALMSG(OAL_ERROR, (L"ERROR: OALIntrRequestSysIntr: "
- L"Static mapping for IRQ %d already assigned/r/n", irq
- ));
- sysIntr = SYSINTR_UNDEFINED;
- goto cleanUp;
- }
- // If we should translate, return existing SYSINTR
- if ((flags & OAL_INTR_TRANSLATE) != 0) {
- sysIntr = g_oalIrq2SysIntr[irq];
- goto cleanUp;
- }
- }
- // Find next available SYSINTR value...
- for (sysIntr = SYSINTR_FIRMWARE; sysIntr < SYSINTR_MAXIMUM; sysIntr++) {
- if (g_oalSysIntr2Irq[sysIntr] == OAL_INTR_IRQ_UNDEFINED) break;
- }
- // Any available SYSINTRs left?
- if (sysIntr >= SYSINTR_MAXIMUM) {
- OALMSG(OAL_ERROR, (L"ERROR: OALIntrRequestSysIntr: "
- L"No avaiable SYSINTR found/r/n"
- ));
- sysIntr = SYSINTR_UNDEFINED;
- goto cleanUp;
- }
- // Make SYSINTR -> IRQ association.
- g_oalSysIntr2Irq[sysIntr] = irq;
- // Make IRQ -> SYSINTR association if required
- if ((flags & OAL_INTR_DYNAMIC) != 0) goto cleanUp;
- if (
- g_oalIrq2SysIntr[irq] == SYSINTR_UNDEFINED ||
- (flags & OAL_INTR_FORCE_STATIC) != 0
- ) {
- g_oalIrq2SysIntr[irq] = sysIntr;
- }
- cleanUp:
- OALMSG(OAL_INTR&&OAL_FUNC, (
- L"-OALIntrRequestSysIntr(sysIntr = %d)/r/n", sysIntr
- ));
- return sysIntr;
- }
- //------------------------------------------------------------------------------
- //
- // Function: OALIntrReleaseSysIntr
- //
- // This function release given SYSINTR and remove static mapping if exists.
- //
- BOOL OALIntrReleaseSysIntr(UINT32 sysIntr)
- {
- BOOL rc = FALSE;
- UINT32 irq;
- OALMSG(OAL_INTR&&OAL_FUNC, (L"+OALIntrReleaseSysIntr(%d)/r/n", sysIntr));
- // Is the SYSINTR already released?
- if (g_oalSysIntr2Irq[sysIntr] == OAL_INTR_IRQ_UNDEFINED) goto cleanUp;
- // Remove the SYSINTR -> IRQ mapping
- irq = g_oalSysIntr2Irq[sysIntr];
- g_oalSysIntr2Irq[sysIntr] = OAL_INTR_IRQ_UNDEFINED;
- // If we're releasing the SYSINTR directly mapped in the IRQ mapping,
- // remove the IRQ mapping also
- if (g_oalIrq2SysIntr[irq] == sysIntr) {
- g_oalIrq2SysIntr[irq] = SYSINTR_UNDEFINED;
- }
- cleanUp:
- OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALIntrReleaseSysIntr(rc = %d)/r/n", rc));
- return rc;
- }
- //------------------------------------------------------------------------------
在OAL开发过程中,OEM需要实现下列主要功能或函数:
.Startup函数;
.调试串口;
.OEMInit函数;
.系统计时器;
.中断处理;
.内核的输入/输出(ioctl);
.KITL。
下面给出微软公司提供的各个功能的函数。
/***************************中断处理****************************/
./platform/Common/src/common/intr/base/map.c
The file implement simple table/array based mapping between IRQ and SYSINTR
which is suitable for most OAL implementations.
这个文件主要是用来定义IRQ和SYSIRQ的映射关系。
主要函数如下:
OALIntrMapInit();//此函数由OALInterruptInit调用来初始化IRQ和SYSIRQ的映射,只是简单的映射数组的初始化;初始化为未定义类型。
VOID OALIntrStaticTranslate(UINT32 sysIntr, UINT32 irq); //此函数建立IRQ和SYSINTR的静态映射,大多数情况下都不可能用到,只有在SYSINTR_RTC_ALARM和过时的设备驱动的时候会用到。
BOOL OALIntrTranslateSysIntr(UINT32 sysIntr, UINT32 *pCount, const UINT32 **ppIrqs);//此函数将SYSINTR映射为它相应的IRQ,主要用在OEMInterruptXXX中对于给定SYSINTR得到其IRQs。
UINT32 OALIntrTranslateIrq(UINT32 irq);//此函数将IRQ映射为相应的SYSINTR。
UINT32 OALIntrRequestSysIntr(UINT32 count, const UINT32 *pIrqs, UINT32 flags);//此函数为给定的IRQ分配一个新的SYSINTR,如果此IRQ没有静态映射,就创建一个。
BOOL OALIntrReleaseSysIntr(UINT32 sysIntr);//此函数释放一个SYSINTR,并且消除存在的静态映射。
问题:
SYSINTR于IRQ的映射关系是不是一对一?BOOL OALIntrTranslateSysIntr(UINT32 sysIntr, UINT32 *pCount, const UINT32 **ppIrqs)使用的是地址来进行映射,而UINT32 OALIntrTranslateIrq(UINT32 irq)使用值来进行映射,目前我认为应该是一对一的关系来映射的。
感想:
微软的程序写的很缜密,设计的很合理,能让我学到不少编程的方法。映射关系的编程可以参考微软的中断映射表。
- //------------------------------------------------------------------------------
- static UINT32 g_oalSysIntr2Irq[SYSINTR_MAXIMUM];
- static UINT32 g_oalIrq2SysIntr[OAL_INTR_IRQ_MAXIMUM];