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