开发环境:
宿主机: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