在调试CAN总线的时候,遇到了操作系统的中断,为了彻底的弄清楚中断是怎么回事?我先从底层的中断开始研究,在这里我们只讨论外部中断,下面就结合S3C2440TEST测试程序来分析一下中断是怎么执行的:我们研究的是IRQ中断,分析中断过程如下,

在2440init.s中有这样的定义

b HandlerIRQ  ;handler for IRQinterrupt 这个标号HandlerIRQ 就是IRQ中断发生十跳转的地址,

然后有这个定义

HandlerIRQ     HANDLER HandleIRQ  这是一个宏定义

我们知道HandlerIRQ 是一个标号,IRQ异常向量就是跳到这里执行的,根据上面的宏定义我又找到一个标号HandleIRQ这个标号是真正的处理函数,然后我们找到这个定义

AREA RamData, DATA, READWRITE

^  _ISR_STARTADDRESS  ;_ISR_STARTADDRESS=0x33FF_FF00
HandleReset  #  4       //启动程序中,如下地址是依次加4
HandleUndef  #  4
HandleSWI  #  4
HandlePabort   #   4
HandleDabort   #   4
HandleReserved #   4
HandleIRQ  #  4
HandleFIQ  #  4

在这里我们找到了HandleIRQ标号的入口地址:

接着往下看

HandleEINT0  #  4
HandleEINT1  #  4
HandleEINT2  #  4
HandleEINT3  #  4
HandleEINT4_7 #  4
HandleEINT8_23 #  4

HandleEINT0是IRQ异常的向量存放的地方了,是所有IRQ中断向量表的入口。

下面看2440的中断按键程序,在2440addr.h里找到了这样的定义(中断、IO、LCD等地址分配)

#definepISR_EINT0  (*(unsigned*)(_ISR_STARTADDRESS+0x20))
#define pISR_EINT1  (*(unsigned*)(_ISR_STARTADDRESS+0x24))
#define pISR_EINT2  (*(unsigned*)(_ISR_STARTADDRESS+0x28))
#define pISR_EINT3  (*(unsigned*)(_ISR_STARTADDRESS+0x2c))
#define pISR_EINT4_7 (*(unsigned*)(_ISR_STARTADDRESS+0x30))
#define pISR_EINT8_23 (*(unsigned*)(_ISR_STARTADDRESS+0x34))

通过地址对照,我们明白了pISR_EINT0  pISR_EINT1  pISR_EINT2  pISR_EINT3  pISR_EINT4_7 pISR_EINT8_23 就是上面的

HandleEINT0  HandleEINT1  HandleEINT2  HandleEINT3  HandleEINT4_7 HandleEINT8_23

我们知道ARM9的外部中断有5条中断信号线,当外部的中断发生时,就会触发相应的中断信号线,其中pISR_EINT4_7 pISR_EINT8_23 两条复用的中断信号线,当外部中断,4-7,8-23都会触发pISR_EINT4_7 pISR_EINT8_23 这两条中断信号线,然后再根据EINTPEND外部中断悬挂寄存器来判断是哪个外部中断源。

因此我们知道pISR_EINT0 = pISR_EINT2 = pISR_EINT8_23 = (U32)Key_ISR;

就是将中断服务程序Key_ISR的地址传送到pISR_EINT0,pISR_EINT2, pISR_EINT8_23 所对应的HandleEINT0   HandleEINT2    HandleEINT8_23 里。从而当中断发生的时候,就可以执行相应的外部中断服务程序。

/

下面介绍基于WINCE操作系统的外部中断,我现在说一下,WINCE中断的具体过程,

首先我们要把我们设置外部中断函数在我们BSP包里必须定义对应的逻辑中断号,在头文件OALINTR.H中

// These are the 'standard' interrupts
#defineSYSINTR_KEYBOARD    (SYSINTR_FIRMWARE+0)
#defineSYSINTR_TOUCH     (SYSINTR_FIRMWARE+1)
#defineSYSINTR_ADC      (SYSINTR_FIRMWARE+2)
#defineSYSINTR_SERIAL     (SYSINTR_FIRMWARE+3)
#defineSYSINTR_AUDIO     (SYSINTR_FIRMWARE+4)
#defineSYSINTR_PCMCIA_STATE   (SYSINTR_FIRMWARE+5)
#defineSYSINTR_PCMCIA_EDGE    (SYSINTR_FIRMWARE+6)
#defineSYSINTR_PCMCIA_LEVEL   (SYSINTR_FIRMWARE+7)

…………// 具体查看D:\WINCE500\PLATFORM\SMDK2410\INC\oalintr.h

MapIrq2SysIntr(DWORD_Irq)这个函数我自己理解当我们的中断发生的时候,调用相应的逻辑中断号时,它就返回逻辑中断号的值。_Irq就是(SYSINTR_FIRMWARE+_Irq)中的。_Irq。只要有了这个逻辑中断号我们就可以用这个函数进行关联中断了,InterruptInitialize(SYSINTR_ETHER,g_hInterrupt, 0,0)他的作用就是,把SYSINTR_ETHER逻辑中断号和创建的事件g_hInterrupt关联起来,当有中断发生的时候,这个函数就会使g_hInterrupt这个事件生效,然后我们用这个函数WaitForSingleObject(g_hInterrupt,INFINITE);
这个函数是一个等待函数,当事件g_hInterrupt生效时,就会向下面的程序执行,否则一直在这里等待事件生效。这就是静态中断的过程,动态我还没有研究出来,可能和我们的BSP包有关系,在下面的学习中我会把它研究出来。

注:在EVC编写调用上面的函数时需要包含头文件:ceddk.h(此处用于实验室面板按键用)。

其实添加完对应的逻辑中断号之后我们还的在这几个文件中添加相应的语句才能真正的触发中断,CFW.C中(参考现有中断添加需要的中断如EINT0等)

2 OAL层中断程序汇总

关于WinCE的中断处理,OAL中主要是实现了ISR部分,一般IST会在设备驱动中实现。架构如图:硬件中断产生以后,会导致内核ISR的运行,然后由OAL中的ISR来处理相应的中断,最后导致相对应的IST运行完成真正的中断处理。所以在WinCE中,中断处理由ISR和IST共同完成。ISR主要完成中断源的确定,屏蔽该中断并返回给内核相对应的系统中断号,ISR应该尽量短小。IST则是完成真正的中断处理,比如数据的传输和解析等。当然不是所有的中断处理都需要ISR和IST,看需要,比如WinCE的系统Timer中断就只需要ISR完成。

2.1 在OAL中支持中断,需要实现以下几个中断处理函数

a. BOOL OEMInterruptEnable(DWORD sysIntr, VOID* pData, DWORD dataSize)

sysIntr:要被使能的系统中断号

pData:传入的数据指针,该数据由InterruptInitialize函数传入

dataSize:传入数据的大小

该函数用于使能某一个硬件中断。在设备驱动调用InterruptInitialize来初始化一个中断的时候,内核就会调用该函数来使能相应的硬件中断。

b. VOID OEMInterruptDisable(DWORD sysIntr)

sysIntr:要被屏蔽的系统中断号

该函数用于屏蔽一个硬件中断。如果设备驱动调用InterruptDisable函数,则该函数会被调用。

c. VOID OEMInterruptDone(DWORD sysIntr)

sysIntr:要被重新使能的系统中断号

该函数标志着一个中断处理过程的完成。当设备驱动调用InterruptDone函数的时候,该函数会被调用,重新使能相应的硬件中断。

d. ULONG OEMInterruptHandler(ULONG ra)

ra:指令计数,在实际应用中,没有太大意义

当硬件中断产生的时候,该函数就会被调用完成ISR部分的中断处理。一般会在该函数中读取系统的中断标记位,确定中断源并返回相应的系统中断号。

e. void OEMInterruptHandlerFIQ(void)

针对于ARM处理器,该函数用于处理快速中断。

上面5个函数完成了中断的相关处理。这里要提到两个概念:IRQ和SYSINTR。IRQ是指物理中断或者叫硬件中断,而SYSINTR指的是系统中断,也有的地方称为虚拟中断或者逻辑中断,我个人觉得还是叫系统中断比较好。每一个IRQ会和一个系统中断SYSINTR相对应,当硬件中断产生时,ISR实际上是处理IRQ中断,然后返回相应的系统中断SYSINTR给内核,内核会根据相应的SYSINTR触发相应的IST来完成中断处理。

IRQ和SYSINTR之间的对应关系称为映射,分为静态映射和动态映射。静态映射是指在系统编译时IRQ已经和SYSINTR相对应,一般通过OALIntrStaticTranslate函数来实现。而动态映射是指WinCE系统启动后,动态关联IRQ与SYSINTR,一般通过KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR…)来实现。

SYSINTR的类型在nkintr.h中定义,OEMInterruptHandler函数在处理完中断以后,会返回不同类型的SYSINTR给内核,内核会根据返回值进行下一步操作,分为以下几种类型:

SYSINTR_NOP:表示不需要进行任何处理

SYSINTR_RESCHED:表示要进行一次系统调度

SYSINTR_CHAIN:表示不是该中断源产生,在中断链中寻找下一个中断

SYSINTR_RTC_ALARM:表示RTC报警产生

SYSINTR_TIMING:用于ILTiming测试

SYSINTR_PROFILE:用于系统的profile

SYSINTR_FIRMWARE:用于用户自定义系统中断号,所有自定义的系统中断号都应该基于该值进行累加加1,这些自定义的系统中断号用于和IRQ一一对应。

S3C2440中断解析和基于WINCE操作系统的中断分析(整理于网络,用于按键中断使用)相关推荐

  1. linux驱动由浅入深系列:基于高通平台分析触摸屏(TP)、虚拟按键驱动

    触摸屏的触摸板(touch panel简称TP)驱动的基本架构和普通按键驱动基本一致,可以参考文章: linux驱动由浅入深系列:输入子系统之二(编写一个gpio_key驱动).只是其功能稍稍复杂些, ...

  2. c语言 执行free函数程序被卡住,FreeRTOS操作系统,在按键中断函数中恢复被挂起的任务,程序卡死的原因和解决办法...

    FreeRTOS操作系统,在按键中断函数中恢复被挂起的任务,程序卡死的原因和解决办法 时间:2019-08-10 14:39:47  来源:  作者:  所属栏目:其他服务端 这里将告诉您FreeRT ...

  3. c语言程序仪表称重编程,基于WinCE的双台面动态汽车称重装置仪表设计

    摘要: 动态汽车衡技术在我国已有多年的发展,已广泛应用在高速公路计重收费与超限检测系统中,其核心技术为系统中的核心装置电子称重仪表的软硬件开发与设计.在传统的称重仪表开发模式中,一直采用单片机作为主控 ...

  4. STM32——中断、EXTI、按键中断实验

    STM32中断--总结及实操 一.中断是什么? 1.1 中断的含义 1.2 中断的作用(了解即可) 1.3 中断的流程 二.中断资源 2.1 NVIC中断控制器 2.2 NVIC寄存器 三.优先级的概 ...

  5. linux驱动开发5 按键中断实验(定时器和中断)

    led:IO的输出 :key:IO的输入 法一:直接读写IO 使用while(1)无限读取,但CPU占用达到了99.6%,所以不行 #include <linux/types.h>#inc ...

  6. 光中断器行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)

    光中断器市场的企业竞争态势 该报告涉及的主要国际市场参与者有Sharp.Omron.Rohm Semiconductor.TT Electronics.Vishay Intertechnology.P ...

  7. linux虚拟中断virq,一种微内核操作系统的分区多核方法与流程

    本发明涉及一种计算机领域,特别涉及一种微内核操作系统的分区多核方法. 背景技术: 在宏内核操作系统(如Linux,Windows)中,网络.文件系统.设备驱动等大量系统服务都在操作系统内核中,微内核操 ...

  8. S3C2440之按键中断

    文章目录 前言 一.中断过程 二.关键代码 前言 本文基于S3C2440开发板所写的按键中断 一.中断过程 1.初始化.①设置中断,让它能够发出中断信号 ②设置中断控制器,让它能发出中断给CPU ③设 ...

  9. 基于OMAPL138的字符驱动_GPIO驱动AD9833(三)之中断申请IRQ

    基于OMAPL138的字符驱动_GPIO驱动AD9833(三)之中断申请IRQ 0. 导语 学习进入到了下一个阶段,还是以AD9833为例,这次学习是向设备申请中断,实现触发,在未来很多场景,比如做用 ...

最新文章

  1. 24/100. Linked List Cycle
  2. Gradle中的默认任务和任务依赖关系设置
  3. dlopen linux 实例_Linux静态库和动态库
  4. Linux 下wifi 驱动开发(四)—— USB接口WiFi驱动浅析
  5. Python中文全攻略
  6. AcWing 4244. 牛的比赛(双向建图BFS)
  7. 使用Sphinx对MySQL数据库进行全文检索
  8. 暴风酷播云二期配置_暴风播酷云二期拆解
  9. HIVE:Hive启动 beeline 客户端失败的解决方法
  10. 2021年N1叉车司机模拟考试题库软件及全国真题汇总
  11. java创建临时文件夹_Java 创建文件、文件夹以及临时文件
  12. 使用OpenCV,Python和dlib进行眨眼检测
  13. 论文精读:XGBoost: A Scalable Tree Boosting System
  14. freescale S12X微控制器 模拟EEPROM 快速上手指南
  15. 语音芯片JQ8400的使用心得
  16. 俞敏洪大学经典励志演讲:像树一样活着
  17. 【译】Jep文档(4)——数据类型(Data Type)
  18. Centos7卸载自带的OpenJDK
  19. [空间分析] DEM提取沟沿线
  20. Premiere Pro CC 2017-基础操作

热门文章

  1. java中字节流的选择,求助,java中怎么用字节流读写汉字
  2. beetl 取list下标的问题
  3. grav html5,如何通过html5实现摇一摇的功能
  4. xss防御补丁_Discuz论坛最新dom xss漏洞的解决方法
  5. html框架有什么作用,使用HTML5+CSS+JS框架有那些好处
  6. Spring Boot----Dubbo原理分析
  7. Flask 路由映射对于双斜线的处理 //a//b
  8. B-JUI文档、下载
  9. bzoj3203: [Sdoi2013]保护出题人
  10. $(document).ready()和window.onload之间的差异