我用6410裸奔,首先在NAND的0地址烧写了我自己的BOOT(一下简称“BOOT部分程序”),然后在把用户裸奔程序用仿真器烧写到NAND的第2个BLOCK,上电启动通过BOOT把用户程序下载进DDR里面运行,但是现在进步了中断,具体代码如下:
这是START.S的代码
GET option.inc
GET sfr6410.inc
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr doesnt push because it return to original address)
ldr r0,=$HandleLabel ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
MEND
IMPORT InitDmc ;DMC initialize
;=======================================================
; ENTRY
;=======================================================
AREA Init,CODE,READONLY
ENTRY
b ResetHandler
b HandlerUndef
b HandlerSWI
b HandlerPabort
b HandlerDabort
b .
b HandlerIRQ
b HandlerFIQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerPabort HANDLER HandlePabort
HandlerDabort HANDLER HandleDabort
HandlerIRQ HANDLER HandleIRQ
HandlerFIQ HANDLER HandleFIQ
ResetHandler
[ (SILICON)
bl InitSyscon
]
; bl InitSmc
bl InitDmc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; memport1 drive strength change 3mA->7mA
;;
ldr r3, =0x7F0081D4
ldr r4, =0x55555555
str r4, [r3]
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IMPORT __main
bl __main
b .
;=======================================================
;------------[Syscon Initialize Routine]----------------
InitSyscon PROC
; Peri Port Setup
; Disable WatchDog
; Operating Mode Change
; Set PLL LockTime
; Set PMS valuse and enable PLL
; Set Clock Divider
; Select Clock Source for SYSCLK
; Expand DRAM Port
ldr r0, =0x70000013 ; Peri. Port Setup
mcr p15,0,r0,c15,c2,4 ; 256M(0x7000_0000 ~ 0x7fff_ffff
ldr r0, =rWTCON ; Disable WatchDog
mov r1, #0
str r1,[r0]
[ (SYNCMODE) ; Operating Mode Change
ldr r0, =rOTHERS
ldr r1, [r0]
mov r2, #0x40 ; rOTHERS[6] = "1"
orr r1, r1, r2
str r1, [r0] ; SYNCMUXSEL
;DELAY
NOP
NOP
NOP
NOP
NOP
ldr r2, =((1<<7)) ; SYNCMODE,
orr r1, r1, r2
str r1, [r0] ; Assert SYNCACK, VICSYNCEN
Check_SYNCACK
ldr r1, [r0]
ldr r2, =(0xF<<8)
and r1, r1, r2 ; rOTHERS[11:8]
cmp r1, #0xF00
bne Check_SYNCACK
]
mov r1, #0xff00
orr r1,r1,#0xff ; Lock Time Value, Fin=12MHz - 0x4B1(min)
ldr r0, =rAPLL_LOCK ; APLL Lock Time
str r1, [r0]
str r1, [r0,#0x4] ; MPLL Lock Time
;;Set Clock Divider0
ldr r1, [r0,#0x20] ; Load Clock Divider Value
bic r1, #0x30000
bic r1, #0xff00
bic r1, #0xff
ldr r2, =((PCLK_DIV<<12)|(HCLKx2_DIV<<9)|(HCLK_DIV<<8)|(MPLL_DIV<<4)|(APLL_DIV<<0))
orr r1,r1,r2
str r1, [r0,#0x20] ; CLK_DIV0 Register
;; APLL M,P,S Value & Enable
ldr r1, =((1<<31)|(APLL_MVAL<<16)|(APLL_PVAL<<8)|(APLL_SVAL))
str r1, [r0,#0xC] ; APLL_CON Register
;; MPLL M,P,S Value & Enable
ldr r1, =((1<<31)|(MPLL_MVAL<<16)|(MPLL_PVAL<<8)|(MPLL_SVAL))
str r1, [r0,#0x10] ; MPLL_CON Register
;;Select PLL clock out
ldr r1, [r0, #0x1c]
orr r1,r1,#0x3
str r1, [r0,#0x1c]
;;Expand Memory 1 Port to X32
ldr r1, [r0, #0x120]
bic r1, #0x80 ; ADDR_EXPAND to "0"
str r1, [r0, #0x120] ; MEM_SYS_CFG Register
mov pc,lr
ENDP
;-------------------------------------------------------
;---------------[SMC Initialize Routine]----------------
InitSmc PROC
; Initialize SMC
mov pc,lr
; b main
ENDP
;-------------------------------------------------------
LTORG
ALIGN
AREA IntVector, DATA, READWRITE
^ Exception_Vector
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
END
对以上代码我是那么理解的,我的程序正在DDR里面运行,当中断来的时候程序会跳转到BOOT部分程序的0X18地址,也就是执行b HandlerIRQ这语句,而HandlerIRQ是一个汇编的宏定义:
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr doesnt push because it return to original address)
ldr r0,=$HandleLabel ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
MEND
仔细看就是跳转到了$HandleLabel地址,我在去找$HandleLabel地址到底是多少:
^ Exception_Vector
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
而#define _Exception_Vector (_DRAM_BaseAddress+ 0x07ffff00)
也就是中断一来就跳转到了_Exception_Vector+0x18地址。
然后我在加入以下几行代码:
#define pExceptionRESET (*(u32 *)(_Exception_Vector + 0x0))
#define pExceptionUNDEF (*(u32 *)(_Exception_Vector + 0x4))
#define pExceptionSWI (*(u32 *)(_Exception_Vector + 0x8))
#define pExceptionPABORT (*(u32 *)(_Exception_Vector + 0xc))
#define pExceptionDABORT (*(u32 *)(_Exception_Vector + 0x10))
#define pExceptionRESERVED (*(u32 *)(_Exception_Vector + 0x14))
#define pExceptionIRQ (*(u32 *)(_Exception_Vector + 0x18))
#define pExceptionFIQ (*(u32 *)(_Exception_Vector + 0x1c))
void eExceptionIRQ(void)
{
DisplayLED(0x00);
while(1);
}
void SYSTEM_InitException( void)
{
pExceptionUNDEF = (u32)ExceptionUNDEF;
pExceptionSWI = (u32)ExceptionSWI;
pExceptionPABORT = (u32)ExceptionPABORT;
pExceptionDABORT = (u32)ExceptionDABORT;
#if (VIC_MODE == 1) //0
pExceptionIRQ = (u32)IsrIRQ;
#else
pExceptionIRQ = (u32)eExceptionIRQ;
#endif
pExceptionFIQ = (u32)ExceptionFIQ;
INTC_Init();
#if (VIC_MODE == 0)
SYSTEM_DisableVIC();
#else
SYSTEM_EnableVIC();
#endif
SYSTEM_EnableIRQ();
SYSTEM_EnableFIQ();
}
以上代码的作用是:既然中断来了直接跳转到_Exception_Vector+0x18地址,那我在这地址里面赋值,赋的值就是中断函数的地址,那也就是执行了我的中断函数。
最后我开启串口中断:
INTC_SetVectAddr(uart_num, SW_isr);
INTC_Enable(uart_num);
那么我在PC机上发数据给6410,6410发生串口中断,应为串口中断也是属于普通中断,它也会跳转到eExceptionIRQ执行,一旦执行就会把我的LED灯熄灭,但是我在调试的过程中就没进中断函数 ,我就想不通了,有些兄弟说一定要开启MMU映射,但是我不那么想 ,我想不开启也可以进中断的,现在就是希望各位兄弟能指点下 ,帮我看看我以上的想法对吗? 谢谢各位!
你的这段是烧录到哪里的?
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr doesnt push because it return to original address)
ldr r0,=$HandleLabel ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
BLOCK0?BLOCK2?还是在你的代码里边?我有一篇关于ADS下调试中断的文章,你可以去看下,也许对你有帮助
你的CODE跑在DDR里,不过DDR是被映射在0地址上的吗?
如果不是,你把0地址里面的东西读出来看看。
看这里是否存在向二级中断向量表跳转的代码。