zoukankan      html  css  js  c++  java
  • GNU μC/OS-II 在 S3C2440 上中断的实现

    上一篇文章介绍了S3c2440的中断体系结构,今天我们来分析一下GNU-uC/OS-II在S3c2440上中断的实现。

    首先找到IRQ的中断的向量,位于 2440init.S :

    OK ,我们通过名字找到了这个函数:

    OS_CPU_IRQ_ISR:
    
    	STMFD   SP!, {R1-R3}		           
    	MOV     R1, SP
    	ADD     SP, SP, #12                   
    	SUB     R2, LR, #4             			
    
    	MRS     R3, SPSR				       
    
    	MSR     CPSR_cxsf, #SVCMODE|NOINT 
    
    	STMFD   SP!, {R2}			             
    	STMFD   SP!, {R4-R12, LR}			
    
    	LDMFD   R1!, {R4-R6}				
    	STMFD   SP!, {R4-R6}				
    	STMFD   SP!, {R0}			    	      
    
    	STMFD   SP!, {R3}				        
    	LDR     R0,=OSIntNesting       		        
    	LDRB    R1,[R0]
    	ADD     R1,R1,#1
    	STRB    R1,[R0]
    
    	CMP     R1,#1                   		       
    	BNE     1f
    
    	LDR     R4,=OSTCBCur            		
    	LDR     R5,[R4]
     	STR     SP,[R5]  
    1:
    	MSR    	CPSR_c,#IRQMODE|NOINT   	
    	LDR     R0, =INTOFFSET
        LDR     R0, [R0]
    	LDR     R1, =INTMSK
    	LDR     R1, [R1]
    	MOV     R3, #1
    	LSL     R4, R3,R0
    	TST     R4, R1
    	BNE	2f
    	
        LDR     R1, =IRQ_STARTADDRESS
    	MOV     LR, PC
        LDR     PC, [R1, R0, LSL #2]
    
    2:
    	LDR     R0, =INTOFFSET
        LDR     R0, [R0]
    	MOV     R1, #1
    	MOV     R1, R1, LSL R0
    	LDR     R0, =SRCPND
    	LDR     R2, [R0]
    	ORR     R2, R1,R2
    	STR     R2, [R0]
    
    	LDR     R0, =INTPND	
    	LDR     R2, [R0]
    	ORR     R2, R1,R2
    	STR     R2, [R0]	
    	
    	MSR	CPSR_c,#SVCMODE|NOINT
    	BL 	OSIntExit
    
    	LDMFD   SP!,{R4}
    	MSR	SPSR_cxsf,R4
    	LDMFD   SP!,{R0-R12,LR,PC}^	   	       
    

    有点长,我们挑关键的部分分析。
    看这三行代码:

    LDR     R1, =IRQ_STARTADDRESS
    MOV     LR, PC
    LDR     PC, [R1, R0, LSL #2]
    

    IRQ_STARTADDRESS 是这样定义的:

    .equ IRQ_STARTADDRESS , 0x33ffff00

    当前PC保存到LR,然后PC直接跳到了 R1 + R0 * 4 这个地址处(LSL #2 代表左移2位,相当于 *4)。

    R0的值来自这个寄存器:

    LDR     R0, =INTOFFSET
    LDR     R0, [R0]
    

    上一篇文章中我们也说过了,INTOFFSET 这个寄存器可以查出当前是哪个中断源在发生请求。

    假如现在Timer1请求中断,那么 INTOFFSET 的值就是 11.

    R1 + R0 * 4 的结果计算得出就是 0x33FFFF2C 。

    这个地址处是什么数据呢?

    我们在Timer初始化程序中找到了这个:

    pIRQ_TIMER1 = (uint32)OSTickISR;

    头文件中找到了这个:

    OK,这样就在 0x33FFFF2C 地址处存储了 OSTickISR 的入口地址,从而就执行了Timer1的中断服务程序。

    执行完ISR之后,汇编的那段程序之后又完成了清中断的操作。

    其实在这个过程中有一个要点容易被忽视,IRQ异常发生时,PC跳转到异常向量处,那么IRQ异常向量应该存储在 0x18 这个位置处的啊,可我们一开始说到的是执行 "b OS_CPU_IRQ_ISR" 这条语句,它的地址应该是0x30000018呀(我们的程序在SDRAM中运行,如图定义):

    可为什么执行的是它呢?

    这个时候MMU这位大将就要派上用场了,程序中通过这条语句将地址做了映射,

    MMU_SetMTT(0x00000000,0x03f00000,(uint32)_start,RW_CB)

    所以找到的就是0x30000018位置处的向量啦。

  • 相关阅读:
    linux安装python3
    web模拟终端 --使用shellinabox
    linux防火墙和xshell的链接
    Linux安装在虚拟机上
    DRF(django-rest_framework)框架
    Pycharm常用快捷键
    普通脚本调用django程序
    Pycharm安装模块提示module 'pip' has no attribute 'main'的问题
    Django的ModelForm
    面向对象(常用和特殊的创建类)
  • 原文地址:https://www.cnblogs.com/GyForever1004/p/8361988.html
Copyright © 2011-2022 走看看