mini2440调试进不了中断解决方案
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ldr r0,=SRCPND str r1,[r0] ldr r0,=INTPND str r1,[r0] ldr r0,=INTSUBMSK ldr r1,=0x7fff @all sub interrupt disable, 2002/04/10 str r1,[r0] @@@设置频率 mov r1, #CLK_CTL_BASE ldr r2, clock_locktime str r2, [r1, #oLOCKTIME] mov r1, #CLK_CTL_BASE ldr r2, clkdivn_value str r2, [r1, #oCLKDIVN] mrc p15, 0, r1, c1, c0, 0 @ read ctrl register orr r1, r1, #0xc0000000 @ Asynchronous mcr p15, 0, r1, c1, c0, 0 @ write ctrl register mov r1, #CLK_CTL_BASE ldr r2, mpll_value @ clock default str r2, [r1, #oMPLLCON] @@@@初始化串口 InitUART: @set GPIO for UART mov r1, #GPIO_CTL_BASE add r1, r1, #oGPIO_H ldr r2, gpio_con_uart str r2, [r1, #oGPIO_CON] ldr r2, gpio_up_uart str r2, [r1, #oGPIO_UP] ldr r1, SerBase mov r2, #0x0 str r2, [r1, #oUFCON] str r2, [r1, #oUMCON] mov r2, #0x3 str r2, [r1, #oULCON] ldr r2, =0x245 str r2, [r1, #oUCON] .equ UART_BRD , ((UART_PCLK / (UART_BAUD_RATE*16)) - 1) mov r2, #UART_BRD str r2, [r1, #oUBRDIV] mov r3, #100 InitUART1:
Hale Waihona Puke ldr r0,=0x33ffff18 ldr r1,=ISR_IRQ @ if there isnt "subs pc,lr,#4" at 0x18, 0x1c str r1,[r0] bl memsetup @ 设置存储控制器以使用 SDRAM bl copy_2th_to_sdram @ 将第二部分代码复制到 SDRAM bl create_page_table @ 设置页表 bl mmu_init @ 启动 MMU ldr sp, =0xB2000000 @ 重设栈指针,指向 SDRAM 顶端(使用虚拟地址) ldr pc,=0xB0004000 @ 跳到 SDRAM 中继续执行第二部分代码 halt_loop: b halt_loop PrintChar: mov r1, #UART0_CTL_BASE PrintChar1: ldr r2, [r1, #oUTRSTAT] tst r2, #UTRSTAT_TX_EMPTY beq PrintChar1 str r0, [r1, #oUTXHL] mov pc, lr PrintStr: stmfd sp!, {r4, lr} movs r4, r0 ldmeqfd sp!, {r4, pc} PrintStr1: ldrb r0, [r4], #1
subs r3, r3, #0x1 bne InitUART1 @@@@@@@@@@@@@@进入中断模式,并设置堆栈指针@@@@@@@@@@ mrs r0,cpsr orr r1,r0,#0xd2 msr cpsr_c,r1 ldr sp,=3072 msr ldr mov str ldr msr cpsr_c, #0xdf @进入系统模式 r0,=rINTMSK r1,#0xfffffbff@@@允许中断 r1,[r0] sp,=4096 cpsr_c, #0x5f @设置 I-bit=0,开 IRQ 中断
本文原创:在编程的过程中,遇到了很多问题,困扰了自己多时,所以, 感觉有必要写出来,与大家分享下。 经常看到有人问这样的问题, 自己用 mini2440 开发板调试中断的时候进不 去中断,要了解中断,就需要了解中断机制和中断向量表。相信看这篇文 章的读者肯定知道什么是中断以及中断机制了, 由于中断的编程跟 2440 的 启动方式有关系,因此我们先说下启动方式吧。 S3C2440 支持两种启动模式:NAND 和非 NAND(这里是 NOR FLASH)具体取 决与 OM0,OM1 两个引脚。同时我们这里再加一种情况,就是程序在 SDRAM 中运行(或者说用 JTAG 调试的时候的情况)。我们就从这三种情况来说明 中断如何实现。 (1) 当从 NAND 启动时,CPU 会自动从 NAND flash 中读取前 4KB 的数据放 置在片内 SRAM 里(S3C2440 是集成到内部的叫做 Steppingstone),同时把这段 片内 SRAM 映射到 nGCS0 片选的空间(即 0x00000000)。 CPU 是从 0x00000000 开始执行的,也就是 NAND FLASH 里面的前 4KB 内容。由于 NAND FLASH 的 结构决定了 NAND FLASH 没有地址线,而且存取都是以页来进行的,这就是 为什么 CPU 会自动从 NAND FLASH 读取前面 4KB 到内部 SRAM 里的原因。我 们很快会想到一个问题,那就是 4KB 以后的代码如何执行。这就是程序员 需要做的工作了,在前面 4KB 的代码中,必须含有将以后的主程序代码拷 贝到 SDRAM 中运行,完成拷贝,以及 4KB 的启动代码后,跳转到 SDRAM 中 执行其余程序。这里我就不详细介绍了,可以查看 mini2440 例子中的启动 代码。 注意: 这里必须明确的一点就是 NAND 地址不是线性的, 程序不能直接运行, 必须拷贝到线性 RAM 中。 (2) 当从 NOR 启动时,NOR FLASH 被映射到 0x00000000 地址(就是 nGCS0, 这里就不需要片内 SRAM 来辅助了,所以片内 SRAM 的起始地址还是 0x40000000)。然后 CPU 从 0x00000000 开始执行(也就是在 Norflash 中执 行)。这种情况是最简单的,只要将程序的下载地址设置到 0x00000000 即 可。 在实际的开发中, 一般可以把 bootloader 烧入到 Norflash, 程序运行可以通 过串口交互,进行一定的操作,比如下载,调试。这样就很可以很方便的 调试你的一些代码。Norflash 中的 Bootloader 还可以烧录内核到 Norflash 等等功能。 (3) 当程序在 SDRAM 运行,由于 SDRAM 的地址是 0x30000000,因此运行程 序需要下载到 0x30000000,当程序在内存中运行,由于发生中断时,会跳 到 0x00000018, 因此在 SDRAM 运行时, 要进入中断, 有两种方法进行实现: 一是 MMU 配置,使 0x30000000 映射到 0x00000000 地址,当中断发生时, 跳到 0x30000018 的地址。二是在 0x00000000 的内部 SDRAM 中存中断向量 表,或者在 0x00000000 的 NAND FLASH 位置放中断向量表。
.code 32 .text .align 4 .global _start _start: b ResetHandle HandlerUndef: b HandlerUndef @@@未定义指令中止模式的向量地址 HandlerSWI: b HandlerSWI @@@管理模式的向量地址,通过 SWI 指令进入此模式 HandlerPabort: b HandlerPabort @@@指令预取终止导致的异常的向量地址 HandlerDabort: b HandlerDabort @@@数据访问终止导致的异常的向量地址 b . ldr pc, =HandlerIRQ @@@中断模式的向量地址 ldr pc, =HandlerFIQ @@@快中断模式的向量地址 b . HandlerFIQ: HANDLER HandleFIQ HandlerIRQ: HANDLER HandleIRQ @@@@@@@中断二级表,在这里区别是什么中断,然后跳入相应的中断进行处理 ISR_IRQ: sub lr, lr, #4 @ compute the return address stmfd sp!,{r0-r12,lr} @ save r8, r9, lr adr r0,Say_Hello bl PrintStr ldr r9,=INTOFFSET ldr r9,[r9] @ldr r8,=HandleEINT0 ldr r8,=0xB3ffff20//这里用的是虚拟地址, 因为映射后 HandleEINT0==0xB3ffff20 add r8,r8,r9,lsl #2 ldr r8,[r8] mov lr, pc @ the pc is the address ofIRQ_return mov pc, r8 ldmia sp!, {r0-r12,pc}^ @ restore the r8,r9,pc(lr) @@@@@@@RESET ResetHandle: ldr sp, =4096 @ 设置栈指针,以下都是 C 函数,调用前需要设好栈 bl disable_watch_dog @ 关闭 WATCHDOG,否则 CPU 会不断重启 ldr r0,=INTMSK ldr r1,=0xffffffff @all interrupt disable 不使能中断 str r1,[r0]
下面是自己在 MMU 开启的情况下,中断的应用实例: 文件名:head.s @*************************************************************** ********** @ File:head.S @ 功能: 设置 SDRAM, 将第二部分代码复制到 SDRAM, 设置页表, 启动 MMU, @ 然后跳到 SDRAM 继续执行 @*************************************************************** **********
.global PrintStr @************串口输出字符串函数*******************@ .include "2440addr.inc" @************引用 2440 头文件 ************************@ .include "Memcfg.inc" .equ ISR_BADDR , 0xB3ffff00 @**************中断映射后的地址 *****************@ .equ INTOFFSET , 0x4a000014 @Interruot r=est source offset .equ rINTMSK ,0x4a000008 @//Interrupt mask control @频率的设置参数定义 .equ CLKDIV_VAL , 5 @ 0=1:1:1, 1=1:1:2, 2=1:2:2, 3=1:2:4, 4=1:4:4, 5=1:4:8, 6=1:3:3, 7=1:3:6. .equ M_MDIV , 92 @ Fin=12.0MHz Fout=304.8MHz .equ M_PDIV , 1 @ 1 .equ M_SDIV , 1 @ 2 .equ U_MDIV , 56 @ Fin=12MHz Fout=48MHz .equ U_PDIV , 2 .equ U_SDIV , 2 @宏定义 定义 HANDLER 宏 .macro HANDLER $HandleLabel sub sp,sp,#4 stmfd sp!,{r0} ldr r0,=\$HandleLabel ldr r0,[r0] str r0,[sp,#4] ldmfd sp!,{r0,pc} .endm @@@@@@****************程序入口********************@@@@@@@@