s5pv210的汇编中断

时间:2021-05-08 01:03:33

开发环境:

宿主机:32位的fedora14

开发板:友善的tiny210

交叉编译环境:arm-linux-gcc-4.5.1(友善光盘里提供)

主要内容:

用汇编实现s5pv210的中断,中断的原理请查看友善提供的《linux平台下Mini210S裸机开发指南》的中断部分原理。实验现象是:当把bin文件烧写到sd卡后,上电启动时核心板上的4个led来回闪烁,当按下k1键时,4个led灯全亮,然后恢复到来的状态,4个led灯不停地闪烁,整个程序是用汇编实现的,如果对你有帮助我就非常荣幸了,好了,下边我把汇编代码粘到下面,整个工程我也会上传。源码如下:

@看门狗寄存器
.equ    WTCON,      0xE2700000
@led灯对应管脚寄存器
.equ    GPJ2CON,    0xE0200280      @led  
.equ    GPJ2DAT,    0xE0200284      @led 

@配置向量中断控制器的地址
.equ   VIC0_BASE,           0xF2000000
.equ   VIC1_BASE,           0xF2100000
.equ   VIC2_BASE,           0xF2200000
.equ   VIC3_BASE,           0xF2300000

@VIC0
.equ   VIC0IRQSTATUS,			VIC0_BASE + 0x00
.equ   VIC0FIQSTATUS,			VIC0_BASE + 0x04
.equ   VIC0RAWINTR,				VIC0_BASE + 0x08
.equ   VIC0INTSELECT,			VIC0_BASE + 0x0c
.equ   VIC0INTENABLE,			VIC0_BASE + 0x10
.equ   VIC0INTENCLEAR,			VIC0_BASE + 0x14
.equ   VIC0SOFTINT,				VIC0_BASE + 0x18
.equ   VIC0SOFTINTCLEAR,		    VIC0_BASE + 0x1c
.equ   VIC0PROTECTION,			VIC0_BASE + 0x20
.equ   VIC0SWPRIORITYMASK,		VIC0_BASE + 0x24
.equ   VIC0PRIORITYDAISY,		VIC0_BASE + 0x28
.equ   VIC0VECTADDR,			    VIC0_BASE + 0x100
.equ   VIC0VECPRIORITY,			VIC0_BASE + 0x200
.equ   VIC0ADDR,				    VIC0_BASE + 0xf00
.equ   VIC0PERID0,				VIC0_BASE + 0xfe0
.equ   VIC0PERID1,				VIC0_BASE + 0xfe4
.equ   VIC0PERID2,				VIC0_BASE + 0xfe8
.equ   VIC0PERID3,				VIC0_BASE + 0xfec
.equ   VIC0PCELLID0,			    VIC0_BASE + 0xff0
.equ   VIC0PCELLID1,			    VIC0_BASE + 0xff4
.equ   VIC0PCELLID2,			    VIC0_BASE + 0xff8
.equ   VIC0PCELLID3,			    VIC0_BASE + 0xffc

@VIC1
.equ   VIC1IRQSTATUS,			VIC1_BASE + 0x00
.equ   VIC1FIQSTATUS,			VIC1_BASE + 0x04
.equ   VIC1RAWINTR,				VIC1_BASE + 0x08
.equ   VIC1INTSELECT,			VIC1_BASE + 0x0c
.equ   VIC1INTENABLE,			VIC1_BASE + 0x10
.equ   VIC1INTENCLEAR,			VIC1_BASE + 0x14
.equ   VIC1SOFTINT,				VIC1_BASE + 0x18
.equ   VIC1SOFTINTCLEAR,		    VIC1_BASE + 0x1c
.equ   VIC1PROTECTION,			VIC1_BASE + 0x20
.equ   VIC1SWPRIORITYMASK,		VIC1_BASE + 0x24
.equ   VIC1PRIORITYDAISY,		VIC1_BASE + 0x28
.equ   VIC1VECTADDR,			    VIC1_BASE + 0x100
.equ   VIC1VECPRIORITY,			VIC1_BASE + 0x200
.equ   VIC1ADDR,				    VIC1_BASE + 0xf00
.equ   VIC1PERID0,				VIC1_BASE + 0xfe0
.equ   VIC1PERID1,				VIC1_BASE + 0xfe4
.equ   VIC1PERID2,				VIC1_BASE + 0xfe8
.equ   VIC1PERID3,				VIC1_BASE + 0xfec
.equ   VIC1PCELLID0,				VIC1_BASE + 0xff0
.equ   VIC1PCELLID1,				VIC1_BASE + 0xff4
.equ   VIC1PCELLID2,				VIC1_BASE + 0xff8
.equ   VIC1PCELLID3,				VIC1_BASE + 0xffc

@VIC2
.equ   VIC2IRQSTATUS,			VIC2_BASE + 0x00
.equ   VIC2FIQSTATUS,			VIC2_BASE + 0x04
.equ   VIC2RAWINTR,				VIC2_BASE + 0x08
.equ   VIC2INTSELECT,			VIC2_BASE + 0x0c
.equ   VIC2INTENABLE,			VIC2_BASE + 0x10
.equ   VIC2INTENCLEAR,			VIC2_BASE + 0x14
.equ   VIC2SOFTINT,				VIC2_BASE + 0x18
.equ   VIC2SOFTINTCLEAR,		    VIC2_BASE + 0x1c
.equ   VIC2PROTECTION,			VIC2_BASE + 0x20
.equ   VIC2SWPRIORITYMASK,		VIC2_BASE + 0x24
.equ   VIC2PRIORITYDAISY,		VIC2_BASE + 0x28
.equ   VIC2VECTADDR,			    VIC2_BASE + 0x100
.equ   VIC2VECPRIORITY,			VIC2_BASE + 0x200
.equ   VIC2ADDR,				    VIC2_BASE + 0xf00
.equ   VIC2PERID0,				VIC2_BASE + 0xfe0
.equ   VIC2PERID1,				VIC2_BASE + 0xfe4
.equ   VIC2PERID2,				VIC2_BASE + 0xfe8
.equ   VIC2PERID3,				VIC2_BASE + 0xfec
.equ   VIC2PCELLID0,				VIC2_BASE + 0xff0
.equ   VIC2PCELLID1,				VIC2_BASE + 0xff4
.equ   VIC2PCELLID2,				VIC2_BASE + 0xff8
.equ   VIC2PCELLID3,				VIC2_BASE + 0xffc

@VIC3
.equ   VIC3IRQSTATUS,			VIC3_BASE + 0x00
.equ   VIC3FIQSTATUS,			VIC3_BASE + 0x04
.equ   VIC3RAWINTR,				VIC3_BASE + 0x08
.equ   VIC3INTSELECT,			VIC3_BASE + 0x0c
.equ   VIC3INTENABLE,			VIC3_BASE + 0x10
.equ   VIC3INTENCLEAR,			VIC3_BASE + 0x14
.equ   VIC3SOFTINT,				VIC3_BASE + 0x18
.equ   VIC3SOFTINTCLEAR,		    VIC3_BASE + 0x1c
.equ   VIC3PROTECTION,			VIC3_BASE + 0x20
.equ   VIC3SWPRIORITYMASK,		VIC3_BASE + 0x24
.equ   VIC3PRIORITYDAISY,		VIC3_BASE + 0x28
.equ   VIC3VECTADDR,		    VIC3_BASE + 0x100
.equ   VIC3VECPRIORITY,			VIC3_BASE + 0x200
.equ   VIC3ADDR,			    VIC3_BASE + 0xf00
.equ   VIC3PERID0,				VIC3_BASE + 0xfe0
.equ   VIC3PERID1,				VIC3_BASE + 0xfe4
.equ   VIC3PERID2,				VIC3_BASE + 0xfe8
.equ   VIC3PERID3,				VIC3_BASE + 0xfec
.equ   VIC3PCELLID0,				VIC3_BASE + 0xff0
.equ   VIC3PCELLID1,				VIC3_BASE + 0xff4
.equ   VIC3PCELLID2,				VIC3_BASE + 0xff8
.equ   VIC3PCELLID3,				VIC3_BASE + 0xffc

@外部中断控制器地址
.equ		EXT_INT_0_CON,  			0xE0200E00
.equ		EXT_INT_1_CON,  			0xE0200E04
.equ		EXT_INT_2_CON,  			0xE0200E08
.equ		EXT_INT_3_CON,  			0xE0200E0C

.equ		EXT_INT_0_MASK,   		0xE0200F00
.equ		EXT_INT_1_MASK,   		0xE0200F04
.equ		EXT_INT_2_MASK,   		0xE0200F08
.equ		EXT_INT_3_MASK,   		0xE0200F0C

.equ		EXT_INT_0_PEND,   		0xE0200F40
.equ		EXT_INT_1_PEND,   		0xE0200F44
.equ		EXT_INT_2_PEND,   		0xE0200F48
.equ		EXT_INT_3_PEND,   		0xE0200F4C

@外部中断16对应的gpio控制寄存器
.equ        GPH2CON,                0xE0200C40

.equ   pExceptionRESET,        0xD0037400
.equ   pExceptionUNDEF,        0xD0037404
.equ   pExceptionSWI,          0xD0037408
.equ   pExceptionPABORT,       0xD003740C
.equ   pExceptionDABORT,       0xD0037410
.equ   pExceptionRESERVED,     0xD0037414
.equ   pExceptionIRQ,          0xD0037418
.equ   pExceptionFIQ,          0xD003741C 

.global _start
.global IRQ_handle

_start:
	@调用关闭看门狗函数
	bl disable_watchdog
	// 开中断
	mrs r0, cpsr  
    bic r0, r0, #0x00000080     /* 清楚第7位,IRQ中断禁止位,写0使能IRQ */  
    msr cpsr, r0	
	@调用设置异常向量表函数
	bl set_exception_vector_tables
	@调用设置中断控制器函数
	bl init_interrupt_controller
	@调用初始化外部中断16函数
	bl set_external_16_interrupt        
	@调用使能外部中断函数
	bl enable_external_16_interrupt
	@调用设置led gpio管脚函数
	bl set_led_gpio
	@调用led灯循环点亮的主函数
	bl main	

_exception_undefine:   .word  exception_undefine
_exception_swi:        .word  exception_swi
_exception_pabort:     .word  exception_pabort
_exception_dabort:     .word  exception_dabort
_exception_reserved:   .word  exception_reserved
_exception_irq:        .word  IRQ_handle
_exception_fiq:        .word  IRQ_handle

_irq_handler:          .word  irq_handler

.balignl 16,0xdeadbeef
@关看门狗
disable_watchdog:
	ldr	r0, =WTCON			
	mov	r1, #0
	str	r1, [r0]

	mov pc, lr
@设置异常向量表
set_exception_vector_tables:
	@配置中断向量表
	ldr r3, =pExceptionUNDEF
	ldr r4, _exception_undefine
	str r4, [r3]               @设置undefined
	
	ldr r3, =pExceptionSWI
	ldr r4, _exception_swi
	str r4, [r3]               @设置SWI
	
	ldr r3, =pExceptionPABORT
	ldr r4, _exception_pabort
	str r4, [r3]               @设置prefetch_abort
	
	ldr r3, =pExceptionDABORT
	ldr r4, _exception_dabort
	str r4, [r3]               @设置data_abort
	
	ldr r3, =pExceptionRESERVED
	ldr r4, _exception_reserved
	str r4, [r3]               @设置reserved
	
	ldr r3, =pExceptionIRQ
	ldr r4, _exception_irq
	str r4, [r3]               @设置irq
	
	ldr r3, =pExceptionFIQ
	ldr r4, _exception_fiq
	str r4, [r3]               @设置fiq
	
	mov pc, lr

@初始化中断控制器
init_interrupt_controller:
	@禁止所有中断
	ldr r0, =VIC0INTENCLEAR
	ldr r1, =VIC1INTENCLEAR
	ldr r2, =VIC2INTENCLEAR
	ldr r3, =VIC3INTENCLEAR
	ldr r4, =0xffffffff
	str r4, [r0]
	str r4, [r1]
	str r4, [r2]
	str r4, [r3]
	
	@选择中断类型为IRQ
	ldr r0, =VIC0INTSELECT
	ldr r1, =VIC1INTSELECT
	ldr r2, =VIC2INTSELECT
	ldr r3, =VIC3INTSELECT
	ldr r4, =0x0
	str r4, [r0]
	str r4, [r1]
	str r4, [r2]
	str r4, [r3]
	@清除需要处理的中断的中断处理函数的地址
	ldr r0, =VIC0ADDR
	ldr r1, =VIC1ADDR
	ldr r2, =VIC2ADDR
	ldr r3, =VIC3ADDR
	ldr r4, =0x0
	str r4, [r0]
	str r4, [r1]
	str r4, [r2]
	str r4, [r3]
	
	mov pc, lr

@设置外部中断16引脚
set_external_16_interrupt:
	@配置GPH2_0为中断功能
	ldr r1, =GPH2CON
	ldr r2, =0x0000000f
	str r2, [r1]
	@配置外部中断16为下降沿触发
	ldr r1, =EXT_INT_2_CON
	ldr r2, =0x00000002
	str r2, [r1]
	@unmasked外部中断16
	ldr r1, =EXT_INT_2_MASK
	ldr r2, =0xfe
	str r2, [r1]
	
	mov pc, lr

@使能外部中断16
enable_external_16_interrupt:
	ldr r2, =0x10000
	ldr r0, =VIC0INTENABLE
	ldr r1, [r0]
	orr r1, r1, r2
	str r1, [r0]
	
	mov pc, lr
	
@实现4个led循环点亮	
main:
	mov r3, #0x0
ledloop:
	cmp r3, #4
	beq main
	
	@点亮4个led中的一个
	mov r4, #1
	ldr r1, =GPJ2DAT
	ldr r2, [r1]
	bic r2, r2, r4, lsl r3
	str r2, [r1]
	
	@调用延时函数,进行延时
	bl delay
	
	@熄灭上面刚点亮的led灯
	ldr r2, [r1]
	orr r2, r2, r4, lsl r3
	str r2, [r1]
	add r3, #1
	
	b ledloop
	
	mov pc, lr

@设置led灯对应的引脚状态
set_led_gpio:
	@led灯对应的引脚为输出,也就是GPJ2_0,GPJ2_1,GPJ2_2,GPJ2_3为输出
	ldr r1, =GPJ2CON
	ldr r2, [r1]
	ldr r3, =0x00001111
	orr r2, r2, r3
	str r2, [r1]
	
	@关闭所有的led灯
	mov r4, #0x0f
	ldr r1, =GPJ2DAT
	ldr r2, [r1]
	orr r2, r2, r4
	str r2, [r1]
	
	mov pc, lr

@irq异常处理函数
IRQ_handle:
	@设置中断模式的栈
	ldr sp, =0xD0037F80
	@保存现场
	sub lr, lr, #4				
	stmfd sp!, {r0-r12, lr}
	@跳转到中断处理函数
	bl	irq_handler		
	@恢复现场
	ldmfd sp!, {r0-r12, pc}^
@irq中断服务函数
irq_handler:
	@全部点亮4个led灯,表示进入中断
	ldr r1, =GPJ2DAT
	ldr r2, =0x00
	str r2, [r1]
	
	@清除需要处理的中断的中断处理函数的地址
	@清除需要处理的中断的中断处理函数的地址
	ldr r0, =0xF2000F00
	ldr r4, =0x0
	str r4, [r0]
	@清除penging bit
	ldr r0, =EXT_INT_2_PEND
	ldr r1, =0x01
	str r1, [r0]
	
	mov pc, lr

@延时函数	
delay:
	ldr r0, =0xffffff
delay_loop:
	cmp r0, #0
	sub r0, r0, #1
	bne delay_loop
	
	mov pc, lr
	
@其他几个异常处理函数,这里什么也没做,只是执行了一个nop
exception_undefine:
	nop
exception_swi:
	nop
exception_pabort:
	nop
exception_dabort:
	nop
exception_reserved:
	nop
exception_fiq:
	nop

上面就是.s的汇编文件,整个工程的代码链接是:http://download.csdn.net/detail/xie0812/7649535