RealView MDK中宏的使用方法

[复制链接]
2527|0
 楼主| xiong_gang 发表于 2008-5-6 09:28 | 显示全部楼层 |阅读模式
<br />宏可以减少源代码长度,结构清晰,可以给宏起个与功能相关的名字,增加可读性。另外在RealView&nbsp;MDK中可以用宏来处理中断。即把一个普通函数作为中断服务子程序。例如AT91RM9200这块芯片采用的ARM9内核。ARM9核有多种模式,进入中断时需要进行模式切换。因此中断服务子程序时,除了保护现场之外还需要在进入中断之间保存当前模式,在中断子程序执行完时恢复到中断之前的模式。但是我们知道普通函数并不会保存进入之前的模式也不会恢复到进入之前的模式。为将一个普通函数改造为一个中断函数,我们需要在进入函数之前和退出函数之后加上一小段汇编代码来进行模式的保存和恢复。这就是ARM9核惯用的中断处理方法之一。下面介绍在MDK中如何使用宏。<br />宏的定义格式:<br />MACRO<br />{$label}&nbsp;&nbsp;macroname&nbsp;&nbsp;&nbsp;{$parameter}{$parameter&nbsp;}…<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;宏定义体<br />MEND<br />其中&nbsp;&nbsp;$label&nbsp;宏指令被展开时,label可被替换成相应的符号,通常为一个标号在一个符号前使用$表示被汇编时使用相应的值替代$后的符号。<br />Macroname&nbsp;所定义的宏的名称。<br />$parameter&nbsp;宏指令的参数。当宏指令被展开时将被替换成相应的值,类似于函数中的形参。<br /><br />下面举个例子,这个例子中先定义一个宏,然后调用该宏,并显示调用该宏之后展开的汇编代码。让读者深刻理解宏的使用方法。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MACRO<br />$Lab&nbsp;&nbsp;&nbsp;&nbsp;DivMod&nbsp;&nbsp;$Div,$Top,$Bot,$Temp<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT&nbsp;&nbsp;$Top&nbsp;&lt&gt&nbsp;$Bot&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Produce&nbsp;an&nbsp;error&nbsp;message&nbsp;if&nbsp;the<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT&nbsp;&nbsp;$Top&nbsp;&lt&gt&nbsp;$Temp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;registers&nbsp;supplied&nbsp;are<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT&nbsp;&nbsp;$Bot&nbsp;&lt&gt&nbsp;$Temp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;not&nbsp;all&nbsp;different<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;$Div&quot;&nbsp;&lt&gt&nbsp;&quot;&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT&nbsp;&nbsp;$Div&nbsp;&lt&gt&nbsp;$Top&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;These&nbsp;three&nbsp;only&nbsp;matter&nbsp;if&nbsp;$Div<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT&nbsp;&nbsp;$Div&nbsp;&lt&gt&nbsp;$Bot&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;is&nbsp;not&nbsp;null&nbsp;(&quot;&quot;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT&nbsp;&nbsp;$Div&nbsp;&lt&gt&nbsp;$Temp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ENDIF<br />$Lab<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$Temp,&nbsp;$Bot&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Put&nbsp;divisor&nbsp;in&nbsp;$Temp<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$Temp,&nbsp;$Top,&nbsp;LSR&nbsp;#1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;double&nbsp;it&nbsp;until<br />90&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOVLS&nbsp;&nbsp;&nbsp;$Temp,&nbsp;$Temp,&nbsp;LSL&nbsp;#1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;2&nbsp;*&nbsp;$Temp&nbsp;&gt&nbsp;$Top<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$Temp,&nbsp;$Top,&nbsp;LSR&nbsp;#1<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BLS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%b90&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;The&nbsp;b&nbsp;means&nbsp;search&nbsp;backwards<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;$Div&quot;&nbsp;&lt&gt&nbsp;&quot;&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Omit&nbsp;next&nbsp;instruction&nbsp;if&nbsp;$Div&nbsp;is&nbsp;null<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$Div,&nbsp;#0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Initialize&nbsp;quotient<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ENDIF<br />91&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$Top,&nbsp;$Temp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Can&nbsp;we&nbsp;subtract&nbsp;$Temp?<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SUBCS&nbsp;&nbsp;&nbsp;$Top,&nbsp;$Top,$Temp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;If&nbsp;we&nbsp;can,&nbsp;do&nbsp;so<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;$Div&quot;&nbsp;&lt&gt&nbsp;&quot;&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Omit&nbsp;next&nbsp;instruction&nbsp;if&nbsp;$Div&nbsp;is&nbsp;null<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$Div,&nbsp;$Div,&nbsp;$Div&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Double&nbsp;$Div<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ENDIF<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$Temp,&nbsp;$Temp,&nbsp;LSR&nbsp;#1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Halve&nbsp;$Temp,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$Temp,&nbsp;$Bot&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;and&nbsp;loop&nbsp;until<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BHS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%b91&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;less&nbsp;than&nbsp;divisor<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MEND<br /><br />调用该宏语句:<br />ratio&nbsp;&nbsp;DivMod&nbsp;&nbsp;r0,r5,r4,r2<br /><br />该宏展开后的汇编代码如下:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT&nbsp;&nbsp;r5&nbsp;&lt&gt&nbsp;r4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Produce&nbsp;an&nbsp;error&nbsp;if&nbsp;the<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT&nbsp;&nbsp;r5&nbsp;&lt&gt&nbsp;r2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;registers&nbsp;supplied&nbsp;are<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT&nbsp;&nbsp;r4&nbsp;&lt&gt&nbsp;r2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;not&nbsp;all&nbsp;different<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT&nbsp;&nbsp;r0&nbsp;&lt&gt&nbsp;r5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;These&nbsp;three&nbsp;only&nbsp;matter&nbsp;if&nbsp;$Div<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT&nbsp;&nbsp;r0&nbsp;&lt&gt&nbsp;r4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;is&nbsp;not&nbsp;null&nbsp;(&quot;&quot;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ASSERT&nbsp;&nbsp;r0&nbsp;&lt&gt&nbsp;r2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;<br />ratio<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r2,&nbsp;r4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Put&nbsp;divisor&nbsp;in&nbsp;$Temp<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r2,&nbsp;r5,&nbsp;LSR&nbsp;#1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;double&nbsp;it&nbsp;until<br />90&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOVLS&nbsp;&nbsp;&nbsp;r2,&nbsp;r2,&nbsp;LSL&nbsp;#1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;2&nbsp;*&nbsp;r2&nbsp;&gt&nbsp;r5<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r2,&nbsp;r5,&nbsp;LSR&nbsp;#1<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BLS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%b90&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;The&nbsp;b&nbsp;means&nbsp;search&nbsp;backwards<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,&nbsp;#0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Initialize&nbsp;quotient<br />91&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r5,&nbsp;r2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Can&nbsp;we&nbsp;subtract&nbsp;r2?<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SUBCS&nbsp;&nbsp;&nbsp;r5,&nbsp;r5,&nbsp;r2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;If&nbsp;we&nbsp;can,&nbsp;do&nbsp;so<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,&nbsp;r0,&nbsp;r0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Double&nbsp;r0<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r2,&nbsp;r2,&nbsp;LSR&nbsp;#1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Halve&nbsp;r2,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r2,&nbsp;r4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;and&nbsp;loop&nbsp;until<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BHS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%b91&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;less&nbsp;than&nbsp;divisor<br />看完以上例子,读者应该对MDK下宏的使用很清晰了。<br />下面以AT91RM9200为例,说明如何将一个普通函数用作中断服务子程序。<br />普通函数定义如下:<br />void&nbsp;AT91F_ST_HANDLER(void)<br />{<br />volatile&nbsp;int&nbsp;StStatus;<br />&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Read&nbsp;the&nbsp;system&nbsp;timer&nbsp;status&nbsp;register<br />&nbsp;&nbsp;&nbsp;&nbsp;StStatus&nbsp;=&nbsp;*(AT91C_ST_SR);<br />&nbsp;&nbsp;&nbsp;&nbsp;StTick++;<br />}<br />处理中断的宏为:<br />&nbsp;&nbsp;&nbsp;&nbsp;MACRO&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;IRQHandle&nbsp;$in_handle,$out_handle<br />&nbsp;&nbsp;&nbsp;&nbsp;EXTERN&nbsp;$in_handle<br />&nbsp;&nbsp;&nbsp;&nbsp;GLOBAL&nbsp;$out_handle<br /><br /><br />;#-&nbsp;Adjust&nbsp;and&nbsp;save&nbsp;LR_irq&nbsp;in&nbsp;IRQ&nbsp;stack<br />&nbsp;&nbsp;&nbsp;&nbsp;sub&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r14,&nbsp;r14,&nbsp;#4<br />&nbsp;&nbsp;&nbsp;&nbsp;stmfd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sp!,&nbsp;{r14}<br /><br />;#-&nbsp;Write&nbsp;in&nbsp;the&nbsp;IVR&nbsp;to&nbsp;support&nbsp;Protect&nbsp;Mode<br />;#-&nbsp;No&nbsp;effect&nbsp;in&nbsp;Normal&nbsp;Mode<br />;#-&nbsp;De-assert&nbsp;the&nbsp;NIRQ&nbsp;and&nbsp;clear&nbsp;the&nbsp;source&nbsp;in&nbsp;Protect&nbsp;Mode<br />&nbsp;&nbsp;&nbsp;&nbsp;ldr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r14,&nbsp;=AT91C_BASE_AIC<br />&nbsp;&nbsp;&nbsp;&nbsp;str&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r14,&nbsp;[r14,&nbsp;#AT91C_AIC_IVR-AT91C_BASE_AIC]<br /><br />;#-&nbsp;Save&nbsp;SPSR&nbsp;and&nbsp;r0&nbsp;in&nbsp;IRQ&nbsp;stack<br />&nbsp;&nbsp;&nbsp;&nbsp;mrs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r14,&nbsp;SPSR<br />&nbsp;&nbsp;&nbsp;&nbsp;stmfd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sp!,&nbsp;{r0,&nbsp;r14}<br /><br />;#-&nbsp;Enable&nbsp;Interrupt&nbsp;and&nbsp;Switch&nbsp;in&nbsp;SYS&nbsp;Mode<br />&nbsp;&nbsp;&nbsp;&nbsp;mrs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,&nbsp;CPSR<br />&nbsp;&nbsp;&nbsp;&nbsp;bic&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,&nbsp;r0,&nbsp;#I_BIT<br />&nbsp;&nbsp;&nbsp;&nbsp;orr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,&nbsp;r0,&nbsp;#ARM_MODE_SYS<br />&nbsp;&nbsp;&nbsp;&nbsp;msr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CPSR_c,&nbsp;r0<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />;#-&nbsp;Save&nbsp;scratch/used&nbsp;registers&nbsp;and&nbsp;LR&nbsp;in&nbsp;User&nbsp;Stack<br />&nbsp;&nbsp;&nbsp;&nbsp;stmfd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sp!,&nbsp;{&nbsp;r1-r3,&nbsp;r12,&nbsp;r14}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;ldr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r1,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=$in_handle<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lr,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pc<br />&nbsp;&nbsp;&nbsp;&nbsp;bx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r1<br /><br />;#-&nbsp;Restore&nbsp;scratch/used&nbsp;registers&nbsp;and&nbsp;LR&nbsp;from&nbsp;User&nbsp;Stack<br />&nbsp;&nbsp;&nbsp;&nbsp;ldmia&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sp!,&nbsp;{&nbsp;r1-r3,&nbsp;r12,&nbsp;r14}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />;#-&nbsp;Disable&nbsp;Interrupt&nbsp;and&nbsp;switch&nbsp;back&nbsp;in&nbsp;IRQ&nbsp;mode<br />&nbsp;&nbsp;&nbsp;&nbsp;mrs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,&nbsp;CPSR<br />&nbsp;&nbsp;&nbsp;&nbsp;bic&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,&nbsp;r0,&nbsp;#ARM_MODE_SYS<br />&nbsp;&nbsp;&nbsp;&nbsp;orr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,&nbsp;r0,&nbsp;#I_BIT|ARM_MODE_IRQ<br />&nbsp;&nbsp;&nbsp;&nbsp;msr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CPSR_c,&nbsp;r0<br /><br />;#-&nbsp;Mark&nbsp;the&nbsp;End&nbsp;of&nbsp;Interrupt&nbsp;on&nbsp;the&nbsp;AIC<br />&nbsp;&nbsp;&nbsp;&nbsp;ldr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,&nbsp;=AT91C_BASE_AIC<br />&nbsp;&nbsp;&nbsp;&nbsp;str&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,&nbsp;[r0,&nbsp;#AT91C_AIC_EOICR-AT91C_BASE_AIC]<br /><br />;#-&nbsp;Restore&nbsp;SPSR_irq&nbsp;and&nbsp;r0&nbsp;from&nbsp;IRQ&nbsp;stack<br />&nbsp;&nbsp;&nbsp;&nbsp;ldmia&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sp!,&nbsp;{r0,&nbsp;r14}<br />&nbsp;&nbsp;&nbsp;&nbsp;msr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPSR_cxsf,&nbsp;r14<br /><br />;#-&nbsp;Restore&nbsp;adjusted&nbsp;&nbsp;LR_irq&nbsp;from&nbsp;IRQ&nbsp;stack&nbsp;directly&nbsp;in&nbsp;the&nbsp;PC<br />&nbsp;&nbsp;&nbsp;&nbsp;ldmia&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sp!,&nbsp;{pc}^<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;MEND<br />&nbsp;&nbsp;&nbsp;&nbsp;GLOBAL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AT91F_ST_ASM_HANDLER&nbsp;<br />AT91F_ST_ASM_HANDLER&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;IRQHandle&nbsp;AT91F_ST_HANDLER,AT91F_ST_ASM_HANDLER<br />以上红色部分即为利用定义的宏来处理中断。其中AT91F_ST_ASM_HANDLER是一个全局标号,可在其它文件中引用。AT91F_ST_ASM_HANDLER是前面定义的C函数。中断发生时道先找到标号AT91F_ST_ASM_HANDLER并执行其展开的汇编代码,保存PC及模式之后跳到C函数void&nbsp;AT91F_ST_HANDLER(void)。在返回该函数时有恢复PC和模式。这样就完成了一次中断的调用过程。<br />注:读者可能会注意到宏IRQHandle前面并没有标号,这也是允许的,该标号是可选的。<br /><br />附:<br />MDK中还允许直接使用中断函数,而无须使用汇编代码来处理中断。只须在中断服务子程序加上一些关键字来标识它是一个中断服务子程序,这样在编译器编译的时候会自动在服务子程序的入口和出口加上一些与中断相关的现场保护与恢复汇编指令。<br />中断标识符与您所选的编译器有关。强大的RealView&nbsp;MDK支持三种主流编译器。它们是RealView编译器、Keil&nbsp;CARM编译器以及GNU编译器。在使用不同的编译器时,中断标识符有所不同。现通过举例来说明不同编译器下中断标识符的用法:<br />RealView编译器:<br />__irq&nbsp;void&nbsp;IRQ_Handler&nbsp;(void)&nbsp;{<br />&nbsp;&nbsp;&nbsp;/*&nbsp;the&nbsp;interrupt&nbsp;code&nbsp;*/<br />}<br />Keil&nbsp;CARM编译器:<br />void&nbsp;IRQ_Handler&nbsp;(void)&nbsp;__irq&nbsp;&nbsp;{<br /> &nbsp;/*&nbsp;the&nbsp;interrupt&nbsp;code&nbsp;*/}<br />GNU编译器:<br />void&nbsp;IRQ_Handler&nbsp;(void)&nbsp;__attribute__&nbsp;((interrupt));&nbsp;//&nbsp;Generate&nbsp;Interrupt&nbsp;<br /><br />void&nbsp;IRQ_Handler&nbsp;(void)&nbsp;{<br />&nbsp;&nbsp;&nbsp;/*&nbsp;the&nbsp;interrupt&nbsp;code&nbsp;*/<br />}<br />&nbsp;
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

4

帖子

0

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