驱动中断流程

转载 2007年09月13日 17:08:00

    在学习驱动程序之前,我们还有很多东西要了解。想来想去,可能最重要的还是中断了,所以,这次我们花点时间来了解一下在Windows CE中的中断机制。
    凡是学过计算机原理的人都知道中断是什么东西,所以这些基本知识我们就不再详述了,我们下面就先看一下CE对中断的整体处理流程,以方便从全局上有个整体的认识。
    下图是CE中中断处理的流程图示 

     我们分布来解释上图中的流程:
    1、硬件设备向Kernel发送中断异常的代码,如果检测到这个中断异常,就会被Kernel层的异常处理所截获;
    2、中断服务调度程序会调用OAL例程中的OEMInterruptDisable函数,这个函数会通知硬件在处理完这一中断前关闭特殊的中断,但其他的中断仍然处于开放状态;
    3、中断服务例程ISR被调用以决定如何来处理这一中断;
    4、Kernel接收到ISR的返回值以得知如何处理这一中断。它的响应结果之一是忽略掉这一中断不作处理(SYSINTR_NOP),另一结果是准备执行IST。
    5、Kernel引发中断服务调度程序来唤醒中断服务线程去工作。IST是常规的Win32线程,一旦启动后,它会创建必要的EVENT然后等待该EVENT被激发。中断服务调度通过调用PulseEvent函数来激发EVENT,从而唤醒IST线程运行;
    6、当唤醒以后,IST会对中断进行必要的处理如将数据移动到缓冲区或其他有意义的事;
    7、如果需要的话,IST会借助于I/O支持例程访问硬件设备;
    8、当IST处理完成后,它会调用InterruptDone函数通知Kernel;
    9、Kernel调用OEMInterruptDone函数完成此次中断的处理过程,OAL例程通知硬件设备重新启用中断。
    以上就是中断在CE中简要的处理过程。这其中还涉及到几个函数的使用,包括:
    1、供OAL调用的ISR函数
        HookInterrupt函数在OEMInit函数中被调用以关联IRQ和ISR;
        UnhookInterrupt函数用来终止IRQ和ISR的关联。
    2、供驱动程序调用的IST函数
        InterruptInitialize函数用来将EVENT对象和逻辑中断号关联并允许中断;
        InterruptDone函数用来通知中断处理的结束;
        InterruptDisable函数被驱动程序调用以关闭中断同时取消被InterruptInitialize初始化的EVENT对象。
    下面我们再分别来看一下最重要的两部分,ISR和IST。
    ISR属于OAL层,通常是用汇编语言编写的,它可以将CPU寄存器中的数据移动到内存缓冲区中,但是它不能做更多的工作,其中一个原因就是它不能访问到用户态的存储区,它要把这些工作交给IST来完成。它做的另一项工作是进行物理中断号和逻辑中断号的映射。一个物理设备比如键盘在一种平台上可能产生4号中断,在另一种平台上可能产生15号中断,经过ISR以后,它就会把这一物理中断转换成CE中标准的SYSINTR_KEYBOARD逻辑中断。Kernel就会根据这个逻辑中断值找到对应的EVENT从而唤醒IST。
    ISR有两种,一种是单ISR模式, 即全局只有一个ISR,它适用于不支持多中断的CPU,在这种情况下,OAL会提供一个OEMInterruptHandler的命令ISR。另一种是多ISR模式,即CPU有多个硬件中断的情况,OAL通过HookInterrupt函数为每一个中断调用ISR。
    IST是驱动程序中的用户态线程,它来执行中断的处理工作。在启动后它会空闲等待EVENT的激发状态,激发后处理真正的中断处理过程,最后调用InterruptDone函数标识中断处理完成。它通常通过CeSetThreadPriority函数设置在较高的优先级状态。
    以上是对中断的简要了解,在WINCE5的驱动程序中,很大的变化就是把很多过程化的东西变成了面向对象的方式,即进行了以类为基础的封装,这样代码变得非常层次化,如果你想了解以上这些中断在具体驱动程序中的实现,建议还是先来看看CE4中的代码,似乎更明显一些。
    好了,此次的内容不多,但是较空洞,最好配合查阅驱动程序的源程序如串口的,键盘的,比如键盘的驱动中就有非常明显的IST,很容易看到它是如何设置优先级的,如果等待EVENT的,如何处理键盘消息的以及如何完成中断的,代码附后,这样才能加强理解。即使自己写驱动,也不一定完全从头编写,在以在别人的架构上修改以缩短开发周期。
BOOL
KeybdIstLoop(
PKEYBD_IST pKeybdIst
)
{
SETFNAME(_T("KeybdIstLoop")); 

UINT32 rguiScanCode[16];
BOOL rgfKeyUp[16];
UINT cEvents;

DEBUGCHK(pKeybdIst->hevInterrupt != NULL);
DEBUGCHK(pKeybdIst->pfnGetKeybdEvent != NULL);
DEBUGCHK(pKeybdIst->pfnKeybdEvent != NULL);

SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);

wait_for_keybd_interrupt:
  if (WaitForSingleObject(pKeybdIst->hevInterrupt, INFINITE) == WAIT_OBJECT_0)
  {
   cEvents = (*pKeybdIst->pfnGetKeybdEvent)
(pKeybdIst->uiPddId, rguiScanCode, rgfKeyUp);

   for (UINT iEvent = 0; iEvent < cEvents; ++iEvent) {
     (*pKeybdIst->pfnKeybdEvent)(pKeybdIst->uiPddId, 
      rguiScanCode[iEvent], rgfKeyUp[iEvent]);
   }
// cEvents could be 0 if this was a partial scan code, like 0xE0

  InterruptDone(pKeybdIst->dwSysIntr_Keybd);
}

  goto wait_for_keybd_interrupt;

ERRORMSG(1, (TEXT("KeybdIstLoop: Keyboard driver thread terminating./r/n")));
return TRUE;

相关文章推荐

Linux设备驱动程序学习笔记12:中断调用流程

通过轮询的方式去查询各个硬件的状态显得有的低效,一种更好的机制是当硬件状态准备好之后能够主动地报告给CPU。中断就是这样的一种机制,它允许硬件发信号给CPU。 下面就先分析一下当一个中断发生时,Li...

ARM 中断驱动程序的开发流程(以s3c2440开发板为例)

为便于管理中断和节约CPU管脚,在cpu与中断源之间都会有中断控制器,一般的ARM芯片内部都集成了片上中断控制器。 以s3c2440开发板的按键中断为例来说明ARM中断的开发过程。 当一个设备产生...

S3C6410 按键驱动(二) ---按键中断的基本流程

1.将引脚设置为中断模式 void init_dev(void) { s3c_gpio_cfgpin(key_table[0],S3C_GPIO_SFN(2)); s3c_gpio_cfg...

Linux设备驱动程序学习笔记14:中断的初始化流程

init是Linux内核启动的第一个用户级进程,系统的很多初始化工作都是由它开始的,当然也包括中断的初始化工作。其主要函数在init/main.c中,汇编程序会跳到该文件的start_kernel函数...

Exynos4412 中断驱动开发(二)—— 中断处理流程分析

前面已经学习了中断的注册过程,下面由一张流程图来看一下当中断发生时的处理流程: 中断发生之后处理流程 a -- 具体的CPU architecture相关模块进行现...

Exynos4412 中断驱动开发(二)—— 中断处理流程分析

前面已经学习了中断的注册过程,下面由一张流程图来看一下当中断发生时的处理流程: 中断发生之后处理流程 a -- 具体的CPU architecture相关模块进行现场保护,然后调用machin...

嵌入式学习-驱动开发-lesson3-混杂设备驱动模型与linux中断处理流程

一、混杂设备驱动模型 混杂设备属于字符设备中的一种 在Linux驱动中把无法归类的一些的设备定义为混杂设备(miscdevice)。他们共享相同的主设备号MISC_MAJOR(即10),但次设备号...

WCE驱动开发流程

  • 2013年09月10日 09:48
  • 45KB
  • 下载

嵌入式linux驱动开发流程总结

嵌入式linux驱动开发流程 嵌入式系统中,操作系统是通过各种驱动程序来驾驭硬件设备的。设备驱动程序是操作系统内核和硬件设备之间的接口,它为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:驱动中断流程
举报原因:
原因补充:

(最多只允许输入30个字)