转载——wince源码分析中断之map.c

    1. //------------------------------------------------------------------------------
    2. //
    3. //  Function:   OALIntrStaticTranslate
    4. //
    5. //  This function sets static translation between IRQ and SYSINTR. In most
    6. //  cases it should not be used. Only exception is mapping for 
    7. //  SYSINTR_RTC_ALARM and obsolete device drivers.
    8. //
    9. VOID OALIntrStaticTranslate(UINT32 sysIntr, UINT32 irq)
    10. {
    11.     OALMSG(OAL_FUNC&&OAL_INTR, (
    12.         L"+OALIntrStaticTranslate(%d, %d)/r/n", sysIntr, irq
    13.     ));
    14.     if (irq < OAL_INTR_IRQ_MAXIMUM && sysIntr < SYSINTR_MAXIMUM) {
    15.         g_oalSysIntr2Irq[sysIntr] = irq;
    16.         g_oalIrq2SysIntr[irq] = sysIntr;
    17.     }        
    18.     OALMSG(OAL_FUNC&&OAL_INTR, (L"-OALIntrStaticTranslate/r/n"));
    19. }
    //------------------------------------------------------------------------------
  1. //
  2. //  Function:  OALIntrMapInit
  3. //
  4. //  This function must be called from OALInterruptInit to initialize mapping
  5. //  between IRQ and SYSINTR. It simply initialize mapping arrays.
  6. //
  7. VOID OALIntrMapInit()
  8. {
  9.     UINT32 i;
  10.     
  11.     OALMSG(OAL_FUNC&&OAL_INTR, (L"+OALIntrMapInit/r/n"));
  12.     // Initialize interrupt maps
  13.     for (i = 0; i < SYSINTR_MAXIMUM; i++) {
  14.         g_oalSysIntr2Irq[i] = OAL_INTR_IRQ_UNDEFINED;
  15.     }
  16.     for (i = 0; i < OAL_INTR_IRQ_MAXIMUM; i++) {
  17.         g_oalIrq2SysIntr[i] = SYSINTR_UNDEFINED;
  18.     }
  19.     OALMSG(OAL_FUNC&&OAL_INTR, (L"-OALIntrMapInit/r/n"));
  20. }
wince学习手记

  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. //
  8. BOOL OALIntrTranslateSysIntr(
  9.     UINT32 sysIntr, UINT32 *pCount, const UINT32 **ppIrqs
  10. ) {
  11.     BOOL rc;
  12.     OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+OALTranslateSysIntr(%d)/r/n", sysIntr));
  13.     
  14.     // Valid SYSINTR?
  15.     if (sysIntr >= SYSINTR_MAXIMUM) {
  16.         rc = FALSE;
  17.         goto cleanUp;
  18.     }
  19.     *pCount = 1;
  20.     *ppIrqs = &g_oalSysIntr2Irq[sysIntr];
  21.     rc = TRUE;
  22. cleanUp:
  23.     OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OALTranslateSysIntr(rc = %d)/r/n", rc));
  24.     return rc;
  25. }

 

 

  1. //------------------------------------------------------------------------------
  2. //
  3. //  Function:  OALIntrTranslateIrq
  4. //
  5. //  This function maps a IRQ to its corresponding SYSINTR.
  6. //
  7. UINT32 OALIntrTranslateIrq(UINT32 irq)
  8. {
  9.     UINT32 sysIntr = SYSINTR_UNDEFINED;
  10.     
  11.     OALMSG(OAL_FUNC&&OAL_VERBOSE, (L"+OALIntrTranslateIrq(%d)/r/n", irq));
  12.     if (irq >= OAL_INTR_IRQ_MAXIMUM) goto cleanUp;
  13.     sysIntr = g_oalIrq2SysIntr[irq];
  14. cleanUp:
  15.     OALMSG(OAL_FUNC&&OAL_VERBOSE, (
  16.         L"-OEMTranslateIrq(sysIntr = %d)/r/n", sysIntr
  17.     ));
  18.     return sysIntr;
  19. }
  20. //------------------------------------------------------------------------------
  21. //
  22. //  Function:  OALIntrRequestSysIntr
  23. //
  24. //  This function allocate new SYSINTR for given IRQ and it there isn't
  25. //  static mapping for this IRQ it will create it.
  26. //
  27. UINT32 OALIntrRequestSysIntr(UINT32 count, const UINT32 *pIrqs, UINT32 flags)
  28. {
  29.     UINT32 irq, sysIntr;
  30.     OALMSG(OAL_INTR&&OAL_FUNC, (
  31.         L"+OALIntrRequestSysIntr(%d, 0x%08x, 0x%08x)/r/n", count, pIrqs, flags
  32.     ));
  33.     
  34.     // Valid IRQ?
  35.     if (count != 1 || pIrqs[0] >= OAL_INTR_IRQ_MAXIMUM) {
  36.         sysIntr = SYSINTR_UNDEFINED;            
  37.         goto cleanUp;
  38.     }
  39.     irq = pIrqs[0];
  40.     // If there is mapping for given irq check for special cases
  41.     if (g_oalIrq2SysIntr[irq] != SYSINTR_UNDEFINED) {
  42.         // If static mapping is requested we fail
  43.         if ((flags & OAL_INTR_STATIC) != 0) {
  44.             OALMSG(OAL_ERROR, (L"ERROR: OALIntrRequestSysIntr: "
  45.                L"Static mapping for IRQ %d already assigned/r/n", irq
  46.             ));
  47.             sysIntr = SYSINTR_UNDEFINED;            
  48.             goto cleanUp;
  49.         }
  50.         // If we should translate, return existing SYSINTR
  51.         if ((flags & OAL_INTR_TRANSLATE) != 0) {
  52.             sysIntr = g_oalIrq2SysIntr[irq];
  53.             goto cleanUp;
  54.         }
  55.     }
  56.     // Find next available SYSINTR value...
  57.     for (sysIntr = SYSINTR_FIRMWARE; sysIntr < SYSINTR_MAXIMUM; sysIntr++) {
  58.         if (g_oalSysIntr2Irq[sysIntr] == OAL_INTR_IRQ_UNDEFINED) break;
  59.     }
  60.     
  61.     // Any available SYSINTRs left?
  62.     if (sysIntr >= SYSINTR_MAXIMUM) {
  63.         OALMSG(OAL_ERROR, (L"ERROR: OALIntrRequestSysIntr: "
  64.             L"No avaiable SYSINTR found/r/n"
  65.         ));            
  66.         sysIntr = SYSINTR_UNDEFINED;
  67.         goto cleanUp;
  68.     }
  69.     
  70.     // Make SYSINTR -> IRQ association.
  71.     g_oalSysIntr2Irq[sysIntr] = irq;
  72.     
  73.     // Make IRQ -> SYSINTR association if required
  74.     if ((flags & OAL_INTR_DYNAMIC) != 0) goto cleanUp;
  75.     if (
  76.         g_oalIrq2SysIntr[irq] == SYSINTR_UNDEFINED ||
  77.         (flags & OAL_INTR_FORCE_STATIC) != 0
  78.     ) {
  79.         g_oalIrq2SysIntr[irq] = sysIntr;
  80.     }
  81. cleanUp:
  82.     OALMSG(OAL_INTR&&OAL_FUNC, (
  83.         L"-OALIntrRequestSysIntr(sysIntr = %d)/r/n", sysIntr
  84.     ));
  85.     return sysIntr;
  86. }
  87. //------------------------------------------------------------------------------
  88. //
  89. //  Function:  OALIntrReleaseSysIntr
  90. //
  91. //  This function release given SYSINTR and remove static mapping if exists.
  92. //
  93. BOOL OALIntrReleaseSysIntr(UINT32 sysIntr)
  94. {
  95.     BOOL rc = FALSE;
  96.     UINT32 irq;
  97.     OALMSG(OAL_INTR&&OAL_FUNC, (L"+OALIntrReleaseSysIntr(%d)/r/n", sysIntr));
  98.     // Is the SYSINTR already released?
  99.     if (g_oalSysIntr2Irq[sysIntr] == OAL_INTR_IRQ_UNDEFINED) goto cleanUp;
  100.     // Remove the SYSINTR -> IRQ mapping
  101.     irq = g_oalSysIntr2Irq[sysIntr];
  102.     g_oalSysIntr2Irq[sysIntr] = OAL_INTR_IRQ_UNDEFINED;
  103.     // If we're releasing the SYSINTR directly mapped in the IRQ mapping, 
  104.     // remove the IRQ mapping also
  105.     if (g_oalIrq2SysIntr[irq] == sysIntr) {
  106.         g_oalIrq2SysIntr[irq] = SYSINTR_UNDEFINED;
  107.     }
  108. cleanUp:
  109.     OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALIntrReleaseSysIntr(rc = %d)/r/n", rc));
  110.     return rc;
  111. }
  112. //------------------------------------------------------------------------------
OAL是位于WindowsCE内核与目标设备硬件之间的一个代码层,用于实现windowCE与目标设备硬件之间的通信。为了实现内核与硬件之间最基本的通信功能,OEM必须实现一些必要的功能,同时为了适合不同的硬件配置与操作系统功能,OEM有必要的选择实现一些其他的功能。
在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)使用值来进行映射,目前我认为应该是一对一的关系来映射的。
感想:
微软的程序写的很缜密,设计的很合理,能让我学到不少编程的方法。映射关系的编程可以参考微软的中断映射表。
 
  1. //------------------------------------------------------------------------------
  2. static UINT32 g_oalSysIntr2Irq[SYSINTR_MAXIMUM];
  3. static UINT32 g_oalIrq2SysIntr[OAL_INTR_IRQ_MAXIMUM];
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值