嵌入式中的中断问题

上传人:M****1 文档编号:563333011 上传时间:2023-09-04 格式:DOCX 页数:18 大小:318.14KB
返回 下载 相关 举报
嵌入式中的中断问题_第1页
第1页 / 共18页
嵌入式中的中断问题_第2页
第2页 / 共18页
嵌入式中的中断问题_第3页
第3页 / 共18页
嵌入式中的中断问题_第4页
第4页 / 共18页
嵌入式中的中断问题_第5页
第5页 / 共18页
点击查看更多>>
资源描述

《嵌入式中的中断问题》由会员分享,可在线阅读,更多相关《嵌入式中的中断问题(18页珍藏版)》请在金锄头文库上搜索。

1、原文地址:C语言中关于中断的问题(嵌入式)前提:中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展让标 准C支持中断。具代表事实是,产生了一个新的关键字interrupt。下面的代码就使用了 interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。_interrupt double compute_area (double radius)double area = PI * radius * radius;printf( Area = %f, area);return area;这个函数有太多的错误了,以至让人不知从何说起了:1) . ISR 不能

2、返回一个值。2) . ISR 不能传递参数。3) . 在许多的处理器/编译器中,浮点一般都是不可重入的。有些处理器/编译器需要让额处 的寄存器入栈,有些处理器/编译器就是不允许在ISR中做浮点运算。此外,ISR应该是短 而有效率的,在ISR中做浮点运算是不明智的。4) .与第三点一脉相承,printf()经常有重入和性能上的问题。对于printf()经常有重入和性能上的问题的理解: 由于存在任务的调度,它实时系统,可剥夺型内核中是危险的,如同一个安静的水雷。可能 会被触发,也可能安然无恙。由于它运行结果的不可预期性,会使系统带来隐患。下面引用一段别人的解释:这主要在多任务环境中使用,一个可重入

3、的函数简单来说,就是:可以被中断的函数。就是 说,你可以在这个函数执行的任何时候中断他的运行,在OS的调度下去执行另外一段代码 而不会出现什么错误。而不可重入的函数由于使用了一些系统资源,比如全局变量区,中断 向量表等等,所以他如果被中断的话,可能出现问题,所以这类函数是不能运行在多任务环 境下的。把一个不可重入函数变成可重入的唯一方法是用可重入规则来重写他。其实很简单,只要遵守了几条很容易理解的规则,那么写出来的函数就是可重入的。第一,不要使用全局变量。因为别的代码很可能覆盖这些变量值。第二,在和硬件发生交互的时候,切记执行类似disinterrupt()之类的操作,就是关闭硬件中 断。 完

4、成交互记得打开中断, 在有些系列上, 这叫做“进入/退出核心”或者用 OS_ENTER_KERNAL/OS_EXIT_KERNAL 来描述。第三,不能调用任何不可重入的函数。第四,谨慎使用堆栈。最好先在使用前先OS_ENTER_KERNAL。还有一些规则,都是很好理解的,总之,时刻记住一句话:保证中断是安全的!通俗的来讲吧:由于中断是可能随时发生的,断点位置也是无法预期的。所以必须保证每个 函数都具有不被中断发生,压栈,转向ISR,弹栈后继续执行影响的稳定性。也就是说具有 不会被中断影响的能力。既然有这个要求,你提供和编写的每个函数就不能拿公共的资源或 者是变量来使用,因为该函数使用的同时,I

5、SR (中断服务程序)也可那会去修改或者是获 取这个资源,从而有可能使中断返回之后,这部分公用的资源已经面目全非。满足下列条件的函数多数是不可重入的:(1) 函数体内使用了静态的数据结构;(2) 函数体内调用了 malloc()或者free()函数;(3) 函数体内调用了标准I/O函数。下面举例加以说明。可重入函数void strcpy(char* lpszDest, char* lpszSrc)while(*lpszDest = *lpszSrc );*dest=0;非可重入函数1char cTemp; / 全局变量void SwapChar1(char* lpcX, char* lpcY)

6、cTemp = *lpcX;*lpcX = *lpcY;lpcY = cTemp; / 访问了全局变量,在分享内存的多个线程中可能造成问题非可重入函数2void SwapChar2(char* lpcX, char* lpcY)static char cTemp; / 静态局部变量cTemp = *lpcX;*lpcX = *lpcY;lpcY = cTemp; / 使用了静态局部变量,在分享内存的多个线程中可能造成问题如何写出可重入的函数? 在函数体内不访问那些全局变量,不使用静态局部变量,坚持只使用局部变量,写出的函数 就将是可重入的。如果必须访问全局变量,记住利用互斥信号量来保护全局变量

7、。 近来在 LPC 的中断过程上看了点文献,作为一个初学者感觉这个内容与其它的处理器还是 有很大的区别,比如说三星的S3C4510B,两者在中断的处理上理念是完全不同的,个人感 觉LPC的要难一些,很多地方感觉上是在和ARM的规范打擦边球,下面具体说一下相关 内容。基础知识:LPC2294 的 EXT 中断分为了三类,包括FIQ, Vectored IRQ,non- Vectored IRQ 其中,以FIQ的优先级最高,而以non- Vectored IRQ的优先级最低,系统一共提供了 27 个中断源,并且给这27 个中断源进行了固定的编号,但是注意,这个编号和优先级没有任 何的关系,并非是编

8、号在前面的优先级就越高,见下面说明。关键内容:两套控制渠道,第一套:在ARM体系中,本来有SWI,FIQ,IRQ等这些中断的定义,并且已经定义了这 些中断的开关控制位,就是在CPSR寄存器中,该寄存器包含了一个I位和一个F位,I位 用于控制IRQ中断的开关,F用于控制FIQ的开关,但是值得注意的是CPSR的读取和修 改在用户模式下是不能完成的,必须要通过SWI指令进入到特权模式下才可以进行修改。第二套:在LPC的SFR(特殊功能寄存器)中,也提供了一套寄存器用于控制相应的中断 的进行,这组控制器叫做VIC寄存器(都以VIC开头),改组寄存器包括了所有的与中断有 关的设置,开启,分类等功能,仅仅

9、是将外部中断引脚对应的部分功能分离出去,由 EXT 系列的寄存器来处理,因此,对这一个系列的寄存器的掌握是非常重要的!两者间的关系:仅仅在第二套控制渠道下打开FIQ, IRQ中断是不够的,如果ARM内核没 有开中断的话,整个系统就不会有中断产生,因此,常见的做法是这样:先将第二套渠道的 控制内容处理好,然后通过SWI软件中断指令,将ARM处理器的模式切换为特权模式, 在特权模式下,对CPSR进行“读出一修改一写回”的操作,将中断打开,然后在返回到用 户模式。LPC的中断的特殊性:FIQ的中断和普通的ARM规定是没有任何区别的,即是在产生中断 时,指令跳转到OxOOOOOOlC处开始执行,这个是

10、没有什么疑问的。但是IRQ的响应过程就 不同了,先看下面一段代码,这个是写在程序的头部的部分字节:ResetLDRPC, ResetAddr;/ 0x00000000, Reset-Supervisor ModeLDRPC, Und_Addr;/ 0x00000004, Undefined Instruction-Undefined ModeLDRPC, SWI_Addr;/ 0x00000008, Software Interrupt-Supervisor ModeLDRPC, PAbort_Addr;/ 0x0000000c, Abort(Prefetch)-Abort ModeLDRPC

11、, DAbort_Addr;/ 0x000000l0, Abort(Data)-Abort ModeDCD 0xB9205F80;/ 0x00000014,Reserved -LDRPC, PC,#-0xFF0;/ 0x00000018,IRQ-IRQ ModeLDRPC, FIQ_Addr;/ 0x0000001c,FIQ指令为“LDRPC, PC,#-OxFFO”非常特殊,其并没有跳转到IRQ中断程序的入口处,而是进行了一个PC 的运算后赋值,这里就要说明其缘由。在LPC系列中,IRQ的响应过程,程序的入口地址 并不是直接写在这条语句中,而是放在一个寄存器中,该寄存器是:VICVectAd

12、dr,其地址 是OxFFFFFO3O,现在就很明白了,在执行语句“LDRPC, PC,#-0xFF0”时,PC的值已经变为该语句的后面第二条语句的地址了,也就是 0x00000020,而0x00000020OxFFO时,发生借位,其结果恰好为OxFFFFFO3O,也就是说, 通过这个简单的运算,使PC跳转到了寄存器VICVectAddr中包含的值为地址的位置上,这 样就简单的完成了 IRQ的跳转。当然,IRQ中断源不止一个,其中断服务程序也不止一个,这个寄存器的值是自动更新的, 另有一组寄存器VICVectAddr015 (后面有数字)将IRQ的16个中断源的地址分别放在对 应的位置上(优先级

13、等内容有另外的寄存器来控制,这里不多说)当IRQ中断发生时,硬 件自动将对应的VICVectAddr015中的某个对应的地址传给VICVectAddr寄存器,这个过 程不用我们来编程实现。原文链接:http:/ 在 ARM 移植中的中断处理uCOS II 是一个源码公开、可移植、可固化、可剪裁和抢占式的实时多任务操作系统,其大 部分源码是用ANSI C编写,与处理器硬件相关的部分使用汇编语言编写。总量约200行的 汇编语言部分被压缩到最低限度,以便于移植到任何一种其它的CPU上。uCOS II 最多可支持56个任务,其内核为占先式,总是执行就绪态的优先级最高的任务,并 支持Semaphore

14、(信号量)、Mailbox (邮箱)、MessageQueue(消息队列)等多种常用的进程 间通信机制。与大多商用RTOS不同的是,uCOS II公开所有的源代码并可以免费获得, 只对商业应用收取少量License费用。uCOS II移植跟OS_CUP_C.C、OS_CPU_A.S、OS_CPU.H 3个文件有关,中断处理的移 植占据了很大一部分内容。作为移植的一个重点,本文以标准中断(IRQ)为例讨论了移植中 的中断处理。1 uCOS II系统结构uCOS II 的软硬件体系结构如图1。应用程序处于整个系统的顶层.每个任务都可以认为自己 独占了 CPU,因而可以设计成为一个无限循环。大部分代

15、码是使用ANSI C语言书写的, 因此uCOS II的可移植性较好。尽管如此,仍然需要使用C和汇编语言写一些处理器相关 的代码。uCOS II的移植需要满足以下要求:1) 处理器的C编译器可以产生可重入代码:可以使用C调用进入和退出CriTIcal Code(临界 区代码);2) 处理器必须支持硬件中断,并且需要一个定时中断源;3) 处理器需能容纳一定数据的硬件堆栈;4) 处理器需有能在CPU寄存器与内存和堆栈交换数据的指令。移植uCOS II的主要工作就是处理器和编译器相关代码以及BSP(Board Support Package) 的编写。uCOS II处理器无关的代码提供uCOS II的系统服务,应用程序可以使用这些API 函数进行内存管理、任务间通信以及创建、删除任务等。2 uCOS II移植过程中需要注意的几个问题uCOS II移植的中断处理跟ARM体系结构和uCOS II处理中断的过程有关,必须注意这2 个方面的问题才能高效移植。2.1 ARM 处理器7种操作模式用户模式(USER MODE)是ARM通常执行状态,用于执行大

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 学术论文 > 其它学术论文

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号