rSRCPND=BIT_EINT0 是把相应的打印位置 置零 514置0了还是置1了 ?

2410学习笔记_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
2410学习笔记
上传于||暂无简介
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩13页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢1063人阅读
TX2440 看手册学习2440-深入理解中断处理机制(ADS1.2编译)
在中断控制器中有五个控制寄存器:中断源未决寄存器,中断模式寄存器,屏蔽寄存器,优先级寄存器和中断未决寄存器.
一.支持60个中断源:
中断源未决寄存器:一个SRCPND中断源未决寄存器只有32位,是根本不够放60个中断源的.所以三星公把一些相似的中断源放到另外一些寄存器里成为一组,给这些组员集合定一个组名放到SRCPND中断源未决寄存器里.如:外部中断4-7,共有4个中断源,它们的组名在SRCPND中断源未决寄存器里叫做EINT4_7.看下图:
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 图(1)
二.中断的优先级:
优先级寄存器:通过设置寄存器PRIORITY配置参数.
如图(1)所示.把这32个主中断源分6个一级仲裁器,而又把这6个一级仲裁器组成1个二级仲裁器,加起来总共有7个仲裁器,如图(2),每个仲裁器都有配置优先规则.
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 图(2)
每个仲裁器基于一个位仲裁器模式控制(ARB_MODE)和选择控制信号(ARB_SEL)的
两位来处理6 个中断请求。
如果 ARB_SEL位是 00b ,优先级是 REQ0 ,REQ1 ,REQ2 ,REQ3 ,REQ4 ,和REQ5.
如果 ARB_SEL位是 01b ,优先级是 REQ0 ,REQ2 ,REQ3 ,REQ4 ,REQ1 ,和REQ5.
如果 ARB_SEL位是 10b ,优先级是 REQ0 ,REQ3 ,REQ4 ,REQ1 ,REQ2 ,和REQ5.
如果 ARB_SEL位是 11b ,优先级是REQ0 ,REQ4 ,REQ1 ,REQ2 ,REQ3,和REQ5.
注意仲裁器的REQ0 总是有最高优先级,REQ5 总是有最低优先级。此外通过改变
ARB_SEL 位,我们可以翻转REQ1 到REQ4 的优先级。
如果ARB_MODE 位置0,ARB_SEL 位不会自动改变,使得仲裁器在一个固定优先级的模
式下操作(注意在此模式下,我们通过手工改变ARB_SEL 位来配置优先级)。另外,如
果ARB_MODE 位是1 ,ARB_SEL 位以翻转的方式改变。例如如果REQ1 被服务,则
ARB_SEL 位自动的变为01b ,把REQ1 放到最低的优先级。ARB_SEL 变化的详细规则如
如果REQ0 或REQ5 被服务,ARB_SEL位完全不会变化。
如果REQ1 被服务,ARB_SEL位变为01b 。
如果REQ2 被服务,ARB_SEL位变为10b 。
如果REQ3 被服务,ARB_SEL位变为11b 。
如果REQ4 被服务,ARB_SEL位变为00b 。
三.中断处理机制:
中断模式寄存器:该INTMOD寄存器包括32位,每位与一个中断源相关。如果某位置1,相应的中断将在FIQ 模式下处理。否则在IRQ 模式下操作。请注意仅有一个中断源能够在FIR模式下服务,也就是说,INTMOD 仅有一个位可以被置1 。FIQ 比任何一个IRQ的优先级都要高.
屏蔽寄存器:该INTMSK寄存器包括32位,每个都是和一个中断源相关。如果某位置1,则CPU不会服务相应中断源的中断请求(注意SRCPND的相应位还是会被置1 )。如果屏蔽位为0 ,中断请求可以被服务。
中断未决寄存器:INTPND中断未决寄存器的32位显示是否相应的中断请求有最高优先级,其中断请求未屏蔽且在等待中断服务。因为INTPND 寄存器位于优先级逻辑之后,仅 1 位可以被置1,且中断请求生成对CPU的IRQ 。在对于IRQ 的中断服务程序中,我们可以读取寄存器决定那个中断源被服务。
在中断控制器中有五个控制寄存器:中断源未决寄存器,中断模式寄存器,屏蔽寄存器,优先级寄存器和中断未决寄存器,这5个寄存器都是主中断源的寄存器.在子中断源中还会包含子中断源未决寄存器,子中断屏蔽寄存器.
我们先来看一下中断流程图,如图(3):
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 图(3)
中断源分为2种,子中断中断源和中断源,当一个子中断产生一个中断信号,子中断源挂起寄存器(SUBRCPND)相应位自动置1,察看子中断屏蔽寄存器(SUBMASK)该子中断是否被屏蔽(人工设置),如果没屏蔽,则中断源寄存器(SRCPND)置1,察看该中断源是否被屏蔽,如果没被屏蔽,如果采用的是FIQ模式(仅有一个),就直接中断挂起寄存器置1,产生IRQ信号;否则采用IRQ模式,进行优先级判断后,高优先级的执行,中断挂起寄存器置1,产生IRQ信号。同时CPSR寄存器的I位置1,表明当前有一个IRQ中断产生。记得以前让大家注意该寄存器中的I和Q位了吧,他的作用就在这
下面我们结合2440init.s(<span style="color:#ffinit.s不熟悉的话可以看我以前写的教程)和datasheet来深入分析一下中断的处理机制,首先我们看两张图,图(4)和图(5).是CPU硬件中断请求的入口地址和优先级:
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 图(4)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 图(5)
我们以IRQ中断为例,如图(4),IRQ的硬件中断请求入口地址0x,也就是说,硬件收到请求后,会跳到这个地址开始执行.这个地址有什么,我们来看一下2440init.s汇编后的地址.如下图(6)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 图(6)
很明显,在0x地址的内存是一个跳转指令.图(6)汇编源码是这样的:
&b&HandlerUndef&;handler for Undefined mode
&b&HandlerSWI&;handler for SWI interrupt
&b&HandlerPabort&;handler for PAbort
&b&HandlerDabort&;handler for DAbort
&b&.&&;reserved&&&&&&&&&& ;//0x:&&& eafffffe&&& ....&&& B&&&&&&& {pc}& ; 0x14
&b&HandlerIRQ&;handler for IRQ interrupt
&b&HandlerFIQ&;handler for FIQ interrupt
HandlerFIQ&&&&& HANDLER HandleFIQ
HandlerIRQ&&&&& HANDLER HandleIRQ
HandlerUndef&&& HANDLER HandleUndef
HandlerSWI&&&&& HANDLER HandleSWI
HandlerDabort&& HANDLER HandleDabort
HandlerPabort&& HANDLER HandlePabort
学过arm汇编编程的话就很容易理解这段代码的意思.
说了哪么多,入正题,中断的处理过程:
第一步:CPU每执行一条指都会检查CPSR寄存器,当发现I和F位有1位被置位时,就进行中断处理.第一步会跳到异常向量表(图4),以IRQ为例,就会运行b&HandlerIRQ&这条指令.然后就进入HANDLER分解出来的函数HandlerIRQ&,代码如下:
;这是共用宏.相当于多个子函数.子函数个数取决于标号$HandlerLabel的多少.而$HandleLabel只是传进来的参数.HANDLER是这个宏的宏名.
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
&;这个宏的作用是调用中断入口服务程序.
&sub&sp,sp,#4&&&&&& ;栈空间腾出4个字节出来.准备把中断入口程序压栈.(原来sp-4)
&stmfd&sp!,{r0}&&&&&&&& ;(先减后压),把sp指再往下递增4个字节后,把r0压栈后,再把减后的数&#20540;写回sp.(原来sp-8),也就是说,r0放在原来sp-8的位置上.
&ldr&&&& r0,=$HandleLabel&&& ;把一些中断的首地址(硬件地址)加进来给r0.如:HandleFIQ,HandleIRQ等等.
&ldr&&&& r0,[r0]&&&&&&&&&&&& ;把中断程序的首地址(硬件地址)的内容(中断入口服务程序的地址)给r0
&str&&&& r0,[sp,#4]&&&&&&&&& ;把中断入口服务程序的地址放到栈空间sp-4的地方.
&ldmfd&& sp!,{r0,pc}&&&&&&&& ;(先弹后增)出栈,恢复原来的r0(原来sp-8)和把中断入口服务程序的地址给pc(原来sp-4),最后,(原来sp-0)
............
&^&& _ISR_STARTADDRESS&&; _ISR_STARTADDRESS=0x33FF_FF00
HandleReset &#&& 4
HandleUndef &#&& 4
HandleSWI&&#&& 4
HandlePabort&&& #&& 4
HandleDabort&&& #&& 4
HandleReserved& #&& 4
HandleIRQ&&#&& 4
HandleFIQ&&#&& 4
;Do not use the label 'IntVectorTable',
;The value of IntVectorTable is different with the address you think it may be.
;IntVectorTable
;@0x33FF_FF20
HandleEINT0&&#&& 4
HandleEINT1&&#&& 4
HandleEINT2&&#&& 4
HandleEINT3&&#&& 4
HandleEINT4_7&#&& 4
HandleEINT8_23&#&& 4
..............
;;;;;;第二步,跳转到二级向量表.
&sub&sp,sp,#4&&&&&& ;reserved for PC
&stmfd&sp!,{r8-r9}
;===================================================================================
;这查表方法够好了吧,r8(入口)&#43;index*4(别望了一条指令是4 bytes的喔),
;这不就是我们要找的那一项了吗.找到了表项,下一步做什么?肯定先装入了!
;==================================================================================
&ldr&r9,=INTOFFSET
&ldr&r9,[r9]
&ldr&r8,=HandleEINT0
&add&r8,r8,r9,lsl #2&&&&&&& ;//地址对齐,因为每个中断向量占4个字节,即isr = IvectTable &#43; Offeset * 4& 也就是查MAP表 _ISR_STARTADDRESS
&ldr&r8,[r8]&&&&&&&&&&&&&&& ;//装入中断服务程序的入口
&str&r8,[sp,#8]&&&&&&&&&&&& ;//把入口也入栈,准备用旧招
&ldmfd&sp!,{r8-r9,pc}&&&& ;//施招,弹出栈,哈哈,顺便把r8弹出到PC了,跳转成功!
.................
*****下面是C代码,把中断服务程序进行注册连接一下**********:
...........
#define pISR_EINT4_7&& (*(unsigned *)(_ISR_STARTADDRESS&#43;0x30))
............
pISR_EINT4_7=(unsigned)EintH &//外部中断4_7中断服务子程序入口地址
...........
void __irq EintHandler(void)
&if(rINTPND==BIT_EINT4_7)
&&ClearPending(BIT_EINT4_7);
&&if(rEINTPEND&(1&&4))
&&&Uart_Printf(&eint 4\n&);
&&&rGPFDAT = LED1ON;
&&&Delay(500);
&&&rGPFDAT = LEDOFF;
&&&rEINTPEND |= 1&& 4;
&&if(rEINTPEND&(1&&5))
&&&Uart_Printf(&eint 5\n&);
&&&rGPFDAT = LED2ON;
&&&Delay(500);
&&&rGPFDAT = LEDOFF;
&&&rEINTPEND |= 1&& 5;
&&if(rEINTPEND&(1&&6))
&&&Uart_Printf(&eint 6\n&);
&&&rGPFDAT = LED3ON;
&&&Delay(500);
&&&rGPFDAT = LEDOFF;
&&&rEINTPEND |= 1&& 6;
&&if(rEINTPEND&(1&&7))
&&&Uart_Printf(&eint 7\n&);
&&&rGPFDAT = LED4ON;
&&&Delay(500);
&&&rGPFDAT = LEDOFF;
&&&rEINTPEND |= 1&& 7;
..........
关于__irq 的使用
&__irq为一个标识,用来表示一个函数是否为中断函数。对于不同的编译器,__irq在函数名中的位置不一样,例如:
&ADS编译器中 : void __irq IRQ_Eint0(void);
&Keil编译器中 : void IRQ_Eint0(void) __
&但是其意义一样,它所完成的任务是标识该函数为中断函数,在编译器编译是调用此函数时,先保护函数入口现场,然后执行中断函数,
函数执行完毕,恢复中断现场,这整个过程不需要用户重新编写代码来完成,由编译器自动完成。因而这也给不具备中断嵌套功能的ARM系统带来
了问题,若使用 __irq 时有中断嵌套产生,这现场保护就会混乱。在前一篇日志“LPC2000系列中断嵌套处理”中,自己编写中断入口现场保护代
码,并不使用 __irq 标识符号,就是这个原因。
&总结如下:
&1、若不想自己编写中断入口现场保护代码,而且使用中无中断嵌套,在中断函数中用 __irq 来标识我们的中断函数,否则出错;
&2、若程序中要使用中断嵌套,对于无中断嵌套功能的ARM来说,一定要自己编写中断入口现场保护代码,而且不能用 __irq 标识我们的
中断函数,否则出错。
最后结合上面的代码,我们看一下在内存中中断是怎么跳转的.如图(7)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 图(7)
哈哈.终于完成了中断的跳转.中断寄存器无非就是主中断源的中断源未决寄存器,中断模式寄存器,屏蔽寄存器,优先级寄存器和中断未决寄存器,和子中断源的中断源未决寄存器,子中断屏蔽寄存器,共7个,看懂就能用中断写程序了.另注意:中断标志位的清除顺序:SUBSRCPND--&SRCPND--&INTPND.
容易混绞点:
rSRCPND |= (1&&9);&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ///源未决,&&&一定需要设置
&rINTPND |= (1&&9);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ///中断未决,&&&一定需要设置
&rSUBSRCPND |= (1&&13);&&&&&&&&&&&&&&&&& ///子中断未决,&&&查看rINTPND是否有中断复用口,有就要设置.
rINTSUBMSK &= ~(1&&13);&&&&&&&&&&&&&&&&& ///子中断屏蔽,&&&查看rINTPND是否有中断复用口,有就要设置.
&rINTMSK &= ~(1&&9);&&&&&&&&&&&&&&&&&&&&&&&&&& ///中断屏蔽,&&&一定需要设置
外部中断GPF7
rSRCPND |= (1&&4);&&&&&&&&&&&&&&&&&&&&&&&&&&&&///源未决,&&&一定需要设置
rINTPND |= (1&&4);&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ///中断未决,&&&一定需要设置
rEINTPEND |= (1&&7);&&&&&&&&&&&&&&&&&&&&&&&& ///子中断未决,&&&查看rINTPND是否有中断复用口,有就要设置.
rEINTMASK &= ~(1&&7);&&&&&&&&&&&&&&&&&&&&///子中断屏蔽,&&&查看rINTPND是否有中断复用口,有就要设置.
rINTMSK &= ~(1&&4);&&&&&&&&&&&&&&&&&&&&&&&& ///中断屏蔽,&&&一定需要设置
3)同理,其它也就一样的,有中断复用,就必须找到子中断PND和子中断MSK来设置.
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:123490次
积分:2047
积分:2047
排名:第13712名
原创:79篇
转载:12篇
评论:20条
(1)(5)(1)(4)(1)(1)(2)(1)(1)(3)(2)(1)(1)(3)(2)(1)(1)(4)(16)(12)(9)(11)(8)1218人阅读
arn处理器(13)
2410中断中SRCPND和INTPND清零的疑问
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=0x,INTPND=0x,该值说明当前0号中断和1号中断被触发,但当前正在被处理的是0号中断, 处理完毕后我们应该这样设置INTPND和SRCPND:SRCPND=0x& && && && & //位0被置为0INTPND=0x& && && && & //位0被置为0(方法是往该位写入1)但是在一些测试程序中出现的清0程序似乎与上述有出路,如下:程序一:__inline void ClearPending(int bit){& && & rSRCPND =& & rINTPND =& & i = rINTPND;}或程序二:#define ClearPending(bit) {/& && && && && & rSRCPND =/& && && && && & rINTPND =/& && && && && & rINTPND;/& && && && && & }个人认为应该改写为:程序三__inline void ClearPending(int bit){& & rSRCPND &= ~(bit);& & rINTPND =}现在有以下几点疑问:(1)程序一中的i = rINTPND;是什么意思?(2)程序二种的rINTPND;/是什么意思?(3)上述两条语句是否可以删除?(4)考虑到程序一和程序二被广泛引用,但这两个程序中的语句rSRCPND =和rSRCPND =/的作用是将相应中断源请求置1,同时把其他中断源置0,似乎是错误的。请高手不吝赐教!!:)
我没看过2410,我的想法是呀i = xxx,是不是读一遍寄存器,保证数据被写进去了呢??这个是猜的,只是有可能!最后一个问题,你说要改,我想不是吧,那个rSRCPND应该也是写1清0的吧。。。
INTPND清零写1是比较确定的了,但是SRCPND清零应该写1还是写0确实有两种说法,根据2410的说明我觉得SRCPND清0应该写0才对啊
the serviceroutine must clear the pending condition by writing a 1 to the corresponding bit in the SRCPND register first andthen clear the pending condition in the INTPND registers by using the same method.上面是官方手册中的一句话,可见两个都是写1清0的。
再看了下说明,你说得对,我一开始对下面这句话理解错了,原文是:You can clear a specific bit of the SRCPND register by writing a data to this register. It clears only the bit positions of the SRCPND corresponding to those set to one in the data. The bit positions corresponding to those that are set to 0 in the data remains as they are.谢谢啊,呵呵!
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:195110次
积分:2837
积分:2837
排名:第8929名
原创:84篇
转载:50篇
评论:23条
(3)(1)(8)(7)(1)(4)(2)(3)(7)(10)(6)(1)(9)(20)(3)(14)(6)(1)(23)(5)

我要回帖

更多关于 床的摆放位置 的文章

 

随机推荐