嵌入式中断处理
嵌入式中断实验报告心得
一、实验背景随着物联网、智能制造等领域的快速发展,嵌入式系统在各个行业中扮演着越来越重要的角色。
中断技术作为嵌入式系统的重要组成部分,对于提高系统的实时性、可靠性和响应速度具有重要意义。
为了更好地掌握中断技术,我进行了嵌入式中断实验,以下是我对实验的心得体会。
二、实验目的1. 理解中断的概念、作用及中断处理流程;2. 掌握嵌入式系统中断的配置方法;3. 学会编写中断服务程序;4. 通过实验验证中断技术的应用效果。
三、实验内容1. 硬件环境:嵌入式开发板、仿真器、连接线等;2. 软件环境:嵌入式操作系统、集成开发环境、仿真器驱动程序等;3. 实验步骤:(1)搭建实验环境,包括硬件连接和软件配置;(2)配置中断源,如GPIO、定时器等;(3)编写中断服务程序,实现中断响应和处理;(4)通过仿真器观察实验效果,验证中断技术。
四、实验心得1. 理解中断原理在实验过程中,我首先学习了中断的基本概念和作用。
中断是指当外部事件发生时,系统暂停当前执行的任务,转而执行中断服务程序,处理外部事件。
通过实验,我明白了中断处理流程,包括中断请求、中断响应、中断处理和中断返回等环节。
2. 中断配置方法在实验中,我学习了如何配置中断源。
以GPIO为例,首先需要设置GPIO引脚为中断模式,然后配置中断触发方式(上升沿、下降沿或双边沿触发),最后设置中断优先级。
通过实验,我掌握了中断配置方法,为后续应用中断技术打下了基础。
3. 编写中断服务程序中断服务程序是中断处理的核心,我通过实验学会了编写中断服务程序。
在编写过程中,需要注意以下几点:(1)保护现场:在中断服务程序开始执行前,需要保存当前CPU状态,如寄存器值等;(2)处理中断:根据中断类型,执行相应的处理逻辑;(3)恢复现场:在中断服务程序执行完毕后,需要恢复CPU状态,以便继续执行被中断的任务。
4. 实验效果验证通过仿真器观察实验效果,我发现中断技术能够有效地提高系统的响应速度和实时性。
嵌入式--中断系统学习(中断系统+NVIC+SYSCFG+优先级配置+中断嵌套+中断架构)
嵌⼊式--中断系统学习(中断系统+NVIC+SYSCFG+优先级配置+中断嵌套+中断架构)⼀、嵌⼊式中断系统 (1)中断原理 ⾸先要搞明⽩怎么实现的中断,CPU遇到紧急事件要处理,就跳转到紧急事件,再返回来继续处理 就时SP配合PC的⼀套操作了 1、进⼊中断 (a)处理器⾃动保存现场到栈⾥SP,PC,xPSR,R0-R3,LR, (b)⼊栈结束以后,ISR开始执⾏(中断服务) (c)中断会⾃动找到中断⼊⼝函数-》Vector⾥⾯声明的 2、退出中断 (a)现场恢复PC,SP (b)出栈完成执⾏下⼀条⼆、嵌套向量控制器NVIC NVIC专门⽤于管理中断控制器(CPU并不知道谁传来的中断请求) NVIC功能: (1)中断管理 1、给中断使能/禁⽌ ISER--中断使能 ICER--中断禁⽌ 2、设置挂起状态 ISPR--中断挂起 ICPR--中断挂起清除 3、设置脉冲/下降触发 (2)中断异常的向量化处理 Reset+SVCall+系统调⽤+Systick 当产⽣异常时,处理器把PC设置为中断向量(中断⼊⼝),每⼀个异常就是⼀个中断号,汇集起来就是中断向量表 其中位置系统内部是负数,外部异常时正数。
并且优先级值越⼩,优先级越⾼ (3)中断配置 1、中断分组 STM32可以将中断分为5组-》0-4,其中划分两种:抢占优先级和响应优先级 抢占优先级响应级别⾼于响应优先级。
其中数值越⼩优先级越⾼ 嵌套: ⾼优先级的抢占优先级是可以打断正在进⾏的低抢占优先级中断的; 抢占优先级相同的中断,⾼响应优先级不可以打断低响应优先级的中断; 抢占优先级相同的中断,当两个中断同时发⽣的情况下,哪个响应优先级⾼,哪个先执⾏; 如果两个中断的抢占优先级和响应优先级都是⼀样的话,则看哪个中断先发⽣就先执⾏;1. 打断的情况只会与抢占优先级有关,和响应优先级⽆关!⼀般情况下,系统代码执⾏过程中,只设置⼀次中断优先级分组,⽐如分组2,设置好分组之后⼀般不会再改变分组。
嵌入式中断按键实验报告
嵌入式中断按键实验报告本实验的目的是学习如何在嵌入式系统中使用中断来处理按键输入。
通过该实验,我们可以掌握如何配置和使用中断,以及如何编写中断服务程序来处理按键输入。
实验材料:1. 嵌入式开发板2. 按键模块3. 电源适配器实验步骤:1. 将按键模块连接到嵌入式开发板的GPIO引脚上,确保连接正确。
2. 打开开发板的开关,给开发板供电。
3. 在开发板上配置GPIO引脚作为中断输入,并使能中断。
4. 编写中断服务程序来处理按键输入。
当按键被按下时,中断服务程序将被调用,并执行相应的操作。
5. 在主程序中初始化中断服务程序,并进入一个无限循环。
在该循环中,可以进行其他的操作,并等待按键中断的发生。
实验结果:在实验中,我们成功地配置并使用了中断来处理按键输入。
当按键被按下时,中断服务程序被调用,并执行了相应的操作。
讨论与分析:通过该实验,我们学习到了中断的基本原理和使用方法。
中断是一种非常重要的机制,可以使嵌入式系统更高效地响应外部事件。
在实际的嵌入式应用中,按键输入是非常常见的操作,使用中断可以很好地处理按键输入,提高系统的响应速度和可靠性。
然而,中断也存在一些问题。
首先,中断处理需要一定的时间,在高速的系统中,中断的处理时间可能会影响到系统的性能。
另外,当系统存在多个中断源时,中断处理的优先级和调度也需要仔细设计,以确保系统的正常运行。
总结:通过本实验,我们成功地学习了嵌入式系统中使用中断处理按键输入的方法。
中断是一种重要的机制,可以使系统更高效地响应外部事件。
通过合理地设计和使用中断,可以提高系统的性能和可靠性。
在实际的嵌入式应用中,我们应该根据具体的需求和系统条件来选择最合适的中断处理方法,并进行适当的优化和调试。
nvic嵌套向量中断控制器工作原理
一、引言Nvic嵌套向量中断控制器(Nested Vectored Interrupt Controller)是一种常见的中断控制器,它在嵌入式系统中扮演着重要的角色。
本文将介绍Nvic的工作原理,帮助读者更好地理解这一关键的硬件组件。
二、Nvic的基本概念Nvic是一种硬件组件,用于管理和分发系统中的中断请求。
在嵌入式系统中,当发生外部事件或者特定的处理器状态发生变化时,需要立即中断当前的程序执行,执行特定的中断服务程序。
而Nvic就是用来协调这些中断请求的,确保它们按照优先级和顺序得到正确的处理。
三、中断控制器的作用1.管理中断请求中断是在嵌入式系统中的一种重要的事件响应机制。
当外部设备(如传感器、通信接口等)产生需要处理的事件时,会向处理器发送中断请求。
而中断控制器就是负责接收、管理和分发这些中断请求的硬件组件。
2.中断优先级在一个嵌入式系统中,可能同时出现多个中断请求,此时中断控制器需要根据中断请求的优先级决定哪个中断将被优先处理。
Nvic通过优先级编码的方式,能够准确地确定中断的优先级,确保高优先级的中断能够得到及时处理。
四、Nvic的工作原理1.中断向量表Nvic通过中断向量表来实现对中断请求的管理。
中断向量表是一张表格,每个中断都有一个特定的中断向量号。
当中断控制器接收到中断请求时,根据中断向量号可以迅速定位到对应的中断服务程序的入口位置区域,从而进行中断处理。
2.中断优先级编码Nvic使用中断优先级编码的方式来确定中断的优先级。
在Nvic中,中断请求会按照其具体的中断向量号进行编码,从而确定其优先级。
当多个中断请求同时到达时,Nvic会根据优先级编码来决定哪个中断会被优先处理。
3.嵌套中断Nvic支持嵌套中断的机制,即在一个中断服务程序的执行过程中,如果遇到了更高优先级的中断请求,Nvic可以暂停当前中断服务程序的执行,转而处理更高优先级的中断请求。
这种机制可以确保高优先级的中断能够得到及时处理,提高系统的响应速度。
keil中断返回到主函数的特定位置
keil中断返回到主函数的特定位置在嵌入式系统开发中,中断是一种重要的机制,用于处理实时性要求较高的任务。
Keil是一款常用的嵌入式开发工具,它提供了丰富的功能和库,方便开发人员进行嵌入式软件开发。
在Keil中,中断的处理是通过中断服务函数来完成的。
当中断发生时,程序会跳转到相应的中断服务函数中执行,然后再返回到主函数继续执行。
然而,在某些情况下,我们可能希望中断处理完毕后能够返回到主函数的特定位置,而不是从中断服务函数的末尾返回。
这种需求在一些特定的应用场景中非常常见,比如在处理完中断后需要继续执行某个特定的任务。
为了实现这个目标,我们可以借助Keil提供的一些特性和技巧。
首先,我们需要在主函数中定义一个全局变量,用于标记中断处理完毕后需要跳转到的位置。
这个全局变量可以是一个枚举类型,用于表示不同的跳转位置。
然后,在中断服务函数中,我们可以根据具体的需求设置这个全局变量的值。
接下来,我们需要在主函数中添加一个循环,用于检测这个全局变量的值。
当检测到全局变量的值与我们预期的跳转位置相同时,我们可以跳出循环,继续执行后续的任务。
为了避免循环过于频繁地检测全局变量的值,我们可以在循环中添加一些延时操作,以降低CPU的占用率。
下面是一个示例代码,演示了如何在Keil中实现中断返回到主函数的特定位置:```c#include <reg51.h>// 定义全局变量,用于标记跳转位置enum JumpPosition {POSITION_A,POSITION_B,POSITION_C};enum JumpPosition jumpPosition = POSITION_A; // 中断服务函数void interruptServiceRoutine() interrupt 0 {// 中断处理代码...// 设置跳转位置jumpPosition = POSITION_B;}void main() {// 初始化...// 启用中断EA = 1;// 主循环while (1) {// 检测跳转位置if (jumpPosition == POSITION_B) {// 跳转到特定位置// ...// 清除跳转位置标记jumpPosition = POSITION_A;}// 延时操作,降低CPU占用率// ...}}```在上面的示例代码中,中断服务函数中设置了跳转位置为POSITION_B。
嵌入式系统的实时性与稳定性优化
嵌入式系统的实时性与稳定性优化嵌入式系统是一种特殊的计算机系统,被嵌入到其他设备或系统中,广泛应用于汽车、智能家居、医疗仪器等领域。
在这些应用中,实时性和稳定性是嵌入式系统的重要指标,对于系统的可靠性和性能起着至关重要的作用。
因此,为了提高嵌入式系统的实时性与稳定性,需要进行相应的优化。
一、实时性优化实时性是指系统对外部事件的响应速度,即系统在规定的时间内完成某个任务的能力。
在嵌入式系统中,实时性优化需要从以下几个方面入手。
1. 硬件选型优化在设计嵌入式系统时,合理选择硬件是实时性优化的基础。
首先,要选择高性能的处理器和内存,以确保系统能够快速响应外部事件。
其次,要根据实时性的要求,选择合适的外设接口和通信模块,以提高系统的数据传输速度和稳定性。
2. 软件设计优化软件设计是提高嵌入式系统实时性的关键因素。
在软件设计过程中,可以采取以下几个优化策略。
首先,要合理设置任务的优先级,确保高优先级任务能够及时得到执行。
其次,要合理分配任务的时间片,避免任务之间的互相影响。
最后,要采用合适的调度算法,如实时操作系统中的优先级调度算法或轮转调度算法,以提高任务的响应速度。
3. 中断处理优化中断处理是嵌入式系统实时性优化的重要环节。
中断是指硬件或软件发生的突发事件,需要立即中止当前执行的任务,转而执行与中断相关的任务。
在中断处理过程中,需要考虑以下几个优化策略。
首先,要合理设置中断的优先级,确保高优先级中断能够优先得到处理。
其次,要尽量减少中断处理的时间,以避免对正常任务的影响。
最后,要采用合适的中断处理机制,如中断嵌套或中断滤波等,以提高中断处理的效率和可靠性。
二、稳定性优化稳定性是指系统在运行过程中保持稳定的性能和功能。
对于嵌入式系统来说,稳定性优化需要从以下几个方面入手。
1. 电源管理优化电源管理是保证嵌入式系统稳定性的关键因素。
在电源管理过程中,可以采取以下几个优化策略。
首先,要合理设计系统的供电电路,以提供稳定的电压和电流。
嵌入式系统中的实时操作系统应用方法
嵌入式系统中的实时操作系统应用方法嵌入式系统已经成为现代科技应用中不可或缺的一部分,从家电到汽车,从智能手机到工业自动化,几乎所有领域都离不开嵌入式系统的支持。
而实时操作系统(RTOS)在嵌入式系统中的应用则是保证系统任务实时性和可靠性的关键。
实时操作系统是一种能够按照严格的时间要求来处理任务的操作系统。
它的设计目标是保证任务能在预定的时间内得到执行,并且能够及时响应外部事件。
在嵌入式系统中,实时操作系统的应用方法可以大致分为以下几个方面:1. 任务调度嵌入式系统通常有多个任务需要同时进行,这些任务可能具有不同的优先级和时间要求。
实时操作系统通过任务调度算法来确定哪个任务可以得到执行,如何分配处理器资源以及任务的优先级。
常用的任务调度算法包括先来先服务(FCFS)和优先级调度算法。
开发人员可以根据任务的特点选择合适的调度算法,以满足系统的实时要求。
2. 中断处理嵌入式系统中,中断是一种常见的外部事件,如传感器输入、通信数据接收等。
实时操作系统通过中断处理机制来及时响应这些外部事件,并且保证任务能够在正确的时刻被中断执行。
中断处理的方法包括设置中断向量表、中断服务例程的编写和中断处理的优先级管理等。
3. 任务通信与同步在嵌入式系统中,任务之间往往需要进行通信和同步。
实时操作系统提供了一系列的通信与同步机制,如事件标志、消息队列、信号量和互斥锁等。
这些机制可以保证任务之间的有序交互和数据的正确共享,提高系统的实时性和可靠性。
4. 内存管理嵌入式系统通常具有有限的内存资源,因此需要进行有效的内存管理。
实时操作系统提供了内存管理的机制,如静态内存分配和动态内存分配。
开发人员可以根据系统的需求选择合适的内存管理方式,并进行内存分配和回收操作,以提高系统的性能和稳定性。
5. 设备驱动程序开发嵌入式系统通常需要与各种外部设备进行交互,如传感器、执行器、通信模块等。
实时操作系统通过设备驱动程序的开发来实现与外部设备的连接和控制。
浅谈嵌入式MCU的中断处理
浅谈嵌入式MCU的中断处理众所周知,一方面,MCU在嵌入式系统中的广泛使用的一个重要原因就是其相对于MPU和通用CPU的时效性优势。
而低延迟的外设中断和中断嵌套正是MCU实时性的最大保障。
另一方面,在嵌入式系统MCU软件开发中,随着系统功能的日益复杂,不论是否采用RTOS,多任务都是不可避免的。
在裸奔系统中,为了让时间关键的任务得到最先响应,往往需要通过外设中断嵌套来实现,属于基于外设的硬件中断嵌套,而在RTOS中,则给所有系统任务,都赋以具体的优先级,由内核根据优先级高低来进行调度,实际上是实现了一套基于优先级的软件中断嵌套。
RTOS中的任务软件嵌套通过内核tick 定时器中断不断查询RTOS任务就绪表中各任务的优先级高低来实现任务切换,其外设硬件中断未必需要嵌套。
本文旨在给大家介绍嵌入式MCU的中断处理相关知识,帮助大家理解中断,并使用好中断。
既然中断嵌套对于嵌入式系统设计如此重要,具体什么是中断嵌套呢?在具体解释中断嵌套之前,有必须要先讲一下嵌入式MCU的中断工作机制和中断优先级:写过裸奔程序的工程师都知道,一个内核CPU同一个时刻只能执行一个任务/程序代码/指令,比如数据计算,与片上外设进行交互通信等。
代码的执行顺序是用户自己首先写好的,CPU逐行取指、译码、执行即可。
产品功能的实现就是在main函数的while(1)循环中(常称作主程序),不断的调用其他功能函数实现的。
但实际工作环境中、很多事件是随机发生的,比如网络通信,外部IO输入等不确定事件,这个时候CPU就不得不放下当前正在执行的工作,却响应这些紧急事件,及时读取网络报文、处理并回复网络通信需求,及时外部IO请求。
这样的处理就叫做中断。
嵌入式MCU中内核CPU异常和各种外设工作都能够产生响应的中断,且通过中断控制器统一进行管理。
这样CPU在中断未产生时就可以专心处理顺序执行的任务,而只有在中断产生时才通过中断控制器中断CPU(通过产生一个高电平/低电平信号给CPU,这个过程被称为中断请求),如果此时CPU全局中断处于使能状态,则CPU会结合中断向量表和中。
嵌入式-中断实验
嵌入式-中断实验
嵌入式中断实验是一种用来测试和学习嵌入式系统中断功能的实验。
中断是嵌入式系统中常用的一种机制,用于处理紧急事件或高优先级任务。
通过中断,系统可以立即响应外部事件,中断当前正在执行的任务,执行与中断事件相关的代码,然后返回到原来的任务中继续执行。
在进行中断实验时,通常需要以下步骤:
1. 确定中断源:确定要模拟的中断事件,比如外部输入的触发事件、定时器到达时间等。
2. 配置中断控制器:根据硬件平台和实验要求,配置中断控制器的相应寄存器,使其能够正确地处理中断信号。
3. 编写中断服务程序(ISR):定义一个中断服务程序,用于
处理中断事件。
ISR应当对事件进行必要的处理,然后返回到
原来的任务中。
4. 测试和调试:连接硬件平台,运行实验程序,并进行测试和调试,确保中断功能正常工作。
5. 扩展和优化:根据需要,可以进一步扩展和优化中断功能,比如增加多个中断源,实现优先级控制,提高系统响应速度等。
通过嵌入式中断实验,可以深入了解中断机制的工作原理和应用方法,提高对嵌入式系统的理解和能力。
嵌入式100题(77):中断怎么发生,中断处理大概流程
嵌⼊式100题(77):中断怎么发⽣,中断处理⼤概流程中断怎么发⽣,中断处理⼤概流程1. 中断概念:1. 中断是指由于接收到来⾃外围硬件(相对于中央处理器和内存)的异步信号或来⾃软件的同步信号,⽽进⾏相应的硬件/软件处理。
发出这样的信号称为进⾏中断请求(interrupt request,IRQ)。
硬件中断导致处理器通过⼀个上下⽂切换(context switch)来保存执⾏状态(以程序计数器和程序状态字等寄存器信息为主);软件中断则通常作为CPU指令集中的⼀个指令,以可编程的⽅式直接指⽰这种上下⽂切换,并将处理导向⼀段中断处理代码。
中断在计算机多任务处理,尤其是实时系统中尤为有⽤。
这样的系统,包括运⾏于其上的操作系统,也被称为“中断驱动的”(interrupt-driven)。
2. 中断是⼀种使CPU中⽌正在执⾏的程序⽽转去处理特殊事件的操作,这些引起中断的事件称为中断源,它们可能是来⾃外设的输⼊输出请求,也可能是计算机的⼀些异常事故或其它内部原因。
3. 中断:在运⾏⼀个程序的过程中,断续地以“插⼊”⽅式执⾏⼀些完成特定处理功能的程序段,这种处理⽅式称为中断。
2. 中断的作⽤:1. 并⾏操作2. 硬件故障报警与处理3. ⽀持多道程序并发运⾏,提⾼计算机系统的运⾏效率4. ⽀持实时处理功能3. 术语: 按中断源进⾏分类:发出中断请求的设备称为中断源。
按中断源的不同,中断可分为:1. 内中断:即程序运⾏错误引起的中断2. 外中断:即由外部设备、接⼝卡引起的中断3. 软件中断:由写在程序中的语句引起的中断程序的执⾏,称为软件中断 允许/禁⽌(开/关)中断: CPU通过指令限制某些设备发出中断请求,称为屏蔽中断。
从CPU要不要接收中断即能不能限制某些中断发⽣的⾓度,中断可分为:1. 可屏蔽中断:可被CPU通过指令限制某些设备发出中断请求的中断,那是不是意味着进中断时disable整个中断,其实disable的都是可屏蔽中断?2. 不可屏蔽中断:不允许屏蔽的中断如电源掉电 中断允许触发器:在CPU内部设置⼀个中断允许触发器,只有该触发器置“1”,才允许中断;置“0”,不允许中断。
嵌入式系统的异常和中断
大多数嵌入式处理器体系结构提供异常和中断机制,允许处理器中断正常的执行路径。
这个中断可能有应用软件有意的触发,或者由一个错误的、不寻常的条件或某些非计划的外部事件触发。
许多实时操作系统提供处理异常和中断的封装器功能,以便保护嵌入式系统开发者避开低层的细节。
这种应用编程层允许程序员把精力集中在必须处理的高层异常处理上,而不是在处理那些冗长的序言和结束语的系统层次上。
然而,当程序员从一个嵌入式应用程序员过渡到一个嵌入式系统程序员的时候,这种隔离可能产生误会并且变成一种障碍。
一、什么是异常和中断一个异常是指任何打断处理器正常执行,并且迫使处理器进入一个由有特权的特殊指令执行的事件。
异常可以分为两类:同步异常和异步异常。
由内部事件(像处理器指令运行产生的事件)引起的异常称为同步异常。
同步异常的例子包括下列各项:1.在某些处理器体系结构中,对于确定的数据尺寸必须从内存的偶数地址进行读和写操作。
从一个奇数内存地址的读或写操作将引起存储器存取一个错误事件并引起一个异常(称为校准异常)。
2.造成被零除的算术运算引发一个异常。
由外部事件(与处理器指令执行不相关的事件)引发的异常,称为异步异常。
一般,这些外部事件与硬件信号相关。
这些硬件信号典型的来源于外部硬件装置。
异步异常的例子包括下列各项:1.按下嵌入式板上的复位按钮,触发一个异步的异常(称为系统复位异常)。
2.另外一个外部设备的例子是,通信处理器模块已经成为许多嵌入式设计的一个完整部分,当它接收数据包时引发异步异常。
一个中断,有时称为一个外部中断,是一个由外部硬件装置产生的事件引起的异步异常。
中断是异常的一类。
中断区别于其它类型的异常,或更精确地说,同步异常区别于异步异常的地方是事件的来源。
同步异常事件是由于执行某些指令而从处理器内部产生的。
而异步异常事件的来源是外部硬件装置。
异常和中断是大多数嵌入式系统中必须存在的精灵。
这个设施是处理器体系结构特定的;如果误用,将成为混乱的设计源。
嵌入式实验 中断实验报告
嵌入式实验报告中断实验报告指导教师:高金山实验者:13410801 房皓13410802 张耀荣一、实验目的:1.理解中断向量表的结构2.理解中断处理的过程3.学习编写中断处理程序的方法二、实验要求:1.修改源程序,通过中断方式响应按键,当1-16键按下时,数码管显示0-F。
2.提高内容:以FIQ方式,替代IRQ方式,实现按下任何一个键,数码管显示按键号的功能。
三、实验内容:1.设计主程序,使8个LED以一定的时间间隔从右到左依次点亮,循环显示;(实验一的内容)2.当有键按下时,在七段数码管上,显示对应的16个键盘编码值 0-9 a-f(实验二、三的内容)四、程序编辑:;boot.sIMPORT postDelayIMPORT osStack;IMPORT post_initStackIMPORT init_StackIMPORT post_initGpioIMPORT post_initMemIMPORT post_initKeyIMPORT dummyOsIMPORT FIQ_HandlerIMPORT ICMRIMPORT init_ICMRIMPORT FIQIMPORT init_FIQ;IMPORT PSSRAREA boot ,CODE ,READONLYENTRYB Reset_HandlerB Undefined_HandlerB SWI_HandlerB Prefetch_HandlerB DataAbort_HandlerNOPB Reset_HandlerB FIQ_HandlerUndefined_HandlerB Undefined_HandlerSWI_HandlerB SWI_HandlerPrefetch_HandlerB Prefetch_HandlerDataAbort_HandlerB DataAbort_HandlerIRQ_HandlerB IRQ_Handler ;Defined by yourself Reset_Handler;*************************;Check if run in the SDRAM;*************************MOV R0,PCCMP R0,#0x0000003CBNE Stack;**************************;Init Memory;**************************mov r14,pc;ldr pc,=init_Memoryldr pc,=post_initMem;**************************;Init Stack;************************** Stackmov r14,pcldr pc,=init_Stack;ldr pc,=post_initStack;**************************;Init Gpio;**************************mov r14, pcldr pc, =post_initGpio;***************************;Enable & Set Interrupt;***************************mrs r1, CPSRbic r1, r1,#0x40msr CPSR_c, r1ldr r1, =ICMRldr r2, =init_ICMRstr r2,[r1]ldr r1, =FIQldr r2, =init_FIQstr r2, [r1];****************************;Init Keypad;****************************mov r14,pcldr pc,=post_initKey;***************************;Power Manager Sleep Status Register;***************************;ldr r1, =PSSR;mov r2, #0x30;str r2, [r1];***************************;Loop;***************************ldr r0,=postDelaypostLoopsub r0,r0,#0x1cmp r0,#0x0bne postLoopldr pc,=dummyOsEND;handler_IRQ.sIMPORT IRQ_Function;IMPORT ICMREXPORT FIQ_HandlerAREA FIQ_Handler,CODE,READONLY;****************************SUB LR, LR, #0x4STMFD SP!,{R0-R12,LR}BL IRQ_FunctionLDR R0,=0x41500000; by gaoLDR R1,[R0] ;by gaoLDMFD SP!,{R0-R12,PC}^;*******************************END;keypad.c#include <stdio.h>#include "register_variant.h"#define LED_CS2 (*((volatile unsigned short int *)(0x10300000))) //LED1 and LED2#define LED_CS3 (*((volatile unsigned short int *)(0x10400000))) //LED3 and LED4#define KPDK_VALUE (*((volatile unsigned char *)(0x41500008)))//Direct Keypad#define KPMK_VALUE (*((volatile unsigned char *)(0x41500020)))//Matrix Keypad#define LED_CS4 (*((volatile unsigned char *)(0x10500000)))#define LED_VALUE (0xff)void IRQ_Function(void){char i,j; //j by gaounsigned short int kbd_buff;i = KPDK_VALUE;switch (i){case 0x40: //key-press 1LED_CS2 = 0x8079;break;case 0x02: //key-press 2LED_CS2 =0x8024;break;case 0x04: //key-press 3LED_CS2 = 0x8030;break;case 0x20: //key-press 4LED_CS2 =0x8019;break;default: kbd_buff=0x8F8F; break;}i = KPMK_VALUE ;switch (i){case 0x00: //key-press 5LED_CS2 =0x8012;break;case 0x01: //key-press 6LED_CS2 = 0x8002;break;case 0x02: //key-press 7LED_CS2 =0x8078;break;case 0x05: //key-press 8LED_CS2 =0x8000;break;case 0x10: //key-press 9LED_CS2 =0x8010;break;case 0x11: //key-press 10LED_CS2 = 0x4079;break;case 0x12: //key-press 11LED_CS2 =0x7979;break;case 0x15: //key-press 12LED_CS2 =0x2479;break;case 0x20: //key-press 13LED_CS2 =0x3079;break;case 0x21: //key-press 14LED_CS2 = 0x1979;break;case 0x22: //key-press * 15 LED_CS2 =0x1279;break;case 0x25: //key-press # 16 LED_CS2 =0x0279;break;default: break;}}//int i;void Delay(unsigned int x){unsigned int i, j, k;for (i =0; i <=x; i++)for (j = 0; j <0xff; j++)for (k = 0; k <0xff; k++);}void button_statusFetch(void){char i = 0;unsigned short int kbd_buff;i = KPDK_VALUE ;switch (i){case 0x40: //key-press 1 LED_CS2 = 0x8079;break;case 0x02: //key-press 2 LED_CS2 =0x8024;break;case 0x04: //key-press 3 LED_CS2 = 0x8030;break;case 0x20: //key-press 4 LED_CS2 =0x8019;break;default: kbd_buff=0x8F8F; break;}}void button_statusFetch1(void){char i = 0;//unsigned short int kbd_buff;i = KPMK_VALUE ;switch (i){case 0x00: //key-press 5 LED_CS2 =0x8012;break;case 0x01: //key-press 6 LED_CS2 = 0x8002;break;case 0x02: //key-press 7 LED_CS2 =0x8078;break;case 0x05: //key-press 8 LED_CS2 =0x8000;break;case 0x10: //key-press 9LED_CS2 =0x8010;break;case 0x11: //key-press 10LED_CS2 = 0x4079;break;case 0x12: //key-press 11LED_CS2 =0x7979;break;case 0x15: //key-press 12LED_CS2 =0x2479;break;case 0x20: //key-press 13LED_CS2 =0x3079;break;case 0x21: //key-press 14LED_CS2 = 0x1979;break;case 0x22: //key-press * 15 LED_CS2 =0x1279;break;case 0x25: //key-press # 16 LED_CS2 =0x0279;break;default: break;}}void dummyOs(void){//int led_sharp;int temp=~0;int i;LED_CS2 = temp;LED_CS3 = temp;while(1){LED_CS4 = 0xff;for (i = 0; i < 8; i++){LED_CS4 = (LED_VALUE << i) -1;Delay(5);}//button_statusFetch();//Delay(10);// button_statusFetch1();// Delay(10);}}五、实验结果:程序运行时,实验箱上的八个LED灯在自左向右闪烁,当按下键盘上的按钮时,七段数码管吗会显示出对应的编码六、实验总结:通过本次实验,我锻炼了自己的操作能力,加深了对理论知识的理解,并对对中断工作方式有了初步的认识,理解了通过IRQ和FIQ两种不同的中断方式控制程序的运行的方法。
嵌入式系统中的中断处理
嵌入式系统中的中断处理在嵌入式系统中,中断处理是一项至关重要的任务。
中断是指由硬件或软件引发的事件,它打断了CPU的正常执行流程,需要在最短的时间内进行响应和处理。
本文将详细探讨嵌入式系统中的中断处理过程以及相关的技术和策略。
一、中断的概念与分类中断是指CPU接收到一个来自硬件或软件的信号,要求其立即停止正在执行的任务,转而执行一个与之相关的处理程序。
根据中断的来源,可以将中断分为硬件中断和软件中断两种类型。
硬件中断是由外设或内部电路触发的,它可以是定时器超时、外部设备请求等。
硬件中断一般由硬件电路直接与CPU相连,并通过电平或脉冲等信号进行触发。
软件中断是由软件指令触发的,它包括系统调用、异常、陷入等。
软件中断通常是由程序员通过编写相关的中断处理程序来触发和处理的。
二、嵌入式系统中的中断处理过程1. 中断请求与触发当一个中断事件发生时,外设或软件将向CPU发送一个中断请求信号。
CPU在接收到中断请求信号后,需要及时进行中断处理。
在硬件中,中断请求信号通常是通过IRQ(中断请求)引脚发送给CPU;在软件中,通过相关的指令将中断请求传递给CPU。
2. 中断响应与保存上下文CPU在接收到中断请求信号后,需要立即停止当前执行的指令,并保存当前正在执行的程序状态。
这个过程称为中断响应。
为了保存中断发生时的上下文环境,CPU会将当前的程序计数器PC、状态寄存器和一些重要的寄存器的值保存到特定的内存中,以便在中断处理结束后能够正确地恢复现场。
3. 中断处理程序的执行中断处理程序是用来处理中断事件的代码段,它通常被事先定义和初始化。
当中断响应完成后,CPU会跳转到对应的中断处理程序的入口地址开始执行。
中断处理程序根据中断类型进行相应的处理,可以包括读取和处理外设数据、更新系统状态、保存和恢复其他寄存器等操作。
4. 中断处理程序的结束与恢复现场在中断处理程序执行完毕后,CPU会根据程序计数器PC中保存的值,返回到中断发生前的执行状态,即恢复现场。
嵌入式中断的概念和流程
嵌入式中断的概念和流程
嘿,朋友们!今天咱来好好唠唠嵌入式中断这玩意儿。
那嵌入式中断到底是啥呢?就好比你正在家里悠哉地看电视呢,突然门铃响了,这门铃响就相当于中断啦!它会打断你正在做的事情,让你去处理这个新情况。
比如在一个智能设备里,本来它正好好运行着呢,结果来了个紧急信号,就像有人突然拍你一下说:“嘿,有急事!”这时候设备就得赶紧暂停原来的工作,先去处理这个中断。
那嵌入式中断的流程又是怎样的呢?就好像你准备出门,你得先听到门铃声,然后决定去开门,再跟门外的人交流,最后回来继续看电视。
在嵌入式系统里,首先会有一个中断源发出信号,系统就得察觉并接收这个信号,这就像听到门铃响了(比如传感器传来的数据异常啦)。
然后呢,系统要保存当前的状态,就像你赶紧暂停看电视,记住看到哪儿了。
接着,系统会执行对应的中断服务程序,这就好比去跟门外的人说话处理事情。
处理完后,系统再恢复之前的状态,你就又可以回来接着美滋滋地看电视啦。
比如说,你的手机正在播放音乐呢,这时候突然来了个紧急电话,手机不就得中断播放音乐,先去处理这个电话呗。
等电话打完了,又接着放音乐。
这就是嵌入式中断在日常生活中的实际例子啊!
嵌入式中断可重要啦!它就像个机灵的小管家,能让系统快速响应紧急情况,保证一切都能有条不紊地运行。
没了它,那系统可就乱套啦,说不定就会出大问题呢,就像你家没门铃,有人找你都不知道呀!所以说,嵌入式中断真是个神奇又重要的东西呢!。
arm嵌入式 中断注册函数
arm嵌入式中断注册函数关于ARM嵌入式中断注册函数在ARM嵌入式系统中,中断是一种非常重要的机制,它能够有效地提高系统的响应速度,允许在需要时立即响应某些特定事件。
中断通常由外设或者内核生成,并且它们的处理程序也是由软件编写的。
在ARM Cortex-M系列处理器中,中断的处理和管理是通过中断向量表来实现的。
中断向量表是一个包含了中断处理程序地址的表,每个中断都有一个对应的唯一的中断向量表项。
当一个中断发生时,处理器会在中断向量表中查找对应的中断向量表项,并从中取出对应的中断处理程序的地址,然后跳转到该地址执行中断处理程序。
在ARM嵌入式系统中,我们可以通过注册中断处理函数来定义中断的处理方式。
中断注册函数是负责将用户定义的中断处理函数的地址写入中断向量表中的函数。
在本文中,我们将详细介绍ARM嵌入式系统中的中断注册函数的实现步骤。
1. 确定中断号在注册中断处理函数之前,首先需要确定需要注册的中断号。
中断号是一个唯一标识每个中断的数字,它代表了中断向量表中的偏移量。
可以在处理器手册或者开发板的文档中找到相应的中断号编号。
2. 编写中断处理函数根据需要,编写具体的中断处理函数。
中断处理函数通常会执行一系列任务,如保存寄存器状态、处理中断发生的事件等。
在编写中断处理函数时,需要遵循一定的编程规范和要求,以确保中断的及时响应和正确处理。
3. 定义中断处理函数的地址在C/C++中,中断处理函数的地址可以通过函数指针来表示。
将中断处理函数定义为一个函数指针,可以方便地在后续的步骤中操作。
在定义中断处理函数的地址时,要注意函数指针的类型和中断处理函数的类型必须匹配。
4. 修改中断向量表中断向量表是一个位于特定内存位置的数组,用于存储中断处理函数的地址。
我们需要将中断处理函数的地址写入到对应中断号的中断向量表项中。
具体的实现方式可以通过直接修改内存中的中断向量表,或使用相关的指令来实现,如LDR和STR指令。
嵌入式中断控制实训报告
一、实训背景随着物联网、智能制造等领域的快速发展,嵌入式系统在各个行业中的应用日益广泛。
中断技术在嵌入式系统中扮演着至关重要的角色,它能够使系统在处理实时任务时更加高效、可靠。
为了提高学生对嵌入式中断技术的理解和应用能力,我们开展了此次嵌入式中断控制实训。
二、实训目的1. 理解中断的基本概念和原理;2. 掌握中断控制的基本方法;3. 学会使用中断进行实时任务处理;4. 提高嵌入式系统设计和开发能力。
三、实训内容本次实训主要分为以下几个部分:1. 中断基础知识- 介绍中断的概念、分类和作用;- 讲解中断处理流程,包括中断请求、中断响应、中断处理和中断返回;- 分析中断优先级和嵌套中断。
2. 中断控制- 学习使用C语言实现中断服务程序(ISR);- 掌握中断使能和禁用方法;- 熟悉中断触发方式和中断屏蔽;- 学会使用定时器中断实现周期性任务。
3. 嵌入式系统开发- 使用STM32F103C8T6微控制器作为实验平台;- 学习使用ST-Link进行程序下载和调试;- 掌握Keil MDK软件的使用;- 实现基于中断的LED闪烁、按键控制等应用。
4. 实验项目- 设计并实现一个基于定时器中断的LED闪烁程序;- 设计并实现一个基于按键中断的LED开关控制程序;- 设计并实现一个基于串口中断的数据传输程序。
四、实训过程1. 理论学习- 认真阅读教材和资料,理解中断的基本概念和原理;- 分析中断处理流程,掌握中断优先级和嵌套中断;- 学习使用C语言实现中断服务程序。
2. 实验操作- 搭建实验平台,连接STM32F103C8T6微控制器和外部设备;- 使用ST-Link下载程序,并使用Keil MDK进行调试;- 编写程序实现LED闪烁、按键控制等应用。
3. 项目开发- 分析项目需求,设计程序框架;- 编写代码实现项目功能;- 调试程序,确保程序正常运行。
五、实训结果1. 成功实现了基于定时器中断的LED闪烁程序,实现了LED灯以一定频率闪烁;2. 成功实现了基于按键中断的LED开关控制程序,实现了通过按键控制LED灯的开关;3. 成功实现了基于串口中断的数据传输程序,实现了上位机与单片机之间的数据交换。
nvic中断的工作原理和使用方法 -回复
nvic中断的工作原理和使用方法-回复NVIC(Nested Vectored Interrupt Controller)中断控制器是一种常见于嵌入式系统中的硬件模块,用于管理和分配系统中断。
在本文中,我们将详细介绍NVIC中断的工作原理和使用方法。
1. 中断的概念和作用:在嵌入式系统中,中断是一种重要的机制,用于处理来自外部设备或软件的异步事件。
中断可以让处理器立即暂停当前任务,转而处理更为紧急的事件,提高系统的响应能力和实时性。
NVIC中断控制器负责管理和分配中断,使系统能够有效地响应和处理中断事件。
2. NVIC中断控制器的组成:NVIC中断控制器由多个寄存器组成,其中包括以下几个重要的寄存器:- ISER(Interrupt Set Enable Register):用于设置或清除中断的使能位。
当某个中断使能位被设置时,表示该中断已经被使能,可以触发中断服务程序的执行。
- ICER(Interrupt Clear Enable Register):用于清除中断的使能位。
当某个中断使能位被清除时,表示该中断已经被禁止,不会触发中断服务程序的执行。
- ISPR(Interrupt Set Pending Register):用于设置中断的挂起位。
当某个中断挂起位被设置时,表示该中断已经被挂起,正在等待中断服务程序的执行。
- IPR(Interrupt Priority Register):用于设置中断的优先级。
不同中断的优先级不同,高优先级的中断会在低优先级中断之前得到响应和处理。
- IPSR(Interrupt Program Status Register):用于记录当前正在处理的中断号。
3. NVIC中断的工作原理:当外部设备或软件触发一个中断事件时,NVIC中断控制器会根据中断的优先级和使能状态来决定是否响应该中断。
若中断被使能且优先级高于当前正在处理的中断,NVIC中断控制器将触发中断,并根据中断号跳转到对应的中断服务程序(Interrupt Service Routine,ISR)。
嵌入式系统中设计中断服务程序的基本原则
一、介绍嵌入式系统中设计中断服务程序的背景及重要性嵌入式系统是一种特殊的计算机系统,它通常被用于嵌入在其他设备中,用来控制设备的运行和功能。
在嵌入式系统中,中断服务程序是一个非常重要的组成部分。
中断是一种机制,可以在系统执行某个任务的过程中,暂时中止当前任务的执行,转而去执行另一个任务。
中断服务程序是为了响应中断事件而设计的程序,它负责在中断发生时保存当前状态、执行相应的处理程序、然后恢复之前的状态,让被中断的任务能够继续执行。
二、中断服务程序的设计原则在设计嵌入式系统中的中断服务程序时,有一些基本的原则需要遵循,以保证系统的稳定性和可靠性。
1. 可重入性中断服务程序必须是可重入的。
这意味着这个程序可以在其中断的情况下被再次调用,而不会导致不可预测的错误。
这是因为在中断处理过程中,有可能会再次收到同样的中断信号。
如果中断服务程序不是可重入的,那么当它正在执行时再次被调用,就会发生错误。
2. 快速响应中断服务程序必须能够迅速响应中断事件。
在某些情况下,中断的响应时间对系统的性能和稳定性有很大影响。
设计中断服务程序时需要尽量减少其执行时间,以确保系统能够及时处理中断事件。
3. 最小化对全局变量的使用中断服务程序应尽量避免使用全局变量。
这是因为在中断服务程序执行过程中,有可能会发生并发访问全局变量的情况,从而导致数据一致性问题。
为了避免这种情况,可以在中断服务程序中使用局部变量或者禁止中断的方式来保护全局变量。
4. 合理的优先级在设计中断服务程序时,还需要考虑中断的优先级。
不同的中断事件可能有不同的优先级,需要根据实际情况来进行合理的设置。
这样可以确保系统能够在不同的中断事件发生时能够按照一定的顺序来处理。
5. 状态保存和恢复在中断服务程序中,需要及时保存当前任务的状态,以便在处理完中断事件后能够恢复到之前的状态并继续执行。
这也是中断服务程序的一个重要功能,需要在设计中充分考虑。
6. 可靠性和稳定性在设计中断服务程序时,需要考虑系统的可靠性和稳定性。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
福建电脑2012年第12期浅谈嵌入式中断处理郑德利(石家庄市职业技术教育中心计算机专业部河北石家庄050090)【摘要】:中断处理的效率高低直接影响着整个嵌入式系统的工作效率。
从源代码的角度,详细叙述了基于XScale PXA255处理器的嵌入式Linux操作系统的中断处理的整个流程。
【关键词】:中断处理;嵌入式;XScale PXA2551、引言一个完美的嵌入式系统与其中断处理机制是分不开的,没有中断处理的嵌入式系统不是真正意义上的嵌入式系统。
近年来,Intel公司生产的基于ARM体系结构的XScale系列处理器应用越来越广,本文以XScale PXA255处理器为例,从内核源代码的角度详细分析该系统的中断处理机制。
2、ARM系列处理器中断处理的定义当正常的程序执行流程发生暂时的停止时,称之为异常。
对于ARM体系结构的处理器来说,所支持的异常类型有七种,按处理的优先级从高到低分别为复位、数据中止、FIQ、IRQ、预取指令中止、SWI(也称软中断)和未定义指令。
其中,FIQ (Fast Interrupt Request)异常是为了支持快速数据传输或者通道处理而设计的,可由外部通过对处理器的nFIQ引脚输入低电平并且在当前程序状态寄存器CPSR(Current Program Staus Register)中的F位为0的时候来产生。
IRQ(Interrupt Re-quest)异常属于正常的中断请求,是我们常指的通常意义上的外部中断,可通过对处理器的nIRQ 引脚输入低电平并且在CPSR中的I位为0时来产生,系统的外部设备都是通过该异常请求中断服务。
这两个异常处理基本构成了整个系统的中断处理,是本文所讨论研究的重点。
3、中断的初始化在嵌入式Linux中,对中断的初始化必不可少的,下面就对系统中的常用的外部中断IRQ的初始化过程进行讨论。
系统经过BootLoader启动后,先运行init目录里面的main.c,该文件中的函数asmlinkage void __init start_kernel(void)调用了init_IRQ(),其中init_IRQ()函数的执行流程如图1。
从图1里可以看出,先初始化irq_desc[]数据结构,即中断请求描述块。
该数据结构描述了每一条中断线的情况。
为了减少系统中断源过多而中断线少之间的矛盾,可以通过连接一些门电路来解决,也就是一条中断线可能对应多个中断源。
irq_desc[NR_IRQS]这个结构体包含了系统内核能支持的所有的中断线的情况。
在这个结构体中,还定义了一个irqaction结构体(struct irqaction*ac-tion)。
irqaction是描述具体中断服务程序的描述,它会根据系统里各个驱动程序的初始化而被irq_desc设置。
init_arch_irq()是一个全局的函数指针,其在函数setup_arch()已经设置好的。
在PX-A255处理器中对应的是static void__init xhy-per255_init_irq(void),该函数源代码如下:static void__init xhyper255_init_irq(void){pxa_init_irq();set_GPIO_IRQ_edge(0,GPIO_RISING_EDGE);/*Ethernet Interrupt*/#ifdef CONFIG_ARCH_XHYPER255Bset_GPIO_IRQ_edge(IRQ_TO_GPIO_2_80(IRQ_GPI-O_ADS7843),GPIO_FALLING_EDGE);/*ADS7843touch controller*/set_GPIO_IRQ_edge(IRQ_TO_GPIO_2_80(IRQ_GPI-O_EZHOST),GPIO_FALLING_EDGE);/*EZ-Host USB HOST controller*/set_GPIO_IRQ_edge(IRQ_TO_GPIO_2_80(IRQ_GPIO_EX-TEND),GPIO_RISING_EDGE);/*fpga board interrupt*/#elif defined(CONFIG_ARCH_XHYPER255A)set_GPIO_IRQ_edge(IRQ_TO_GPIO_2_80(IRQ_GPI-O_ADS7843),GPIO_FALLING_EDGE);图1init_IRQ()流程76/*ADS7843touch controller*/#endif}由上面函数可以看到,先是pxa_init_irq(),再初始化网口,触摸屏,USB主控器和FPGA扩展板的四个外部中断。
该函数可以根据实际开发时的需要对初始化的外部中断进行增减。
在px-a_init_irq()函数中,先屏蔽掉所有的中断,然后再设置所有的中断为IRQ而不是FIQ,最后设置irq_desc[]数据结构。
该中断响应的框架完成以后,设备驱动程序就可以通过函数request_irq()将具体的中断处理程序跟其对应的中断请求号对应。
其处理过程是首先分配一个irqaction的结构体,将有关的参数写到结构体中,然后通过set-up_arm_irq()将其放入指定中断请求线irqaction 数据结构队列,最后进行DMA初始化。
4、PXA255处理器对中断源的识别及处理当有中断发生时,PXA255处理器是通过两个步骤确定中断源类型。
PXA255处理器对中断源的识别流程如图2所示。
从图2中可以看出,第一步是中断请求线In-terrupt Source Bit先保存在中断未决寄存器ICPR (Interrupt Pending Register),然后中断再根据屏蔽寄存器ICMR(Interrupt MASR Register)决定是否处理。
随后,中断级别寄存器ICLR(Interrupt Level Register)再根据本身内部的数据来控制将第一步处理的中断源信号保存到寄存器ICIP (IRQ Interrupt Pending Register)或者ICFP(FIQ Interrupt Pending Register),某位为0时保存到ICIP,为1时保存到ICFP。
当CPU收到中断请求以后,可以根据中断的种类来进入IRQ或者FIQ 的中断响应程序,再根据ICIP和ICFP的内容进一步确定中断源,最后进入具体的中断服务程序。
在基于ARM体系结构的处理器中,异常向量(Exception Vectors)的地址都是系统设定好的,IRQ的异常向量地址为0x00000018,发生异常后处理器将进入IRQ模式。
FIQ的异常向量地址为0x0000001C,发生异常后处理器将进入FIQ模式。
下面分析外部中断IRQ的中断响应过程。
当一个外部中断IRQ出现时,在中断响应之初,CPU会完成下面的操作。
(1)将下一条指令的地址存入相应的连接寄存器LR,即存入R14_IRQ,以便程序在处理中断返回时能从正确的位置重新开始执行。
若中断是从ARM状态进入,LR寄存器中保存的是下一条指令的地址(当前程序计数器PC+4);若中断是从Thumb状态进入,则在LR寄存器中保存当前PC 的偏移量,这样,中断处理程序就不需要确定中断是从何种状态进入的。
(2)将当前程序状态寄存器CPSR复制到相应的备份程序状态寄存器SPSR(Saved Program-Status Register),即装入寄存器SPSR_IRQ。
(3)同时强制改变CPSR的运行模式位使CPU运行在相应的IRQ模式,并关闭进一步的中断。
并且堆栈指针SP切换成SP_IRQ。
(4)强制PC从相关的中断向量地址取下一条指令运行,就是使PC指向0x00000018,而在这个位置处的指令是一条跳转指令,跳转到相应的中断处理程序处。
如果中断发生的时候,处理器处于Thumb状态,则当中断向量地址加载到PC时,处理器会自动切换到ARM状态。
CPU做完上述工作以后,就会进入中断响应程序的总入口vector_IRQ,先暂时保存中断时的LR和SPSR_IRQ到__temp_irq,CPU在中断模式IRQ做完上述保护工作以后就切换到管理模式SVC模式,开始了真正意义上的中断响应。
进入SVC模式以后,CPU就工作在系统态中。
首先是保存中断现场,并把R0-R12寄存器的内容保存在系统态堆栈中,然后把原来暂存在__temp_irq的LR和SPSR_IRQ也加以保存,最后保存SP和PC。
随后,用宏操作get_irqnr_and_base 来测试中断状态寄存器,测试的方法与具体的硬件有关,得到中断源号码,接着设置R1指向堆栈的中断现场的起点,然后使LR指向宏操作get_irqnr_and_base起点,接着就是执行中断处理函数do_IRQ(),这个函数主要功能是对中断的处理,中断的分发,中断服务程序的调用等。
这个函数返回的并不是下一条指令的起点,而是宏操作get_irqnr_and_base的起点。
这样(下转第135页)图2PXA255对中断源的识别流程(上接第77页)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!CPU在处理函数do_IRQ()后就又再次执行get_irqnr_and_base,形成了一个循环。
这样,只要中断寄存器中还有中断请求,get_irqnr_and_base 返回的中断源号码就是非0,于是再一次调用函数do_IRQ(),直到中断状态寄存器中没有中断请求,循环就结束了。
5、中断的返回中断处理完后,一般分下面几步返回:(1):将连接寄存器LR的值减去相应的偏移量后送到PC。
(2):将相应的SPSR复制回CPSR。
(3):若在进入中断处理时设置了中断禁止位,则要清除。
对于PXA255处理器,具体的返回过程如下(仍然以IRQ中断为例):因为IRQ中断属于外部中断,是在用户态下面发生的中断,所以在中断返回时候可能要涉及到进程的调度,因此会调用函数current_task tsk来使R9指向当前进程的控制块,然后执行ret_to_user,看是否需要调度,如果需要就加以执行,再检查当前进程是否收到信号,如果收到就加以处理。
最后,堆栈指针SP指向内核态堆栈框架的底部,恢复原来保存的各个寄存器的值,并且使系统态的堆栈指针SP恢复到原来的位置。
然后使LR的值减去4送到PC,使SP-SR_SVC寄存器的内容送回到CPSR中,清除原来的禁止了的中断位,这样就使CPU从系统态切换回用户态。
6、结论中断机制是一个完整的操作系统必不可少的一部分,跟底层硬件关系非常密切。
研究中断机制对理解整个嵌入式系统很有帮助。