首先,谢谢大家能够进来看我的这个问题。<br />我想请教一个问题:<br />代码:<br /><br />NoInt EQU 0x80<br /><br />USR32Mode EQU 0x10<br />SVC32Mode EQU 0x13<br />SYS32Mode EQU 0x1f<br />IRQ32Mode EQU 0x12<br />FIQ32Mode EQU 0x11<br /><br /><br />;引入的外部标号在这声明<br /> IMPORT OSIntCtxSw ;任务切换函数<br /> IMPORT OSIntExit ;中断退出函数<br /> IMPORT OSTCBCur<br /> IMPORT OSTCBHighRdy<br /> IMPORT OSIntNesting ;中断嵌套计数器<br /> IMPORT StackUsr<br /> IMPORT OsEnterSum<br /><br /> CODE32<br /><br /> PRESERVE8<br /> AREA IRQ,CODE,READONLY<br /><br /> MACRO<br />$IRQ_Label HANDLER $IRQ_Exception_Function<br /><br /> EXPORT $IRQ_Label ; 输出的标号<br /> IMPORT $IRQ_Exception_Function ; 引用的外部标号<br /><br />$IRQ_Label<br /> SUB LR, LR, #4 ; 计算返回地址<br /> STMFD SP!, {R0-R3, R12, LR} ; 保存任务环境<br /> MRS R3, SPSR ; 保存状态<br /> STMFD SP, {R3, SP, LR}^ ; 保存用户状态的R3,SP,LR,注意不能回写<br /> ; 如果回写的是用户的SP,所以后面要调整SP<br /> LDR R2, =OSIntNesting ; OSIntNesting++<br /> LDRB R1, [R2]<br /> ADD R1, R1, #1<br /> STRB R1, [R2]<br /><br /> SUB SP, SP, #4*3<br /> <br /> MSR CPSR_c, #(NoInt | SYS32Mode) ; 切换到系统模式<br /> CMP R1, #1<br /> LDREQ SP, =StackUsr<br /> <br /> BL $IRQ_Exception_Function ; 调用c语言的中断处理程序<br /> <br />; MSR CPSR_c, #(NoInt | SYS32Mode) ; 切换到系统模式<br /> LDR R2, =OsEnterSum ; OsEnterSum,使OSIntExit退出时中断关闭<br /> MOV R1, #1<br /> STR R1, [R2]<br /><br /> BL OSIntExit<br /><br /> LDR R2, =OsEnterSum ; 因为中断服务程序要退出,所以OsEnterSum=0<br /> MOV R1, #0<br /> STR R1, [R2]<br /><br /> MSR CPSR_c, #(NoInt | IRQ32Mode) ; 切换回irq模式<br /> LDMFD SP, {R3, SP, LR}^ ; 恢复用户状态的R3,SP,LR,注意不能回写<br /> ; 如果回写的是用户的SP,所以后面要调整SP<br /> LDR R0, =OSTCBHighRdy<br /> LDR R0, [R0]<br /> LDR R1, =OSTCBCur<br /> LDR R1, [R1]<br /> CMP R0, R1<br /><br /> ADD SP, SP, #4*3 ; <br /> MSR SPSR_cxsf, R3<br /> LDMEQFD SP!, {R0-R3, R12, PC}^ ; 不进行任务切换<br /> LDR PC, =OSIntCtxSw ; 进行任务切换<br /> MEND<br /><br />;/* 以下添加中断句柄,用户根据实际情况改变 */<br /><br />;/*中断*/<br />IRQ_Handler HANDLER IRQ_Exception<br /><br />UART1_Handler HANDLER UART1_Exception<br />;/*定时器0中断*/<br />Timer0_Handler HANDLER Timer0_Exception<br /><br /> END<br /><br />个人理解:<br />这里是定义一个Handler的宏,该宏是用来做进入中断前的处理。<br /><br />问题:<br />为什么在UC/OS-II中添加3个中断句柄,而在一个while(1)的前后台系统中没有定义?<br />是不是该这样理解:<br />进入中断函数有两种方式,一种是C语言的,另一种是汇编语言的,汇编语言就采用了句柄的方式,而在汇编中采用的是在函数名前加_IRQ,来表示该函数为中断函数,两者是等同的作用。如果是这样的话,那用_IRQ方式的句柄,他在进入中断前处理的代码在哪里呢?是编译器自动生成的吗?怎样可以查看?是编译器处理的话,是不是不同的编译器处理的代码有或多或少的区别呢?<br />附:<br />用的是keil的编译环境。<br /><br />用没有人可以系统地讲解一下,谢谢大家了!<br /> |
|