s3c2410 中断异常处理(转)

2024-04-17 18:48
文章标签 异常 处理 中断 s3c2410

本文主要是介绍s3c2410 中断异常处理(转),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章出处: http://www.another-prj.com/viewthread.php?tid=14&extra=page%3D1
在进入正题之前,我想先把ARM920T的异常向量表(Exception Vectors)做一个简短的介绍。:]
ARM920T的异常向量表有两种存放方式,一种是低端存放(从0x00000000处开始存放),另一种是高端存放(从0xfff000000处开始存放)。关于为什么要分两种方式进行存放这点我将在介绍MMU的文章中进行说明,本文采用低端模式。ARM920T能处理有8个异常,他们分别是:
Reset,Undefined instruction,Software Interrupt,Abort (prefetch),Abort (data),Reserved,IRQ,FIQ
下面是某个采用低端模式的系统源码片段:
_start:
b Handle_Reset
b HandleUndef
b HandleSWI
b HandlePrefetchAbort
b HandleDataAbort
b HandleNotUsed
b HandleIRQ
b HandleFIQ
..

..
other codes
上面这部分片段一般出现在一个名叫“head.s”的汇编文件里,“b Handle_Reset”这条语句就是系统上电之后运行的第一条语句。也就是说这部分代码的二进制码必须位于内存的最开始部分(这正是低端存放模式),因为上电后CPU会从SDRAM的0x00000000处取第一条指令并执行。
Address     Instruct
0x00000000: b Handle_Reset
0x00000004: b HandleUndef
0x00000008: b HandleSWI
0x0000000C: b HandlePrefetchAbort
0x00000010: b HandleDataAbort
0x00000014: b HandleNotUsed
0x00000018: b HandleIRQ
0x0000001C: b HandleFIQ
    上面是该程序段在系统上电后加载到内存后的分布情况,我们可以看到每条指令占用了4个字节。
    上电后,PC指针会跳转到Handle_Reset处开始运行。以后系统每当有异常出现,则CPU会根据异常号,从内存的0x00000000处开始查表做相应的处理,比如系统触发了一个IRQ异常,IRQ为第6号异常,则CPU将把PC指向0x00000018地址(4*6=24=0x00000018)处运行,该地址的指令是跳转到“中断异常服务例程”(HandleIRQ)处运行。以上就是我对异常向量表的一个简单介绍。现在可以进入我们文章的主题 “中断异常处理”,s3c2410的中断分快中断(FIQ)和普通中断(IRQ),我们讨论的重点是普通中断(IRQ)。
s3c2410的中断异常处理模块总共由以下寄存器构成
  SRCPND(SOURCE PENDING REGISTER)
  INTMOD(INTERRUPT MODE REGISTER)
  INTMSK(INTERRUPT MASK REGISTER)
  PRIORITY( PRIORITY REGISTER)
  INTPND(INTERRUPT PENDING REGISTER)
  INTOFFSET(INTERRUPT OFFSET REGISTER)
  SUBSRCPND (INTERRUPT SUB SOURCE PENDING)
  INTSUBMSK  (INTERRUPT SUB MASK REGISTER)

下面我将讲解每个寄存器在一个中断处理流程中所扮演的角色:
    SRCPND/ SUBSRCPND这两个寄存器在功能上是相同的,它们是中断源引脚寄存器,在一个中断异常处理流程中,中断信号传进中断异常处理模块后首先遇到的就是 SRCPND/ SUBSRCPND,这两个寄存器的作用是用于标示出哪个中断请求被触发。 SRCPND的有效位为32, SUBSRCPND 的有效位为11,它们中的每一位分别代表一个中断源。 SRCPND为主中断源引脚寄存器, SUBSRCPND为副中断源引脚寄存器。
这里列举出 SRCPND的各个位信息:
每个位的初始值皆为0。假设现在系统触发了TIMER0中断,则第10bit将被置1,代表TIMER0中断被触发,该中断请求即将被处理(若该中断没有被屏蔽的话)。 SUBSRCPND情况与 SRCPND相同,这里就不多讲了。
    INTMOD寄存器有效位为32位,每一位与 SRCPND中各位相对应,它的作用是指定该位相应的中断源处理模式(IRQ还是FIQ)。若某位为0,则该位相对应的中断按IRQ模式处理,为1则以FIQ模式进行处理,该寄存器初始化值为 0x00000000,即所有中断皆以 IRQ模式进行处理。(详细请参考s3c2410操作手册)。
INTMSK/ INTSUBMSK 寄存器为中断屏蔽寄存器 , INTMSK为主中断屏蔽寄存器, INTSUBMSK为副中断屏蔽寄存器。 INTMSK有效位为32, INTSUBMSK有效位为11,这两个寄存器各个位与 SRCPNDSUBSRCPND分别对应。它们的作用是决定该位相应的中断请求是否被处理。若某位被设置为1,则该位相对应的中断产生后将被忽略(CPU不处理该中断请求),设置为0则对其进行处理。这两个寄存器初始化后的值是 0xFFFFFFFF0x7FF,既默认情况下所有的中断都是被屏蔽的。
到目前为止我们总共讲解了 SRCPND,INTMOD,INTMSK,SUBSRCPND,INTSUBMSK
五个寄存器,在继续讲解PRIORITY寄存器之前我们先来看一张图。
先弄清楚一点,现在要讨论的是一个中断优先级的判断问题。为什么会有中断有先级的问题呢?我们知道CPU某个时刻只能对一个中断源进行中断处理,如果现在有3个中断同时发生了,那CPU要按什么顺序处理这个3个中断呢?这正是引入优先级判断的原因所在,通过优先级判断,CPU可以按某种顺序逐个处理中断请求。3sc2410的优先级判断分为两级。
    如上图所示, SRCPND寄存器对应的32个中断源总共被分为6个组,每个组由一个 ARBITER(0~5)寄存器对其进行管理。中断必须先由所属组的 ARBITER(0~5)进行第一次优先级判断(第一级判断)后再发往 ARBITER6进行最终的判断(第二级判断)。 ARBITER(0~5)这六个组的优先级已经固定,我们无法改变,也就是说由 ARBITER0控制的该组中断优先级最高(该组产生的中断进行第一级判断后永远会以REQ0向 ARBITER6传递过去)其次是 ARBITER1, ARBITER2, ARBITER4, ARBITER4, ARBITER5.我们能够控制的是某个组里面各个中断的优先级顺序。怎么控制?通过 PRIORITY寄存器进行控制:]
以下是PRIORITY寄存器各个位的参数表
从表上我们可以知道 PRIORITY寄存器内部各个位被分为两种类型,一种是 ARB_MODE,另一种为 ARB_SEL, ARB_MODE类型有5组对应 ARBITER(2~6)(PS:此处应更正为 ARB_MODE类型有7组对应 ARBITER(0~6),在datasheet中上表还有续表,为ARB_MODE1-0) ,ARB_SEL类型有7组对应 ARBITER(0~6)。现在我将以 ARBITER2为例,讲解中断组与 PRIORITY寄存器中 ARB_SEL, ARB_MODE之间的相互关系。
  首先我们看到ARBITER2寄存器管理的该组中断里包括了6个中断,分别是 INT_TIMER0,INT_TIMER1,INT_TIMER2,INT_TIMER3,INT_TIMER4,INT_UART2,她们的默认中断请求号分别为 REQ0,REQ1,REQ2,REQ3,REQ4,REQ5。我们先看 PRIORITY寄存器中的 ARB_SEL2,该参数由两个位组成,初始值为00。从该表可以看出00定义了一个顺序 0-1-2-3-4-5 ,这个顺序就是这组中断组的优先级排列,这个顺序指明了以中断请求号为0(REQ0)的INT_TIMER0具有最高的中断优先级,其次是INT_TIMER1,INT_TIMER2…。假设现在 ARB_SEL2的值被我们设置为01。则一个新的优先级次序将被使用,01对应的优先级次序为 0-2-3-4-1-5,从中可以看出优先级最高和最低的中断请求和之前没有变化,但 本来处于第2优先级的INT_TIMER1中断现在变成了第5优先级。从 ARB_SEL2被设置为00,01,10,11各个值所出现的情况我们可以看出,除最高和最低的优先级不变以外,其他各个中断的优先级其实是在做一个 旋转排列rotate)。为了达到对各个中断平等对待这一目标,我们可以让优先级次序在每个中断请求被处理完之后自动进行一次旋转,如何自动让它旋转呢?我们可以通过 ARB_MODE2达到这个目的,该参数只有1个 bit,置1代表开启对应中断组的优先级次序旋转,0则为关闭。事实上当该位置为1之后,每处里完某个组的一个中断后,该组的 ARB_SEL便递增在1(达到11后恢复为00)。
    现在我们另 ARB_MODE2=1,ARB_SEL2=00,则当前 ARBITER2的优先级顺序为 0-1-2-3-4-5,假设现在该组的1号中断请求INT_TIMER1和2号中断请求INT_TIMER2被同时触发,CPU根据优先级判断后决定先把INT_TIMER1中断向 ARBITER6进行发送(在ARBITER6做第最终优先级判断),接着再向 ARBITER6发送INT_TIMER2中断。请注意,在INT_TIMER1被处理完毕后,该组中段的优先级次序被 自动做了一次旋转,旋转后 ARBITER2优先级顺序变为0-2-3-4-1-5。假设之后某个时刻该组的INT_TIMER1和INT_TIMER2又被同时触发,则此时CPU优先处理的会是INT_TIMER2。若我们另ARB_MODE2=0,则改组的中断优先级次序在任何情况下都不做任何改变,除非我们 人为地重新设置了ARB_SEL2的值。
    呼。。。好累。。。终于说完了麻烦的优先级-_-…继续。。。
INTPND 寄存器可能是整个中断处理过程中我们要特别注意的一个寄存器了,他的操作比较特别,怎么特别?请听我慢慢道来.:]
先看一下该寄存器各位详细功能列表
正如你所见的, INTPND寄存器与 SRCPND长得一模一样,但他们在中断异常处理中却扮演着不同的角色,如果说 SRCPND是中断信号进入中断处理模块后所经过的第一个场所的话,那么 INTPND则是中断信号在中断处理模块里经历的最后一个寄存器。它的每个位对应一个中断请求,若该位被置1,则表示相应的中断请求被触发,描述到这里你可能会发现它不仅和 SRCPND长得一模一样,就连功能都一样,其实不然,他们在功能上有着重大的区别。SRCPND是中断源引脚寄存器,某个位被置1表示相应的中断被触发,但我们知道在同一时刻内系统可以触发若干个中断,只要中断被触发了, SRCPND的相应位便被置1, 也就是说SRCPND在同一时刻可以有若干位同时被置1然而INTPND则不同,他在某一时刻只能有1个位被置1,INTPND 某个位被置1(该位对应的中断在所有已触发的中断里具有最高优先级且该中断没有被屏蔽),则表示CPU即将或已经在对该位相应的中断进行处理。于是我们可以有一个总结: SRCPND说明了有什么中断被触发了,INTPND说明了CPU即将或已经在对某一个中断进行处理。
特别注意:每当某一个中断被处理完之后,我们必须 手动地把SRCPND/SUBSRCPND , INTPND三个寄存器中与该中断相应的位由1设置为0,刚才我说 INTPND的操作很特别,它的特别之处就在于对当我们要把该寄存器中某个值为1的位设置为0时,我们不是往该位置0,而是 往该位置1。假设 SRCPND=0x00000003,INTPND=0x00000001,该值说明当前0号中断和1号中断被触发,但当前正在被处理的是0号中断,处理完毕后我们应该这样设置 INTPND和SRCPND
  SRCPND=0x00000002              //位0被置为0
  INTPND =0x00000001             //位0被置为0( 方法是往该位写入1
INTOFFSET寄存器的功能则很简单,它的作用只是用于表明哪个中断正在被处理。下面是该寄存器各位详细功能列表
若当前INT_TIMER0被触发了,则该寄存器的值为10,以此类推。
    现在我把整个中断流程用一个图加以说明
以上这个图清楚地说明了一个中断异常处理流程。
    下面我用INT_TIMER0, INT_TIMER2和INT_UART0三个中断完整地介绍一次中断异常处理。首先我们得做几个假设:
假设1:这三个中断的屏蔽被取消。
假设2: PRIORITY寄存器中ARB_MODE2,ARB_MODE5皆为0,既不进行优先级的自动旋转排序,任何时候
       ARBITER2,ARBITER5控制的中断组优先级次序分别为0-1-2-3-4-5和1-2-3-4。
假设3:这三个中断皆为IRQ类型。
假设4:这三个中断同时被触发。
INT_TIMER0,INT_TIMER2和INT_UART0三个中断被同时触发,此时三个中断信号流向 SRCPND寄存器,使该寄存器中的第10位,12位,28位被置为1,中断信号继续向前流经 INTMASK寄存器,这三个中断都没有被屏蔽,于是信号进一步流经 INTMODE寄存器,这三个中断皆为IRQ类型,故中断信号继续向前流向 PRIORITY寄存器,经过优先级判断,INT_TIMER0中断信号使 INTPND寄存器的第10位置1(INT_TIMER0优先级最高),此时 INTOFFSET寄存器的值为10,CPU转向相应的中断服务例程进行处理。处理完毕后,我们的程序将 INTPNDSRCPND的第10置为0,至此INT_TIMER0中断处理完毕。 此时SRCPND的第12位,28位仍为1(这两个中断请求未被处理),故他们会继续被CPU已刚才描述的方式进行处理。
中断异常处理就先讲到这吧 :]
以上是原帖内容,再次感谢作者。。。
PS
在对2410的裸板进行中断实验的过程中,从菜鸟的角度出发,我把学到了一些东西和之前ARM体系结构的理论结合起来:
1、ARM处理器中,r13sp)和r14lr)分别对应6个不同状态下的物理寄存器,其中1个是用户、系统模式共用的,其他分别对应5种异常模式(Exception Mode)。要在后续程序中使用中断,则应先把要用到的各种模式的堆栈设置好,如设置IRQ和系统模式的sp
msr cpsr_c, #0xd2        @进入IRQ模式,IRQ和FIQ都处于禁止状态
ldr sp, =0x33000000

msr cpsr_c, #0xdf        @进入系统模式,IRQ和FIQ都处于禁止状态
ldr sp, =0x34000000

bl init_irq              @初始化中断
msr cpsr_r, #0x5f        @置控制域的I位为0,打开irq中断。实验中只用到irq
2、   如果用到按键等中断控制,是属于外部中断的( External Interrupt ),就需要配置 EINT 相关的寄存器。
 

这篇关于s3c2410 中断异常处理(转)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/912554

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

Thymeleaf:生成静态文件及异常处理java.lang.NoClassDefFoundError: ognl/PropertyAccessor

我们需要引入包: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>sp

深入理解数据库的 4NF:多值依赖与消除数据异常

在数据库设计中, "范式" 是一个常常被提到的重要概念。许多初学者在学习数据库设计时,经常听到第一范式(1NF)、第二范式(2NF)、第三范式(3NF)以及 BCNF(Boyce-Codd范式)。这些范式都旨在通过消除数据冗余和异常来优化数据库结构。然而,当我们谈到 4NF(第四范式)时,事情变得更加复杂。本文将带你深入了解 多值依赖 和 4NF,帮助你在数据库设计中消除更高级别的异常。 什么是

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法   消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法 [转载]原地址:http://blog.csdn.net/x605940745/article/details/17911115 消除SDK更新时的“

jenkins 插件执行shell命令时,提示“Command not found”处理方法

首先提示找不到“Command not found,可能我们第一反应是查看目标机器是否已支持该命令,不过如果相信能找到这里来的朋友估计遇到的跟我一样,其实目标机器是没有问题的通过一些远程工具执行shell命令是可以执行。奇怪的就是通过jenkinsSSH插件无法执行,经一番折腾各种搜索发现是jenkins没有加载/etc/profile导致。 【解决办法】: 需要在jenkins调用shell脚

JVM 常见异常及内存诊断

栈内存溢出 栈内存大小设置:-Xss size 默认除了window以外的所有操作系统默认情况大小为 1MB,window 的默认大小依赖于虚拟机内存。 栈帧过多导致栈内存溢出 下述示例代码,由于递归深度没有限制且没有设置出口,每次方法的调用都会产生一个栈帧导致了创建的栈帧过多,而导致内存溢出(StackOverflowError)。 示例代码: 运行结果: 栈帧过大导致栈内存

明明的随机数处理问题分析与解决方案

明明的随机数处理问题分析与解决方案 引言问题描述解决方案数据结构设计具体步骤伪代码C语言实现详细解释读取输入去重操作排序操作输出结果复杂度分析 引言 明明生成了N个1到500之间的随机整数,我们需要对这些整数进行处理,删去重复的数字,然后进行排序并输出结果。本文将详细讲解如何通过算法、数据结构以及C语言来解决这个问题。我们将会使用数组和哈希表来实现去重操作,再利用排序算法对结果

8. 自然语言处理中的深度学习:从词向量到BERT

引言 深度学习在自然语言处理(NLP)领域的应用极大地推动了语言理解和生成技术的发展。通过从词向量到预训练模型(如BERT)的演进,NLP技术在机器翻译、情感分析、问答系统等任务中取得了显著成果。本篇博文将探讨深度学习在NLP中的核心技术,包括词向量、序列模型(如RNN、LSTM),以及BERT等预训练模型的崛起及其实际应用。 1. 词向量的生成与应用 词向量(Word Embedding)