1)Windows CE中断处理流程
①硬件设备向Kernel发送中断异常的代码,如果检测到这个中断异常,就会被Kernel层的异常处理所截获。然后,中断服务调度程序会调用OAL例程中的OEMInterruptDisable函数,这个函数会通知硬件在处理完这一中断前关闭特殊的中断,但其它的中断仍然处于开放状态,中断服务例程ISR会被调用来决定如何处理这一中断。
②Kernel接收到ISR的返回值可得知如何处理这一中断。它的响应结果之一是忽略掉这一中断不作处理(SYSINTR_NOP),或另一结果是准备执行IST。然后,Kernel引发中断服务调度程序去唤醒中断服务线程。IST是常规的Win32线程,一旦启动后,它会创建必要的EVENT,然后等待该EVENT被激发。中断服务调度通过调用PulseEvent函数来激发EVENT,从而唤醒IST线程运行。当唤醒以后,IST会对中断进行处理。
③当IST处理完成后,还需要调用InterruptDone函数通知Kernel。Kernel则调用OEMInterruptDone函数完成此次中断的处理过程。最后,OAL例程通知硬件设备重新启用中断。
(2)中断处理涉及的几个常用函数
Windows CE在处理中断时会涉及到两类函数的使用,第一类是供OAL调用的ISR函数,例如HookInterrupt函数在OEMInit函数中被调用以关联IRQ和ISR,UnhookInterrupt函数用来终止IRQ和ISR的关联。第二类是供驱动程序调用的IST函数,例如InterruptInitialize函数用来将EVENT对象和逻辑中断号关联并允许中断,InterruptDone函数用来通知中断处理的结束,InterruptDisable函数被驱动程序调用以关闭中断同时取消被InterruptInitialize初始化的EVENT对象。
ISR函数属于OAL层,它将CPU寄存器中的数据移动到内存缓冲区中,但是它不能做更多的工作,其中一个原因是它不能访问用户态的存储区,它要把这些工作交给IST来完成。ISR函数做的另一项工作是进行物理中断号和逻辑中断号的映射。经过ISR后,就能把这一物理中断转换成Windows CE标准的SYSINTR_KEYBOARD逻辑中断。Kernel会根据这个逻辑中断值找到对应的EVENT,从而唤醒IST。
最后,需要提醒一下的是,常常有一些开发人员习惯拖延或忽视陷阱调度的编写。因为轻视陷阱调度这一坏习惯是如此常见,它甚至已经影响到了Windows CE系统的研发。因此,建议从开始时就应该着手进行陷阱调度研发和计划,应该投入大精力把陷阱调度的策略融合到嵌入式产品中。