嵌入式中的中断问题Word文档下载推荐.docx
- 文档编号:13278799
- 上传时间:2022-10-09
- 格式:DOCX
- 页数:19
- 大小:468KB
嵌入式中的中断问题Word文档下载推荐.docx
《嵌入式中的中断问题Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《嵌入式中的中断问题Word文档下载推荐.docx(19页珍藏版)》请在冰豆网上搜索。
returnarea;
}
这个函数有太多的错误了,以至让人不知从何说起了:
1).ISR不能返回一个值。
2).ISR不能传递参数。
3).在许多的处理器/编译器中,浮点一般都是不可重入的。
有些处理器/编译器需要让额处的寄存器入栈,有些处理器/编译器就是不允许在ISR中做浮点运算。
此外,ISR应该是短而有效率的,在ISR中做浮点运算是不明智的。
4).与第三点一脉相承,printf()经常有重入和性能上的问题。
对于printf()经常有重入和性能上的问题的理解:
由于存在任务的调度,它实时系统,可剥夺型内核中是危险的,如同一个安静的水雷。
可能会被触发,也可能安然无恙。
由于它运行结果的不可预期性,会使系统带来隐患。
下面引用一段别人的解释:
这主要在多任务环境中使用,一个可重入的函数简单来说,就是:
可以被中断的函数。
就是说,你可以在这个函数执行的任何时候中断他的运行,在OS的调度下去执行另外一段代码而不会出现什么错误。
而不可重入的函数由于使用了一些系统资源,比如全局变量区,中断向量表等等,所以他如果被中断的话,可能出现问题,所以这类函数是不能运行在多任务环境下的。
把一个不可重入函数变成可重入的唯一方法是用可重入规则来重写他。
其实很简单,只要遵守了几条很容易理解的规则,那么写出来的函数就是可重入的。
第一,不要使用全局变量。
因为别的代码很可能覆盖这些变量值。
第二,在和硬件发生交互的时候,切记执行类似disinterrupt()之类的操作,就是关闭硬件中断。
完成交互记得打开中断,在有些系列上,这叫做“进入/退出核心”或者用OS_ENTER_KERNAL/OS_EXIT_KERNAL来描述。
第三,不能调用任何不可重入的函数。
第四,谨慎使用堆栈。
最好先在使用前先OS_ENTER_KERNAL。
还有一些规则,都是很好理解的,总之,时刻记住一句话:
保证中断是安全的!
通俗的来讲吧:
由于中断是可能随时发生的,断点位置也是无法预期的。
所以必须保证每个函数都具有不被中断发生,压栈,转向ISR,弹栈后继续执行影响的稳定性。
也就是说具有不会被中断影响的能力。
既然有这个要求,你提供和编写的每个函数就不能拿公共的资源或者是变量来使用,因为该函数使用的同时,ISR(中断服务程序)也可那会去修改或者是获取这个资源,从而有可能使中断返回之后,这部分公用的资源已经面目全非。
满足下列条件的函数多数是不可重入的:
(1)函数体内使用了静态的数据结构;
(2)函数体内调用了malloc()或者free()函数;
(3)函数体内调用了标准I/O函数。
下面举例加以说明。
可重入函数
voidstrcpy(char*lpszDest,char*lpszSrc)
while(*lpszDest=*lpszSrc);
*dest=0;
非可重入函数1
charcTemp;
//全局变量
voidSwapChar1(char*lpcX,char*lpcY)
cTemp=*lpcX;
*lpcX=*lpcY;
lpcY=cTemp;
//访问了全局变量,在分享内存的多个线程中可能造成问题
非可重入函数2
voidSwapChar2(char*lpcX,char*lpcY)
staticcharcTemp;
//静态局部变量
//使用了静态局部变量,在分享内存的多个线程中可能造成问题
如何写出可重入的函数?
在函数体内不访问那些全局变量,不使用静态局部变量,坚持只使用局部变量,写出的函数就将是可重入的。
如果必须访问全局变量,记住利用互斥信号量来保护全局变量。
近来在LPC的中断过程上看了点文献,作为一个初学者感觉这个内容与其它的处理器还是有很大的区别,比如说三星的S3C4510B,两者在中断的处理上理念是完全不同的,个人感觉LPC的要难一些,很多地方感觉上是在和ARM的规范打擦边球,下面具体说一下相关内容。
基础知识:
LPC2294的EXT中断分为了三类,包括FIQ,VectoredIRQ,non--VectoredIRQ,其中,以FIQ的优先级最高,而以non--VectoredIRQ的优先级最低,系统一共提供了27个中断源,并且给这27个中断源进行了固定的编号,但是注意,这个编号和优先级没有任何的关系,并非是编号在前面的优先级就越高,见下面说明。
关键内容:
两套控制渠道,
第一套:
在ARM体系中,本来有SWI,FIQ,IRQ等这些中断的定义,并且已经定义了这些中断的开关控制位,就是在CPSR寄存器中,该寄存器包含了一个I位和一个F位,I位用于控制IRQ中断的开关,F用于控制FIQ的开关,但是值得注意的是CPSR的读取和修改在用户模式下是不能完成的,必须要通过SWI指令进入到特权模式下才可以进行修改。
第二套:
在LPC的SFR(特殊功能寄存器)中,也提供了一套寄存器用于控制相应的中断的进行,这组控制器叫做VIC寄存器(都以VIC开头),改组寄存器包括了所有的与中断有关的设置,开启,分类等功能,仅仅是将外部中断引脚对应的部分功能分离出去,由EXT系列的寄存器来处理,因此,对这一个系列的寄存器的掌握是非常重要的!
两者间的关系:
仅仅在第二套控制渠道下打开FIQ,IRQ中断是不够的,如果ARM内核没有开中断的话,整个系统就不会有中断产生,因此,常见的做法是这样:
先将第二套渠道的控制内容处理好,然后通过SWI软件中断指令,将ARM处理器的模式切换为特权模式,在特权模式下,对CPSR进行“读出-修改-写回”的操作,将中断打开,然后在返回到用户模式。
LPC的中断的特殊性:
FIQ的中断和普通的ARM规定是没有任何区别的,即是在产生中断时,指令跳转到0x0000001C处开始执行,这个是没有什么疑问的。
但是IRQ的响应过程就不同了,先看下面一段代码,这个是写在程序的头部的部分字节:
Reset
LDR
PC,ResetAddr
;
//0x00000000,Reset
--->
SupervisorMode
PC,Und_Addr
//0x00000004,UndefinedInstruction
UndefinedMode
PC,SWI_Addr
//0x00000008,SoftwareInterrupt
PC,PAbort_Addr
//0x0000000c,Abort(Prefetch)
AbortMode
PC,DAbort_Addr
//0x00000010,Abort(Data)
DCD
0xB9205F80
//0x00000014,Reserved
PC,[PC,#-0xFF0]
//0x00000018,IRQ
IRQMode
PC,FIQ_Addr
//0x0000001c,FIQ
指令为“LDR
PC,[PC,#-0xFF0]”非常特殊,其并没有跳转到IRQ中断程序的入口处,而是进行了一个PC的运算后赋值,这里就要说明其缘由。
在LPC系列中,IRQ的响应过程,程序的入口地址并不是直接写在这条语句中,而是放在一个寄存器中,该寄存器是:
VICVectAddr,其地址是0xFFFFF030,现在就很明白了,在执行语句“LDR
PC,[PC,#-0xFF0]”时,PC的值已经变为该语句的后面第二条语句的地址了,也就是0x00000020,而0x00000020-0xFF0时,发生借位,其结果恰好为0xFFFFF030,也就是说,通过这个简单的运算,使PC跳转到了寄存器VICVectAddr中包含的值为地址的位置上,这样就简单的完成了IRQ的跳转。
当然,IRQ中断源不止一个,其中断服务程序也不止一个,这个寄存器的值是自动更新的,另有一组寄存器VICVectAddr0~15(后面有数字)将IRQ的16个中断源的地址分别放在对应的位置上(优先级等内容有另外的寄存器来控制,这里不多说),当IRQ中断发生时,硬件自动将对应的VICVectAddr0~15中的某个对应的地址传给VICVectAddr寄存器,这个过程不用我们来编程实现。
原文链接:
uCOS-II在ARM移植中的中断处理
uCOSII是一个源码公开、可移植、可固化、可剪裁和抢占式的实时多任务操作系统,其大部分源码是用ANSIC编写,与处理器硬件相关的部分使用汇编语言编写。
总量约200行的汇编语言部分被压缩到最低限度,以便于移植到任何一种其它的CPU上。
uCOSII最多可支持56个任务,其内核为占先式,总是执行就绪态的优先级最高的任务,并支持Semaphore(信号量)、Mailbox(邮箱)、MessageQueue(消息队列)等多种常用的进程间通信机制。
与大多商用RTOS不同的是,uCOSII公开所有的源代码.并可以免费获得,只对商业应用收取少量License费用。
uCOSII移植跟OS_CUP_C.C、OS_CPU_A.S、OS_CPU.H3个文件有关,中断处理的移植占据了很大一部分内容。
作为移植的一个重点,本文以标准中断(IRQ)为例讨论了移植中的中断处理。
1uCOSII系统结构
uCOSII的软硬件体系结构如图1。
应用程序处于整个系统的顶层.每个任务都可以认为自己独占了CPU,因而可以设计成为一个无限循环。
大部分代码是使用ANSIC语言书写的,因此uCOSII的可移植性较好。
尽管如此,仍然需要使用C和汇编语言写一些处理器相关的代码。
uCOSII的移植需要满足以下要求:
1)处理器的C编译器可以产生可重入代码:
可以使用C调用进入和退出CriTIcalCode(临界区代码);
2)处理器必须支持硬件中断,并且需要一个定时中断源;
3)处理器需能容纳一定数据的硬件堆栈;
4)处理器需有能在CPU寄存器与内存和堆栈交换数据的指令。
移植uCOSII的主要工作就是处理器和编译器相关代码以及BSP(BoardSupportPackage)的编写。
uCOSII处理器无关的代码提供uCOSII的系统服务,应用程序可以使用这些API函数进行内存管理、任务间通信以及创建、删除任务等。
2uCOSII移植过程中需要注意的几个问题
uCOSII移植的中断处理跟ARM体系结构和uCOSII处理中断的过程有关,必须注意这2个方面的问题才能高效移植。
2.1ARM处理器7种操作模式
用户模式(USERMODE)是ARM通常执行状态,用于执行大多数应用程序;
快速中断模式(FIQMODE)支持
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 嵌入式 中的 中断 问题
![提示](https://static.bdocx.com/images/bang_tan.gif)