[ZLG-ARM] 提问:ARM在中断程序中该如何关中断?

[复制链接]
5200|18
 楼主| linjing 发表于 2007-3-28 17:44 | 显示全部楼层 |阅读模式
想要在SWI中断中访问管脚,同时FIQ中断中也需要访问这几个管脚,所以想在SWI中断中把FIQ中断禁止,该怎么做比较好?似乎不用先调用关中断例程,返回时再调用开中断例程这么麻烦吧,不知道如下面这么做可不可行?<br /><br />int&nbsp;swi(0)&nbsp;PortAccess(&nbsp;void&nbsp;){<br />&nbsp;&nbsp;&nbsp;&nbsp;__asm&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MSR&nbsp;CPSR_c,&nbsp;Mode_SVC&nbsp;+&nbsp;F_IRQ&nbsp;+&nbsp;I_IRQ<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp;//&nbsp;读写与FIQ有冲突的管脚<br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;SWI中断返回时是不是会自动将SPSR恢复到SPSR中从而重新恢复中断?<br />}<br /><br />另外,按照ARM的建议,修改CPSR时应该用读-修改-写的方式,可在Keil的启动代码中Starts.s中就是用的立即数修改CPSR的,这么做有没有问题.
computer00 发表于 2007-3-28 18:12 | 显示全部楼层

晕~~~那是因为才刚刚启动,所以没必要保留以前的状态信息

MSR&nbsp;CPSR,&nbsp;#(Mode_SVC&nbsp;+&nbsp;F_IRQ&nbsp;+&nbsp;I_IRQ)<br /><br />好象这里的CPSR需要指定修改哪个区的吧,光这样好象编译通不过的~~~~~<br /><br />
 楼主| linjing 发表于 2007-3-29 12:08 | 显示全部楼层

见笑了,我刚接触ARM,指令不太熟悉

<br /><br />我的意思是不用读-修改-写的方式,而直接用立即数改写CPRS,SWI中断返回时候自动恢复原来的状态,不需要手动恢复,请问二楼,这样可不可行?
computer00 发表于 2007-3-29 13:00 | 显示全部楼层

最好不要直接修改,可能会不小心修改了其它标志位

读回来,放到一个寄存器,然后再修改某一个位,保留其它位不变,再写回去,也不是很麻烦啊。<br /><br /><br />要不你就把你的FIQ改到IRQ里面,这样就不用担心被打断了~~~~~~~
 楼主| linjing 发表于 2007-3-29 17:48 | 显示全部楼层

回computer00 ,其实我这样做是由具体情况决定的

我说的SWI中断访问的管脚实际上是想要模拟8位的外部总线<br /><br />我说的FIQ中断是定时器中断,是我系统中的唯一的中断源,所以想用FIQ可能会简单些,定时中断用于生成系统时基,以及按键定时扫描(按键扫描是通过前面说的模拟8位总线进行的)<br /><br />既然是模拟总线,所以希望能快点最好还是尽量快点,其实如果不追求速度的话,我完全可以将模拟总线包写成普通函数,再写两个SWI中断通过修改SPRS开/关中断,可相对来说那样多出许多指令。(我不喜欢用太高的晶振或者PLL,不希望一味通过提高主频来提速,纯粹个人习惯:)<br /><br />其实如果实际做的话我也考虑过把FIQ改成向量IRQ,但我还是能希望探讨一些细节,也希望藉此来尽快熟悉ARM的体系结构<br /><br />如果按照computer00&nbsp;的说法,我不用立即数,改成下面的样子,可以吗<br />int&nbsp;swi(0)&nbsp;PortAccess(&nbsp;void&nbsp;){<br />&nbsp;&nbsp;&nbsp;&nbsp;__asm&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MRS&nbsp;R0,&nbsp;CPSR<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ORR&nbsp;R0,&nbsp;RO,&nbsp;#F_IRQ&nbsp;+&nbsp;I_IRQ<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MSR&nbsp;CPSR_c,&nbsp;R0<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp;//&nbsp;模拟总线<br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;SWI中断返回时是不是会自动将SPSR恢复到SPSR中从而重新恢复中断?<br />}<br />
computer00 发表于 2007-3-29 18:34 | 显示全部楼层

这样应该可以的.

为什么模拟总线要通过SWI啊?&nbsp;关中断不如直接关中断控制寄存器来得快吧.这样就不用SWI来搞.
 楼主| linjing 发表于 2007-3-29 22:02 | 显示全部楼层

楼上的意思是不必禁止FIQ位和IRQ位,而是直接关中断控制器

暂时还没看懂LPC2104的那个中断系统,不过这个办法似乎不错,如果可行的话倒象是更简单,受教了!
computer00 发表于 2007-3-30 10:28 | 显示全部楼层

参看我以前写过的代码:

如果你只有一个中断,并且以后不会再扩展的话,你可以直接使用<br /><br />VICIntEnClr=0xFFFFFFFF;<br />VICIntEnable=xxx;&nbsp;<br /><br />来控制中断.<br /><br /><br /><br /><br /><br /><br /><br />/**********************************************************************************************<br />功能:进入临界段。<br />入口参数:无。<br />返回:无。<br />备注:该函数使用的是将中断分配寄存器清0的方法来关中断。比起用软中断,运行速度要快。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果要开某个中断,则应该先调用一次该函数,然后再修改中断备份变量CopyOfVICIntEnable<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;的值,而不能直接修改VICIntEnable的值。否则会出错。<br />**********************************************************************************************/<br />void&nbsp;OSEnterCritical(void)<br />{<br />&nbsp;if(OSEnCrCount==0)&nbsp;&nbsp;&nbsp;//如果前面未关中断<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;VICIntEnClr=0xFFFFFFFF;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//将VICIntEnable清除,禁止中断<br />&nbsp;&nbsp;}<br />&nbsp;OSEnCrCount++;&nbsp;&nbsp;//进入临界段次数加1<br />}<br />//////////////////////////////////End&nbsp;of&nbsp;function//////////////////////////////////////////////<br /><br /><br />/**********************************************************************************************<br />功能:退出临界段<br />入口参数:无。<br />返回:无。<br />备注:无。<br />**********************************************************************************************/<br />void&nbsp;OSExitCritical(void)<br />{<br />&nbsp;if(OSEnCrCount&gt=1)&nbsp;&nbsp;//如果进入临界段的次数大于等于1次<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;OSEnCrCount--;&nbsp;&nbsp;&nbsp;&nbsp;//则次数减1<br />&nbsp;&nbsp;&nbsp;if(OSEnCrCount==0)&nbsp;&nbsp;//如果减次数减到0,则要开中断<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VICIntEnable=CopyOfVICIntEnable;&nbsp;&nbsp;//打开所需要开的中断<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;}<br />}<br />//////////////////////////////////End&nbsp;of&nbsp;function//////////////////////////////////////////////
 楼主| linjing 发表于 2007-3-30 11:58 | 显示全部楼层

先收藏,再分析,谢谢computer00

  
zlgARM 发表于 2007-3-30 17:37 | 显示全部楼层

linjing

&nbsp;&nbsp;&nbsp;&nbsp;圈圈的关中断方法也可以。<br />&nbsp;&nbsp;&nbsp;&nbsp;如果把中断看成是水龙头,那么如果想要关掉屋子里的水龙头,可以有两个办法。<br />&nbsp;&nbsp;&nbsp;&nbsp;其一:关总阀。所有水龙头都没法再用,修改CPSR来关中断的方法属于此类;<br />&nbsp;&nbsp;&nbsp;&nbsp;其二:逐个地把所有或部分水龙头关掉,修改VICIntEnClr的方法属此类。<br />&nbsp;&nbsp;&nbsp;&nbsp;
 楼主| linjing 发表于 2007-3-31 10:27 | 显示全部楼层

用惯了Keil C51,在51中都是用的#pragma disable

Keil&nbsp;C51的#pragma&nbsp;disable有一个很重要的特点,进入子程序的时候保存中断允许位EA的状态,退出子程序的时候不是简单的开中断,而是“恢复”原来的中断允许EA的状态,逻辑上完整
有意思 发表于 2007-3-31 14:42 | 显示全部楼层

这样可不可以

__inline&nbsp;void&nbsp;enable_IRQ(void)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;__asm<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MRS&nbsp;r1,&nbsp;CPSR<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BIC&nbsp;r1,&nbsp;r1,&nbsp;#0x80<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MSR&nbsp;CPSR_c,&nbsp;r1<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br />__inline&nbsp;void&nbsp;disable_IRQ(void)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;__asm<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MRS&nbsp;r1,&nbsp;CPSR<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ORR&nbsp;r1,&nbsp;r1,&nbsp;#0x80<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MSR&nbsp;CPSR_c,&nbsp;r1<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br />
 楼主| linjing 发表于 2007-3-31 21:30 | 显示全部楼层

百步笑一下五十步:)

“有意思”,五十步了吧:)<br /><br />你的办法是可以,但必须放到特权模式下才行,就是前面提到的在用户模式下为什么要用SWI进管态关中断的问题,只有进入管态才能用你的程序。<br /><br />
有意思 发表于 2007-3-31 22:16 | 显示全部楼层

那这样呢

Maskmd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x1f&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />SVC32md&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x13<br />I_Bit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x80<br /><br /><br />FRAME_R0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0X00<br />FRAME_R1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRAME_R0&nbsp;+&nbsp;4<br />FRAME_R2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRAME_R1&nbsp;+&nbsp;4<br />FRAME_R3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRAME_R2&nbsp;+&nbsp;4<br />FRAME_R4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRAME_R3&nbsp;+&nbsp;4<br />FRAME_R5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRAME_R4&nbsp;+&nbsp;4<br />FRAME_R6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRAME_R5&nbsp;+&nbsp;4<br />FRAME_R7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRAME_R6&nbsp;+&nbsp;4<br />FRAME_R8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRAME_R7&nbsp;+&nbsp;4<br />FRAME_R9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRAME_R8&nbsp;+&nbsp;4<br />FRAME_R10&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRAME_R9&nbsp;+&nbsp;4<br />FRAME_R11&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRAME_R10&nbsp;+&nbsp;4<br />FRAME_R12&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRAME_R11&nbsp;+&nbsp;4<br />FRAME_PSR&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRAME_12&nbsp;+&nbsp;4<br />FRAME_LR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRAME_PSR&nbsp;+&nbsp;4<br />FRAME_PC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRAME_LR&nbsp;+&nbsp;4<br />FRAME_SIZE&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRAME_PC&nbsp;+&nbsp;4<br /><br />IRQ_Entry<br />&nbsp;&nbsp;&nbsp;&nbsp;SUB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r14,r14,#4<br />&nbsp;&nbsp;&nbsp;&nbsp;STMDB&nbsp;&nbsp;&nbsp;&nbsp;r13,!{r0-r3,r12,r14}<br />&nbsp;&nbsp;&nbsp;&nbsp;&lt服务中断&gt<br />&nbsp;&nbsp;&nbsp;&nbsp;BL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;read_RescheduleFlag<br />&nbsp;&nbsp;&nbsp;&nbsp;CMP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,#0<br />&nbsp;&nbsp;&nbsp;&nbsp;LDMNEIA&nbsp;&nbsp;r13!,{r0-r13,r12,PC}^<br />&nbsp;&nbsp;&nbsp;&nbsp;MRS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r2,spsr<br />&nbsp;&nbsp;&nbsp;&nbsp;MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,r13<br />&nbsp;&nbsp;&nbsp;&nbsp;ADD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r13,r13,#6*4<br />&nbsp;&nbsp;&nbsp;&nbsp;MRS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r1,cpsr<br />&nbsp;&nbsp;&nbsp;&nbsp;BIC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r1,r1,#Maskmd<br />&nbsp;&nbsp;&nbsp;&nbsp;ORR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r1,r1,SVC32md<br />&nbsp;&nbsp;&nbsp;&nbsp;MSR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cpsr_c,r1<br />&nbsp;&nbsp;&nbsp;&nbsp;SUB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r13,r13,#FRAME_SIZE-FRAME_R4<br />&nbsp;&nbsp;&nbsp;&nbsp;STMIA&nbsp;&nbsp;&nbsp;&nbsp;r13,{r4-r11}<br />&nbsp;&nbsp;&nbsp;&nbsp;LDMIA&nbsp;&nbsp;&nbsp;&nbsp;r0,{r4-r9}<br />&nbsp;&nbsp;&nbsp;&nbsp;BIC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r1,r1,#I_Bit<br />&nbsp;&nbsp;&nbsp;&nbsp;MSR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cpsr_c,r1<br />&nbsp;&nbsp;&nbsp;&nbsp;STMDB&nbsp;&nbsp;&nbsp;&nbsp;r13!,{r4-r7}<br />&nbsp;&nbsp;&nbsp;&nbsp;STR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r2,[r13,#FRAME_PSR]<br />&nbsp;&nbsp;&nbsp;&nbsp;STR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r8,[r13,#FRAME_R12]<br />&nbsp;&nbsp;&nbsp;&nbsp;STR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r9,[r13,#FRAME_PC]<br />&nbsp;&nbsp;&nbsp;&nbsp;STR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r14,[r13,#FRAME_LR]<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&lt完成中断服务程序&gt<br />&nbsp;&nbsp;&nbsp;&nbsp;LDMIA&nbsp;&nbsp;&nbsp;&nbsp;r13!,{r0-r12,r14}<br />&nbsp;&nbsp;&nbsp;&nbsp;MSR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spsr_cxsf,r14<br />&nbsp;&nbsp;&nbsp;&nbsp;LDMIA&nbsp;&nbsp;&nbsp;&nbsp;r13!,{r14,pc}^
 楼主| linjing 发表于 2007-3-31 22:29 | 显示全部楼层

百步只好向五十步说抱歉:(

百步最近刚接触ARM,根本看不懂ARM的汇编指令:{<br /><br />自从知道ARM是什么东东之后,说实话,我根本就没打算去抠ARM的汇编,你想啊,现在有谁Windows编程的时候还去管x86的汇编指令的,不过现在看来汇编指令还是要学点的,不过您帖的程序只好懂我能看懂的时候再回了。<br /><br />抱歉抱歉,不过本帖已收藏,回头我会看的
有意思 发表于 2007-4-1 10:12 | 显示全部楼层

你以为是我写的啊,没那本事

书上抄地,建议你看本书<br />ARM&nbsp;嵌入式系统开发&nbsp;----软件设计与优化<br />ARM&nbsp;System&nbsp;Devcloper`s&nbsp;Guide:Designing&nbsp;and&nbsp;Optimizing&nbsp;System&nbsp;Software<br />[美]&nbsp;Andrew&nbsp;N.Sloss<br />[英]&nbsp;Dominic&nbsp;Sysmes<br />[美]&nbsp;Chis&nbsp;Wright<br />&nbsp;沈建华译<br />北航出的,75块<br />里面详细介绍了可重入中断处理等 <br /> 相关链接:<a href='http://www.dushu.com/book/11183297/'>http://www.dushu.com/book/11183297/</a>
 楼主| linjing 发表于 2007-4-1 17:13 | 显示全部楼层

问 computer00

我如果令VICProtection=1,&nbsp;你前面的&nbsp;进出临界段&nbsp;的代码还能直接用吗。<br /><br />一般VICProtection的保护功能需要用吗
hotpower 发表于 2007-4-1 18:58 | 显示全部楼层

VICProtection只对用户级有作用~~~

  
 楼主| linjing 发表于 2007-4-6 19:47 | 显示全部楼层

追问一下,系统中只有一个中断的时候,用FIQ与IRQ会有什么

好像FIQ还有几个专用的寄存器,这是已知的不同<br /><br />我的疑问是在只有一个中断源的时候,用FIQ响应和用IRQ开销是不是都一样,包括影响中断的时间,堆栈的占用,等等,还有其他的方面吗??
您需要登录后才可以回帖 登录 | 注册

本版积分规则

35

主题

327

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部