wince 中断

摘自:http://blog.chinaunix.net/u2/83682/
请问这两个函数KernelIoControl和InterruptInitialize函数的区别是什么呢??
个人理解:先用KernelIoControl申请中断号
          然后利用InterruptInitialize把 (从KernelIoControl申请的)中断号与事件相关联
          主要作用是使能waitForSingleObject中挂起的事件
KernelIoControl这个函数有很多人都说不能申请成功
那么是否还有另外一种所谓的静态申请中断号的方法
在oalintr.h中添加中断的宏定义
然后…


1 2个函数没有任何关系;KernelIoControl是驱动/应用程序和kernel通讯的一个接口函数,具体的调用意义是看该函数的IOCTRL是什么以及kernel中对应的处理函数(ioctrl table);
2 关于中断,WINCE 5之前都是静态中断,从CE 5开始中断申请分为动态申请和静态分配2种;楼主用的KernelIoControl+IOCTL_HAL_REQUEST_SYSINTR就是动态申请的方法;静态分配其实很简单,在OEMInterruptHandler里直接switch case即可;具体实现很多,各家BSP不一样,但是道理都是如此;
其实,动态申请就是由系统维护一个table,使得OEM允许其他厂商的驱动以安装的形式动态加到这个table里。作为OEM自己,其实维护一个静态的中断分配就可以了,驱动完全不用动态申请。只不过很多参考BSP用了这个形式,导致大家都在动态申请。

后来有人提示,我们来分析如下代码

  1. // read registry settings
  2.     // read the SDIO SYSINTR value
  3.     m_dwSDIOIrq = regDevice.ValueDW( SDIO_IRQ_TEXT, 0xffffffff );
  4.     if( m_dwSDIOIrq == 0xffffffff )
  5.     {
  6.         // invalid SDIO IRQ value!
  7.         DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("invalid SDIO IRQ value!\r\n")));
  8.         fRetVal = FALSE;
  9.         goto FUNCTION_EXIT;
  10.     }
  11.     // convert the SDI hardware IRQ into a logical SYSINTR value
  12.     if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &m_dwSDIOIrq, sizeof(DWORD), &m_dwSDIOSysIntr, sizeof(DWORD), NULL))
  13.     {
  14.         // invalid SDIO SYSINTR value!
  15.         DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("invalid SDIO SYSINTR value!\r\n")));
  16.         m_dwSDIOSysIntr = SYSINTR_UNDEFINED;
  17.         fRetVal = FALSE;
  18.         goto FUNCTION_EXIT;
  19.     } 

m_dwSDIOSysIntr 这个变量是在哪里定义的呢?;不过根据m_dwSDIOSysIntr = SYSINTR_UNDEFINED;
这个可以看出,这个明显和中断相关了。因为刚开始初始化中断都是m_SYSINTR_UNDEFINED的;

后来找到m_dwSDIOSysIntr有关的SD中断线程绑定

  1.  //----- 10. Setup the IST for handling SDIO data transfer interrupts -----
  2.     m_hSDIOInterruptEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
  3.     
  4.     if(NULL == m_hSDIOInterruptEvent) 
  5.     {
  6.         status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
  7.         goto INIT_ERROR;
  8.     }
  9.     // initialize the card insertion interrupt event
  10.     if(!InterruptInitialize (m_dwSDIOSysIntr, m_hSDIOInterruptEvent,
  11.                              NULL, 0)) 
  12.     {
  13.         status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
  14.         goto INIT_ERROR;
  15.     }
  16.     m_hSDIOInterruptThread = CreateThread(NULL, 0,
  17.                                           (LPTHREAD_START_ROUTINE)SD_IOInterruptIstThread,
  18.                                           this, 0, &threadID);

后来又找到了如下函数

 

  1. //----- 2. Disable and cleanup the ISTs/events ------
  2.     InterruptDisable (m_dwSDIOSysIntr);
  3. //=====================================================
  4.  case SDHCDAckSDIOInterrupt:                                     
  5.             
  6.             DEBUGMSG (SDCARD_ZONE_INFO,(TEXT("SDHCDSlotOptionHandler option=SDHCDAckSDIOInterrupt\r\n")));
  7.             //----- 2. Clear the SDIO interrupt pending bit -----
  8.             Ack_SDIO_Interrupts();
  9.             InterruptDone(m_dwSDIOSysIntr);//--------和4.2的有什么区别?
  1. 后来我又找到了如下代码
  2. //--IRQ_EINT0是在 s3c2440a_intr.h中定义的,现在就越来越明朗了
  3. //--而IRQ_SDI为什么没有如下的赋值呢?因为SD卡中断在注册表中设置了
  4. //#define IRQ_SDI  21--在注册表也设置为21,这个原理和IRQ_EINT0等价了
  5. UINT32 g_PwrButtonIrq = IRQ_EINT0;
  6. UINT32 g_PwrButtonSysIntr = SYSINTR_UNDEFINED;
  7. UINT32 g_RebootButtonIrq = IRQ_EINT2;
  8. UINT32 g_RebootButtonSysIntr = SYSINTR_UNDEFINED;

 

到现在已经可以对5.0的BSP方法做个推断了:5.0BSP的所谓动态中断设置方法,就是在驱动中才初始化中断(在4.2下是静态中断,在OAL中初始化的)和注册表等结合起来。使用kernelIoControl这个函数来转换物理中断和逻辑中断(至于为什么要做个转换,我真的有点不了解,有点浪费时间,也许我等级太低了。)

 

但是在OAL又必须初始化什么呢?以前看了好多,一直带着4.2的影子去看程序——哎,老毛病。

现在再来看看OAL的OEMInit函数以及被他调用的函数。

//------------------------------------------------------------------------------ // //  Function:  OEMInit // //  This is Windows CE OAL initialization function. It is called from kernel //  after basic initialization is made. // void OEMInit(){    OALMSG(OAL_FUNC, (L"+OEMInit\r\n"));    CEProcessorType=PROCESSOR_STRONGARM;    // Set memory size for DrWatson kernel support     dwNKDrWatsonSize = 128 * 1024;    // Initilize cache globals     OALCacheGlobalsInit();    OALLogSerial(        L"DCache: %d sets, %d ways, %d line size, %d size\r\n",         g_oalCacheInfo.L1DSetsPerWay, g_oalCacheInfo.L1DNumWays,        g_oalCacheInfo.L1DLineSize, g_oalCacheInfo.L1DSize    );    OALLogSerial(        L"ICache: %d sets, %d ways, %d line size, %d size\r\n",         g_oalCacheInfo.L1ISetsPerWay, g_oalCacheInfo.L1INumWays,        g_oalCacheInfo.L1ILineSize, g_oalCacheInfo.L1ISize    );        // Initialize interrupts     if (!OALIntrInit()) {        OALMSG(OAL_ERROR, (            L"ERROR: OEMInit: failed to initialize interrupts\r\n"        ));    }    // Initialize system clock     OALTimerInit(1, 17, 0); //S3C2440A_PCLK/245/16/1000=16.992

转载于:https://www.cnblogs.com/Torres_fans/archive/2009/10/11/1580759.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值