最近,在写一个支持usb通信的bootloader,我的系统是这样的:
CPU ->S3C2410A,(内部集成4KB的SRAM,以支持Nand Flash的启动)
FLASH ==〉64M的Nand Flash
SDRAM ==〉64M
我的程序基于三星的S3C2410X USB downloader的 ,因为三星的程序是 针对NOR FLASH,而我们系统的非易失存储器是NAND FLASH,所以我需要改动它以支持我们的系统。
程序的开发环境是ADS1.2;我的系统的启动代码大概有30KB,从Flash的0x0开始存放。程序的流程是这样的:系统加电后,NAND Flash 的前4KB程序会自动地流入SRAM中,自动执行,在SRAM中的程序在完成CPU模式,中断,时钟频率,电源,存储器和堆栈等的初始化后,把启动代码拷贝一份到SDRAM中,然后程序跳转到SDRAM中接着执行后面的代码。
程序的编译链接我采用U-boot的思路,使起始代码地址无关,然后用一条"ldr pc,main"指令,使程序转移到main函数的编译地址。我的想法是要让程序从地址0x33f00000开始编译,因此我在ADS中设置RO Base=0x33f000000,没有设置RW Base。在用AXD调试程序时,程序从0x33f00000开始运行,很正常,也能够直接跳入到C代码部分的main函数执行。当我把启动代码直接烧入到NAND FLASH 后,问题出现了:当我的代码量小于4KB时,也就是说程序还在SRAM里执行时一切正常,而当代码量大于4KB时,程序立马就死掉(通过点灯发现,第一句代码都没执行),也就是说程序从SRAM跳往SDRAM里执行时没有成功。
起初我认为是SDRAM 初始化的问题,但我往内存里写数据再读出,数据正确。反复调试,觉得会不会是代码的链接问题,在程序中,我把启动代码拷贝到了内存的0x33f00000处,因为程序的编译地址是从0x33f00000处开始执行的;用存储器地址加载指令ldr将main函数的入口地址赋给pc,我想程序应该可以执行的啊,可程序总是死掉。=========望各位指点指点。
程序初始化代码如下:
 GET option.s
 GET memcfg.s
 GET 2410addr.s
 
 IMPORT nand_read_ll
 IMPORT Port_Init
DELAY       EQU     0x200
R1_iA   EQU (1<<31)
R1_nF   EQU (1<<30)
 
BIT_SELFREFRESH EQU (1<<22)
;Pre-defined constants
USERMODE    EQU  0x10
FIQMODE     EQU  0x11
IRQMODE     EQU  0x12
SVCMODE     EQU  0x13
ABORTMODE   EQU  0x17
UNDEFMODE   EQU  0x1b
MODEMASK    EQU  0x1f
NOINT       EQU  0xc0
;The location of stacks
UserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~ 
SVCStack        EQU (_STACK_BASEADDRESS-0x2800)  ;0x33ff5800 ~
UndefStack EQU (_STACK_BASEADDRESS-0x2400)  ;0x33ff5c00 ~
AbortStack EQU (_STACK_BASEADDRESS-0x2000)  ;0x33ff6000 ~
IRQStack        EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 ~
FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ~ 
;Check if tasm.exe(armasm -16 ...@ADS 1.0) is used.
 GBLL    THUMBCODE
 [ {CONFIG} = 16 
THUMBCODE SETL  {TRUE}
     CODE32
     |   
THUMBCODE SETL  {FALSE}
     ]
     MACRO
 MOV_PC_LR
     [ THUMBCODE
            bx lr
     |
            mov pc,lr
     ]
 MEND
     MACRO
 MOVEQ_PC_LR
     [ THUMBCODE
         bxeq lr
     |
            moveq pc,lr
     ]
 MEND
;---------------------------------------------------------------------------
; 4 LED light function
; The LEDs are located below AMD Flash ROM
 MACRO
 LED_ON $data
 LDR     r10, =0x56000054        
 LDR     r11, =$data
 MOV     r11, r11, lsl #4
   STR     r11, [r10]
    MEND
;---------------------------------------------------------------------------
     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 does't 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  |Image$$RO$$Limit|  ; End of ROM code (=start of ROM data)
 IMPORT  |Image$$RW$$Base|   ; Base of RAM to initialise
 IMPORT  |Image$$ZI$$Base|   ; Base and limit of area
 IMPORT  |Image$$ZI$$Limit|  ; to zero initialise
 
 IMPORT  Main    ; The main entry of mon program 
 
 AREA    Init,CODE,READONLY
ENTRY
 ;1)The code, which converts to Big-endian, should be in little endian code.
 ;2)The following little endian code will be compiled in Big-Endian mode. 
 ;  The code byte order should be changed as the memory bus width.
 ;3)The pseudo instruction,DCD can't be used here because the linker generates error.
 ASSERT :DEF:ENDIAN_CHANGE
 b ResetHandler
 [ ENDIAN_CHANGE
     ASSERT  :DEF:ENTRY_BUS_WIDTH
     [ ENTRY_BUS_WIDTH=32
  b ChangeBigEndian     ;DCD 0xea000007 
     ]
     
     [ ENTRY_BUS_WIDTH=16
  andeq r14,r7,r0,lsl #20   ;DCD 0x0007ea00
     ]
     
     [ ENTRY_BUS_WIDTH=8
  streq r0,[r0,-r10,ror #1] ;DCD 0x070000ea
            ]
 |
     b ResetHandler  
     ]
 b HandlerUndef ;handler for Undefined mode
 b HandlerSWI ;handler for SWI interrupt
 b HandlerPabort ;handler for PAbort
 b HandlerDabort ;handler for DAbort
 b .  ;reserved
 b HandlerIRQ ;handler for IRQ interrupt 
 b HandlerFIQ ;handler for FIQ interrupt
;@0x20
 b EnterPWDN
ChangeBigEndian
;@0x24
 [ ENTRY_BUS_WIDTH=32
     DCD 0xee110f10 ;0xee110f10 => mrc p15,0,r0,c1,c0,0
     DCD 0xe3800080 ;0xe3800080 => orr r0,r0,#0x80;  //Big-endian
     DCD 0xee010f10 ;0xee010f10 => mcr p15,0,r0,c1,c0,0
 ]
 [ ENTRY_BUS_WIDTH=16
     DCD 0x0f10ee11
     DCD 0x0080e380 
     DCD 0x0f10ee01 
 ]
 [ ENTRY_BUS_WIDTH=8
     DCD 0x100f11ee 
     DCD 0x800080e3 
     DCD 0x100f01ee 
     ]
 DCD 0xffffffff  ;swinv 0xffffff is similar with NOP and run well in both endian mode. 
 DCD 0xffffffff
 DCD 0xffffffff
 DCD 0xffffffff
 DCD 0xffffffff
 b ResetHandler
 
;Function for entering power down mode
; 1. SDRAM should be in self-refresh mode.
; 2. All interrupt should be maksked for SDRAM/DRAM self-refresh.
; 3. LCD controller should be disabled for SDRAM/DRAM self-refresh.
; 4. The I-cache may have to be turned on. 
; 5. The location of the following code may have not to be changed.
;void EnterPWDN(int CLKCON); 
EnterPWDN   
 mov r2,r0  ;r2=rCLKCON
 tst r0,#0x8  ;POWER_OFF mode?
 bne ENTER_POWER_OFF
ENTER_STOP 
 ldr r0,=REFRESH  
 ldr r3,[r0]  ;r3=rREFRESH 
 mov r1, r3
 orr r1, r1, #BIT_SELFREFRESH
 str r1, [r0]  ;Enable SDRAM self-refresh
 mov r1,#16     ;wait until self-refresh is issued. may not be needed.
0 subs r1,r1,#1
 bne %B0
 ldr r0,=CLKCON  ;enter STOP mode.
 str r2,[r0]    
 mov r1,#32
0 subs r1,r1,#1 ;1) wait until the STOP mode is in effect.
 bne %B0  ;2) Or wait here until the CPU&Peripherals will be turned-off
   ;   Entering POWER_OFF mode, only the reset by wake-up is available.
 ldr r0,=REFRESH ;exit from SDRAM self refresh mode.
 str r3,[r0]
 
 MOV_PC_LR
ENTER_POWER_OFF 
 ;NOTE.
 ;1) rGSTATUS3 should have the return address after wake-up from POWER_OFF mode.
 
 ldr r0,=REFRESH  
 ldr r1,[r0]  ;r1=rREFRESH 
 orr r1, r1, #BIT_SELFREFRESH
 str r1, [r0]  ;Enable SDRAM self-refresh
 mov r1,#16     ;Wait until self-refresh is issued,which may not be needed.
0 subs r1,r1,#1
 bne %B0
 ldr  r1,=MISCCR
 ldr r0,[r1]
 orr r0,r0,#(7<<17)  ;Make sure that SCLK0:SCLK->0, SCLK1:SCLK->0, SCKE=L during boot-up 
 str r0,[r1]
 ldr r0,=CLKCON
 str r2,[r0]    
 b .   ;CPU will die here.
 
WAKEUP_POWER_OFF
 ;Release SCLKn after wake-up from the POWER_OFF mode.
 ldr  r1,=MISCCR
 ldr r0,[r1]
 bic r0,r0,#(7<<17)  ;SCLK0:0->SCLK, SCLK1:0->SCLK, SCKE:L->H
 str r0,[r1]
 ;Set memory control registers
     ldr r0,=SMRDATA
 ldr r1,=BWSCON ;BWSCON Address
 add r2, r0, #52 ;End address of SMRDATA
0       
 ldr r3, [r0], #4    
 str r3, [r1], #4    
 cmp r2, r0  
 bne %B0
 mov r1,#256
0 subs r1,r1,#1 ;1) wait until the SelfRefresh is released.
 bne %B0  
 
 ldr r1,=GSTATUS3  ;GSTATUS3 has the start address just after POWER_OFF wake-up
 ldr r0,[r1]
 mov pc,r0
 LTORG   
HandlerFIQ      HANDLER HandleFIQ
HandlerIRQ      HANDLER HandleIRQ
HandlerUndef    HANDLER HandleUndef
HandlerSWI      HANDLER HandleSWI
HandlerDabort   HANDLER HandleDabort
HandlerPabort   HANDLER HandlePabort
IsrIRQ  
 sub sp,sp,#4       ;reserved for PC
 stmfd sp!,{r8-r9}   
 
 ldr r9,=INTOFFSET
 ldr r9,[r9]
 ldr r8,=HandleEINT0
 add r8,r8,r9,lsl #2
 ldr r8,[r8]
 str r8,[sp,#8]
 ldmfd sp!,{r8-r9,pc}
;=======
; ENTRY  
;=======
ResetHandler
  
 LED_ON 0x8
   
 ldr r0,=WTCON       ;watch dog disable 
 ldr r1,=0x0         
 str r1,[r0]
 ldr r0,=INTMSK
 ldr r1,=0xffffffff  ;all interrupt disable
 str r1,[r0]
 ldr r0,=INTSUBMSK
 ldr r1,=0x3ff  ;all sub interrupt disable
 str r1,[r0]
 ;feng add
 
 ldr     r0, = INTMOD
    mov r1, #0x0        ; set all interrupt as IRQ (not FIQ)
    str     r1, [r0]
    
 ; configure GPIO pins
    bl  Port_Init
    
        
    ; CLKDIVN
    ldr r0,=CLKDIVN
    ldr r1,=0x3     ; 1:2:4
    str r1,[r0]
    ; delay
    mov     r0, #DELAY
5   subs    r0, r0, #1
    bne     %B5    
    ; MMU_SetAsyncBusMode FCLK:HCLK= 1:2
    ands r1, r1, #0x2
    beq %F1
    mrc p15,0,r0,c1,c0,0
    orr r0,r0,#R1_nF:OR:R1_iA
    mcr p15,0,r0,c1,c0,0
    
1        
 ;To reduce PLL lock time, adjust the LOCKTIME register. 
 ldr r0,=LOCKTIME
 ldr r1,=0xffffff
 str r1,[r0]
    ; delay
    mov     r0, #DELAY
5   subs    r0, r0, #1
    bne     %B5
    
            
    ;Configure MPLL
    ldr r0,=MPLLCON          
    ldr r1,=((0x5c<<12)+(0x4<<4)+0x0)  ;Fin=12MHz,Fout=200MHz
    str r1,[r0]
    ; delay
    mov     r0, #DELAY
5   subs    r0, r0, #1
    bne     %B5
    ;Configure UPLL
    ldr     r0, =UPLLCON          
    ldr     r1, =((0x48<<12)+(0x3<<4)+0x2)  ;Fin=12MHz, Fout=48MHz
    str     r1, [r0]
    ; delay
    mov     r0, #0x200
5   subs    r0, r0, #1
    bne     %B5
    
 ;Set memory control registers
     ldr r0,=SMRDATA
 ldr r1,=BWSCON ;BWSCON Address
 add r2, r0, #52 ;End address of SMRDATA
0       
 ldr r3, [r0], #4    
 str r3, [r1], #4    
 cmp r2, r0  
 bne %B0
 
 
    ;Initialize stacks
 bl InitStacks
 
   ; Setup IRQ handler
 ldr r0,=HandleIRQ       ;This routine is needed
 ldr r1,=IsrIRQ          ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c
 str r1,[r0]
 ;Copy and paste RW data/zero initialized data
 ldr r0, =|Image$$RO$$Limit| ; Get pointer to ROM data
 ldr r1, =|Image$$RW$$Base|  ; and RAM copy
 ldr r3, =|Image$$ZI$$Base|  
 
 mov r10,pc
 ldr r4,=0x30000000
 cmp r4,r10
 bcc %F2
 
 bl nand_read_ll
 
   
2       
 ldr r1, =|Image$$ZI$$Limit| ; Top of zero init segment
 mov r2, #0
3       
 cmp r3, r1      ; Zero init
 strcc r2, [r3], #4
 bcc %B3
LED_ON 0x3
    [ :LNOT:THUMBCODE
     bl Main        ;Don't use main() because ......
     b .                       
    ]
    [ THUMBCODE         ;for start-up code for Thumb mode
     orr lr,pc,#1
     bx lr
     CODE16
     bl Main        ;Don't use main() because ......
     b .
     CODE32
    ]
;function initializing stacks
InitStacks
 ;Don't use DRAM,such as stmfd,ldmfd......
 ;SVCstack is initialized before
 ;Under toolkit ver 2.5, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'
 mrs r0,cpsr
 bic r0,r0,#MODEMASK
 orr r1,r0,#UNDEFMODE|NOINT
 msr cpsr_cxsf,r1  ;UndefMode
 ldr sp,=UndefStack
 
 orr r1,r0,#ABORTMODE|NOINT
 msr cpsr_cxsf,r1  ;AbortMode
 ldr sp,=AbortStack
 orr r1,r0,#IRQMODE|NOINT
 msr cpsr_cxsf,r1  ;IRQMode
 ldr sp,=IRQStack
    
 orr r1,r0,#FIQMODE|NOINT
 msr cpsr_cxsf,r1  ;FIQMode
 ldr sp,=FIQStack
 bic r0,r0,#MODEMASK|NOINT
 orr r1,r0,#SVCMODE
 msr cpsr_cxsf,r1  ;SVCMode
 ldr sp,=SVCStack
 
 ;USER mode has not be initialized.
 
 mov pc,lr 
 ;The LR register won't be valid if the current mode is not SVC mode.
 
LTORG
SMRDATA DATA
; Memory configuration should be optimized for best performance 
; The following parameter is not optimized.                     
; Memory access cycle parameter strategy
; 1) The memory settings is  safe parameters even at HCLK=75Mhz.
; 2) SDRAM refresh period is for HCLK=75Mhz. 
        DCD (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
     DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))   ;GCS0
     DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))   ;GCS1 
     DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))   ;GCS2
     DCD ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))   ;GCS3
     DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))   ;GCS4
     DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))   ;GCS5
     DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))    ;GCS6
     DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))    ;GCS7
     DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)    
DCD 0x32 ;SCLK power saving mode, BANKSIZE 128M/128M
     DCD 0x30            ;MRSR6 CL=3clk
     DCD 0x30            ;MRSR7
;     DCD 0x20            ;MRSR6 CL=2clk
;     DCD 0x20            ;MRSR7
ALIGN
     AREA RamData, DATA, READWRITE
        ^   _ISR_STARTADDRESS
HandleReset  #   4
HandleUndef  #   4
HandleSWI    #   4
HandlePabort    #   4
HandleDabort    #   4
HandleReserved  #   4
HandleIRQ    #   4
HandleFIQ    #   4
;Don't use the label 'IntVectorTable',
;The value of IntVectorTable is different with the address you think it may be.
;IntVectorTable
HandleEINT0    #   4
HandleEINT1    #   4
HandleEINT2    #   4
HandleEINT3    #   4
HandleEINT4_7 #   4
HandleEINT8_23 #   4
HandleRSV6 #   4
HandleBATFLT    #   4
HandleTICK    #   4
HandleWDT #   4
HandleTIMER0  #   4
HandleTIMER1  #   4
HandleTIMER2  #   4
HandleTIMER3  #   4
HandleTIMER4  #   4
HandleUART2   #   4
HandleLCD  #   4
HandleDMA0 #   4
HandleDMA1 #   4
HandleDMA2 #   4
HandleDMA3 #   4
HandleMMC #   4
HandleSPI0 #   4
HandleUART1 #   4
HandleRSV24 #   4
HandleUSBD #   4
HandleUSBH #   4
HandleIIC    #   4
HandleUART0  #   4
HandleSPI1  #   4
HandleRTC  #   4
HandleADC  #   4
        END

 
					
				
 
			
			
			
						
			 我要赚赏金
 我要赚赏金 STM32
STM32 MCU
MCU 通讯及无线技术
通讯及无线技术 物联网技术
物联网技术 电子DIY
电子DIY 板卡试用
板卡试用 基础知识
基础知识 软件与操作系统
软件与操作系统 我爱生活
我爱生活 小e食堂
小e食堂

