S3C2440init分析.doc_第1页
S3C2440init分析.doc_第2页
S3C2440init分析.doc_第3页
S3C2440init分析.doc_第4页
S3C2440init分析.doc_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

该启动代码非BOOTLOADER中的启动代码,而是用户自编程序时所用到的。该启动代码综合了各家所长,结合自己的点点理解,去掉了睡眠模式、代码的搬迁(个人观点:我在学习FL2440的BOOTLAODER时,发现其内已进行了相应的搬迁工作。我所实验的结果是,本文中若加上代码搬迁的代码,并无意义。您可自行尝试,代码是否执行了从NAND FLASH到SDRAM的搬迁),尽量精简了语言。文档后面附上option.inc、memcfg.inc和2440addr.inc三个头文件的相关解释欢迎各位给我发站内信,讨论启动代码的相关内容祝你学习愉快;包含三个头文件 GET类比于#includeGET option.incGET memcfg.incGET 2440addr.inc;定义对应于7种模式的常量USERMODE EQU 0x10FIQMODE EQU 0x11IRQMODE EQU 0x12SVCMODE EQU 0x13ABORTMODE EQU 0x17UNDEFMODE EQU 0x1bMODEMASK EQU 0x1f;用户模式NOINT EQU 0xc0;禁止IRQ、FIQ中断;定义对应于各堆栈地址的常量(大小自行定义)UserStackEQU(_STACK_BASEADDRESS-0x3800);0x33ff4800 SVCStackEQU(_STACK_BASEADDRESS-0x2800);0x33ff5800 4KBUndefStackEQU(_STACK_BASEADDRESS-0x2400);0x33ff5c00 9KBAbortStackEQU(_STACK_BASEADDRESS-0x2000);0x33ff6000 5KBIRQStackEQU(_STACK_BASEADDRESS-0x1000);0x33ff7000 4KBFIQStackEQU(_STACK_BASEADDRESS-0x0);0x33ff8000 4KB;根据编译器内置的常量CONFIG来判断是否使用的是汇编编译器TASM.EXEGBLL THUMBCODE CONFIG = 16THUMBCODE SETL TRUE CODE32;若是,则告诉编译器,后面的指令为ARM指令,并启用ARMASM.EXE编译器 |THUMBCODE SETL FALSE ;定义异常处理宏 MACRO$HandlerLabel HANDLER $HandleLabel$HandlerLabelsubsp,sp,#4;留出堆栈空间以存储第一级异常处理函数的地址stmfdsp!,r0;保存需要用到的寄存器R0到堆栈中(先对堆栈指针进行减操作)ldr r0,=$HandleLabel;加载$HandleLabel的值到R0ldr r0,r0 ;加载$HandleLabel地址所指向的内容(即第一级异常处理函数的地址)到R0str r0,sp,#4 ;将第一级异常处理函数的地址放到预留堆栈空间内ldmfd sp!,r0,pc ;从堆栈中取出数据,并将PC值指向第一级异常处理函数的地址MENDIMPORT Main ; C语言的入口函数Main,不能使用main的原因是当使用ARM C库以实现程序从加载域到运行域的初始化时,程序默认跳到main处AREA Init,CODE,READONLYENTRYResetEntry;判断是否要更改指令模式;32位的数据需要2个16位或4个8位来存储,基于此,可以理解DCD后面的数值的位置需要对换ASSERT:DEF:ENDIAN_CHANGE ENDIAN_CHANGE ASSERT :DEF:ENTRY_BUS_WIDTH ENTRY_BUS_WIDTH=32b ChangeBigEndian;DCD 0xea000007 ENTRY_BUS_WIDTH=16andeqr14,r7,r0,lsl #20 ;DCD 0x0007ea00 ENTRY_BUS_WIDTH=8streqr0,r0,-r10,ror #1 ;DCD 0x070000ea | bResetHandler; bHandlerUndef;handler for Undefined modebHandlerSWI;handler for SWI interruptbHandlerPabort;handler for PAbortbHandlerDabort;handler for DAbortb.;死循环bHandlerIRQ;handler for IRQ interruptbHandlerFIQ;handler for FIQ interrupt; 将小段模式更改为大端模式(通过更改协处理器P15中的寄存器C1的第八位来实现)ChangeBigEndian ENTRY_BUS_WIDTH=32mrc p15,0,r0,c1,c0,0;DCD 0xee110f10orr r0,r0,#0x80;DCD 0xe3800080mcr p15,0,r0,c1,c0,0;DCD 0xee010f10 ENTRY_BUS_WIDTH=16 DCD 0x0f10ee11 DCD 0x0080e380 DCD 0x0f10ee01 ENTRY_BUS_WIDTH=8DCD 0x100f11ee DCD 0x800080e3 DCD 0x100f01ee DCD 0xffffffff;等待小端模式切换到大端模式,相当于NOP指令,只是该指令在大小端模式下更兼容 DCD 0xffffffff DCD 0xffffffff DCD 0xffffffff DCD 0xffffffff bResetHandler;更改完后,跳到复位异常HandlerFIQ HANDLER HandleFIQHandlerIRQ HANDLER HandleIRQHandlerUndef HANDLER HandleUndefHandlerSWI HANDLER HandleSWIHandlerDabort HANDLER HandleDabortHandlerPabort HANDLER HandlePabortIsrIRQsubsp,sp,#4 ;留出堆栈空间,存储第二级异常处理函数的地址stmfdsp!,r8-r9;保存需要用到的寄存器R8、R9到堆栈中(先对堆栈指针进行减操作)ldrr9,=INTOFFSET;获取中断类型偏移值所对应的寄存器地址ldrr9,r9;加载偏移值寄存器中的值ldrr8,=HandleEINT0;获取由程序所定义的外部中断异常向量表的首地址addr8,r8,r9,lsl #2;获取外部异常中断所对应的地址ldrr8,r8strr8,sp,#8;加载外部异常中断地址所指向的内容,即第二级异常处理函数的地址ldmfdsp!,r8-r9,pc ;恢复寄存器R8R9中的值,并使程序跳转到第二级异常处理函数处执行LTORG;声明文件池,常与LDR伪指令连用 ;初始化硬件ResetHandlerldrr0,=WTCON ;关闭看门狗ldrr1,=0x0strr1,r0 ldrr0,=INTMSKldrr1,=0xffffffff ;关闭所有中断strr1,r0ldrr0,=INTSUBMSKldrr1,=0x7fff;关闭所有子中断strr1,r0 FALSE;若无仿真器,可将FALSE改为TRUE,然后下载程序到开发板,若灯亮且蜂蜜器响,说明程序执行了该初始化代码 ldr r0, =GPBCON ldr r1, =0x555555 str r1, r0 ldr r0, =GPBDAT ldr r1, =0x1 str r1, r0 ;设定PLL锁定时间。该寄存器的取值方法:值最小时间(如:300us,见DATASHEET?*Finldrr0,=LOCKTIMEldrr1,=0xfff0fff;或为0xffff ffff最大值strr1,r0 PLL_ON_START;TRUE; 设置CLKDIVN寄存器的值ldrr0,=CLKDIVNldrr1,=CLKDIV_VALstrr1,r0;切换始终模式(通过协处理器P15来进行。S3C2440两种模式:异步模式和高速模式,不支持同步模式) CLKDIV_VAL1 ;即HDIVN不等于,应切换到异步模式mrc p15,0,r0,c1,c0,0orr r0,r0,#0xc0000000;R1_nF:OR:R1_iAmcr p15,0,r0,c1,c0,0|mrc p15,0,r0,c1,c0,0bic r0,r0,#0xc0000000;R1_iA:OR:R1_nFmcr p15,0,r0,c1,c0,0;配置UPLLldrr0,= UPLLCONldrr1,=(U_MDIV12)+(U_PDIV4)+U_SDIV) strr1,r0nop;等待7个时钟的延迟,以使硬件完成配置nopnopnopnopnopnop;配置MPLLldrr0,=MPLLCONldrr1,=(M_MDIV12)+(M_PDIV4)+M_SDIV) ;Fin=12MHzstrr1,r0 ;初始化各模式下的堆栈blInitStacks;建立IRQ中断向量表ldrr0,=HandleIRQ ldrr1,=IsrIRQ strr1,r0 THUMBCODE orrlr,pc,#1 bxlr CODE16 blMain b.CODE32 | blMain b.;调试时,若Main函数中无死循环,则调用完Main函数后,程序即执行该行代码,进入死循环。不再执行自编代码 ;初始化堆栈。即将以分配的地址空间赋值到各模式下的堆栈中InitStacksmrsr0,cpsrbicr0,r0,#MODEMASKorrr1,r0,#UNDEFMODE|NOINTmsrcpsr_cxsf,r1;UndefModeldrsp,=UndefStack; UndefStack=0x33FF_5C00orrr1,r0,#ABORTMODE|NOINTmsrcpsr_cxsf,r1;AbortModeldrsp,=AbortStack; AbortStack=0x33FF_6000orrr1,r0,#IRQMODE|NOINTmsrcpsr_cxsf,r1;IRQModeldrsp,=IRQStack; IRQStack=0x33FF_7000orrr1,r0,#FIQMODE|NOINTmsrcpsr_cxsf,r1;FIQModeldrsp,=FIQStack; FIQStack=0x33FF_8000bicr0,r0,#MODEMASK|NOINTorrr1,r0,#SVCMODEmsrcpsr_cxsf,r1;SVCModeldrsp,=SVCStack; SVCStack=0x33FF_5800;USER模式和系统模式公用一个堆栈,不需要初始化且不能直接进行初始化(原因:不能对USER模式的CPSR寄存器进行操作)movpc,lr;该指令须在SVC模式下调用,否则不能返回到调用InitStacks处ALIGN;创建数据段,包含各中断向量的地址空间AREA RamData, DATA, READWRITE _ISR_STARTADDRESS; = MAP, # = FIELDHandleReset # 4HandleUndef # 4HandleSWI# 4HandlePabort # 4HandleDabort # 4HandleReserved # 4HandleIRQ# 4HandleFIQ# 4HandleEINT0# 4HandleEINT1# 4HandleEINT2# 4HandleEINT3# 4HandleEINT4_7# 4HandleEINT8_23# 4HandleCAM# 4HandleBATFLT# 4HandleTICK# 4HandleWDT# 4HandleTIMER0 # 4HandleTIMER1 # 4HandleTIMER2 # 4HandleTIMER3 # 4HandleTIMER4 # 4HandleUART2 # 4HandleLCD # 4HandleDMA0# 4HandleDMA1# 4HandleDMA2# 4HandleDMA3# 4HandleMMC# 4HandleSPI0# 4HandleUART1# 4HandleNFCON# 4HandleUSBD# 4HandleUSBH# 4HandleIIC# 4HandleUART0 # 4HandleSPI1 # 4HandleRTC # 4HandleADC # 4ENDOption.inc头文件 ;该头文件用来设置地址常量、指令模式切换及内部时钟;自定义两个起始地址;堆栈起始地址常位于SDRAM尾端_STACK_BASEADDRESSEQU 0x33ff8000;中断向量表起始地址常位于SDRAM末端_ISR_STARTADDRESSEQU 0x33ffff00GBLL PLL_ON_STARTPLL_ON_STARTSETL TRUE ;使能上电启动PLL设置GBLLENDIAN_CHANGEENDIAN_CHANGESETLFALSE ;设置指令端模式不改变;BUSWIDTH = 8, 16,32GBLAENTRY_BUS_WIDTHENTRY_BUS_WIDTHSETA32 ;设置入口总线宽度,用于指令端模式切换;ENTRY_BUS_WIDTHSETA16 ;ENTRY_BUS_WIDTHSETA8 GBLA BUSWIDTHBUSWIDTHSETA 32;设置外围设备(即GPIO)的总线宽度(取外接设备中数据总线宽度最大值);BUSWIDTHSETA 16GBLAUCLKUCLKSETA48000000;设置USB输出时钟;上面及下面所列出的选择项,只是为了更好更快的在不同ARM核及外接设备间切换,;CPU选择(通过CHIP ID)GBLACPU_SEL;CPU_SELSETA32440000; 32440000:2440X.CPU_SELSETA32440001; 32440001:2440A;设置CPU芯片的ID,即寄存器GSTATUS1,可在DNW中可查看;输入晶振频率的选择GBLAXTAL_SELXTAL_SELSETA12000000;12MHZ;XTAL_SELSETA16934400;16.9344MHZ;CPU输出时钟的选择GBLAFCLK;FCLKSETA100000000;设置CPU时钟;FCLKSETA200000000;FCLKSETA271500000;FCLKSETA304000000FCLKSETA400000000;设置Fclk:Hclk:Pclk的比值;CLKDIVN的值(左)与三时钟比值的关系: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.;FCLK = 100000000;CLKDIV_VALEQU1; 设置CLKDIVN的值为1;FCLK = 200000000;CLKDIV_VALEQU3; 设置CLKDIVN的值为3;FCLK = 304000000 or 271500000;CLKDIV_VALEQU7; 设置CLKDIVN的值为7;FCLK = 400000000CLKDIV_VALEQU5; 设置CLKDIVN的值为5;根据不同的输入晶振频率、FCLK和CPU ID来设置M_MDIV和M_PDIV的值 XTAL_SEL = 12000000;晶振频率为12MHZ FCLK = 100000000M_MDIVEQU42;Fin=12.0MHz Fout=100MHzM_PDIVEQU4 CPU_SEL = 32440001M_SDIVEQU1; 2440A|M_SDIVEQU0; 2440X FCLK = 200000000M_MDIVEQU92;Fin=12.0MHz Fout=200MHzM_PDIVEQU4 CPU_SEL = 32440001M_SDIVEQU1; 2440A|M_SDIVEQU0; 2440X FCLK = 271500000M_MDIVEQU173;Fin=12.0MHz Fout=271.5MHzM_PDIVEQU2 CPU_SEL = 32440001M_SDIVEQU2; 2440A |M_SDIVEQU1; 2440X FCLK = 304000000M_MDIVEQU68;Fin=12.0MHz Fout=304.8MHzM_PDIVEQU1 CPU_SEL = 32440001M_SDIVEQU1; 2440A|M_SDIVEQU0; 2440X FCLK = 400000000M_MDIVEQU92;Fin=12.0MHz Fout=400MHzM_PDIVEQU1 CPU_SEL = 32440001M_SDIVEQU1; 2440A|M_SDIVEQU0; 2440X UCLK = 48000000U_MDIVEQU56;Fin=12.0MHz Fout=48MHzU_PDIVEQU2 CPU_SEL = 32440001U_SDIVEQU2; 2440A |U_SDIVEQU1; 2440X UCLK = 96000000U_MDIVEQU56;Fin=12.0MHz Fout=96MHzU_PDIVEQU2 CPU_SEL = 32440001U_SDIVEQU1; 2440A |U_SDIVEQU0; 2440X |;晶振频率为16.394MHZ FCLK = 266716800M_MDIVEQU118;Fin=16.9344MHzM_PDIVEQU2 CPU_SEL = 32440001M_SDIVEQU2; 2440A|M_SDIVEQU1; 2440X FCLK = 296352000M_MDIVEQU97;Fin=16.9344MHzM_PDIVEQU1 CPU_SEL = 32440001M_SDIVEQU2; 2440A|M_SDIVEQU1; 2440X FCLK = 541900800M_MDIVEQU120;Fin=16.9344MHzM_PDIVEQU2 CPU_SEL = 32440001M_SDIVEQU1; 2440A|M_SDIVEQU0; 2440X UCLK = 48000000U_MDIVEQU60;Fin=16.9344MHz Fout=48MHzU_PDIVEQU4 CPU_SEL = 32440001U_SDIVEQU2; 2440A |U_SDIVEQU1; 2440X UCLK = 96000000U_MDIVEQU60;Fin=16.9344MHz Fout=96MHzU_PDIVEQU4 CPU_SEL = 32440001U_SDIVEQU1; 2440A |U_SDIVEQU0; 2440X ENDMemcfg.inc头文件;该头文件主要用来初始化存储控制器中的总线、BANKCONn和REFRESH寄存器;为便于初始化,先定义几个对应于总线宽度位、使能等待及使用UB/LB值的常量DW8EQU(0x0)DW16EQU(0x1)DW32EQU(0x2)WAITEQU(0x12)UBLBEQU(0x13);初始化总线各外接设备的数据总线宽度ASSERT :DEF:BUSWIDTH;判断是否已定义BUSWIDTH BUSWIDTH=16B1_BWSCONEQU (DW16)B2_BWSCONEQU (DW16)B3_BWSCONEQU (DW16)B4_BWSCONEQU (DW16+WAIT)B5_BWSCONEQU (DW16)B6_BWSCONEQU (DW16)B7_BWSCONEQU (DW16) | ;BUSWIDTH=32; 2440 EV board.B1_BWSCONEQU (DW16); Intel flash(JS28F320), 16-bit, for nCS1B2_BWSCONEQU (DW16); PCMCIA(PD6710), 16-bitB3_BWSCONEQU (DW16); Ethernet(CS8900), 16-bitB4_BWSCONEQU (DW32); Intel Strata(28F128), 32-bit, for nCS4B5_BWSCONEQU (DW16); A400/A410 Ext, 16-bitB6_BWSCONEQU (DW32); SDRAM(K4S561632N) 32MBx2, 32-bitB7_BWSCONEQU (DW32); N.C. ;初始化各BANKCON寄存器的值,BANKCON0BANKCON5使用默认值0x700;BANKCON0B0_TacsEQU0x3;0clkB0_TcosEQU0x3;0clkB0_TaccEQU0x7;14clkB0_TcohEQU0x3;0clkB0_TahEQU0x3;0clkB0_TacpEQU0x1B0_PMCEQU0x0;normal;BANKCON1B1_TacsEQU1;0x0;0clkB1_TcosEQU1;0x0;0clkB1_TaccEQU6;0x7;14clkB1_TcohEQU1;0x0;0clkB1_TahEQU1;0x0;0clkB1_TacpEQU0x0B1_PMCEQU0x0;normal;BANKCON2B2_TacsEQU1;0x0;0clkB2_TcosEQU1;0x0;0clkB2_TaccEQU6;0x7;14clkB2_TcohEQU1;0x0;0clkB2_TahEQU1;0x0;0clkB2_TacpEQU0x0B2_PMCEQU0x0;normal;BANKCON3B3_TacsEQU0x1;0;0clkB3_TcosEQU0x1;0;0clkB3_TaccEQU0x6;7;14clkB3_TcohEQU0x1;0;0clkB3_TahEQU0x1;0;0clkB3_TacpEQU0x0B3_PMCEQU0x0;normal;BANKCON4B4_TacsEQU0x1;0;0clkB4_TcosEQU0x1;0;0clkB4_TaccEQU0x6;7;14clkB4_TcohEQU0x1;0;0clkB4_TahEQU0x1;0;0clkB4_TacpEQU0x0B4_PMCEQU0x0;normal;BANKCON5B5_TacsEQU0x1;0;0clkB5_TcosEQU0x1;0;0clkB5_TaccEQU0x6;7;14clkB5_TcohEQU0x1;0;0clkB5_TahEQU0x1;0;0clkB5_TacpEQU0x0B5_PMCEQU0x0;normal;BANKCON6、BANKCON7和REFRESH寄存器的参数与外接设备的参数(时钟)和HCLK有关,下面的值是以外接SDRAM和HCLK=100MHZ为前提;BANKCON6 外接SDRAMB6_MTEQU0x3;SDRAM设置bank6所接的存储器类型B6_TrcdEQU0x1;3clk设置从行地址传送到列地址所需要的时钟周期B6_SCANEQU0x1;9bit设置列地址位数,参见datasheet;BANKCON7 空置 常设置成BANKCON6的参数值B7_MTEQU0x3;SDRAM设置bank7所接的存储器类型B7_TrcdEQU0x1;3clkB7_SCANEQU0x1;9bit设置列地址位数,参见datasheet;REFRESH parameterREFENEQU0x1;Refresh enable 使能SDRAM刷新TREFMDEQU0x0;CBR(CAS before RAS)/Auto refresh设置为自动刷新Trp EQU 0x1 ;3clk设置预充电周期时间TsrcEQU0x1;5clk设置半行周期时间 行周期时间为Trc= Trp(2)+Tsrc(5) = 7clockREFCNTEQU1249;HCLK=100Mhz, (2048+1-8*100)FL2440设置刷新计数值,参见datasheetEND2440addr.inc头文件;该头文件主要用于定义一些常量来替代启动代码中常用的寄存器的地址;存储控制寄存器BWSCON EQU 0x48000000 ;Bus width & wait statusBANKCON0EQU 0x48000004 ;Boot ROM controlBANKCON1EQU 0x48000008 ;BANK1 controlBANKCON2EQU 0x4800000c ;BANK2 controlBANKCON3EQU 0x48000010 ;BANK3 controlBANKCON4EQU 0x48000014 ;BANK4 controlBANKCON5EQU 0x48000018 ;BANK5 controlBANKCON6EQU 0x4800001c ;BANK6 controlBANKCON7EQU 0x48000020 ;BANK7 controlREFRESH EQU 0x48000024 ;DRAM/SDRAM refreshBANKSIZEEQU 0x48000028 ;Flexible Bank SizeMRSRB6 EQU 0x4800002c ;Mode register set for SDRAM Bank6MRSRB7 EQU 0x48000030 ;Mode register set for SDRAM Bank7;时钟控制寄存器LOCKTIMEEQU 0x4c000000 ;PLL lock time counterMPLLCON EQU 0x4c000004 ;MPLL ControlUPLLCON EQU 0x4c000008 ;UPLL ControlCLKCON EQU 0x4c00000c ;Clock generator controlCLKSLOW EQU 0x4c000010 ;Slow clock controlCLKDIVN EQU 0x4c000014 ;Clock divider control;中断控制寄存器SRCPND EQU 0x4a000000 ;Interrupt request statusINTMOD EQU 0x4a000004 ;Interrupt mode controlINTMSK EQU 0x4a000008 ;Interrupt mask controlPRIORITY EQU 0x4a00000c ;IRQ priority control - May 06, 2002 SOPINTPND EQU 0x4a000010 ;Interrupt request statusINTOFFSETEQU 0x4a000014 ;Interruot request source offsetSUSSRCPNDEQU 0x4a000018 ;Sub source pendingINTSUBMSKEQU 0x4a00001c ;Interrupt sub mask;GPBCON寄存器,主要用于点亮LEDGPBCON EQU 0x56000010 ;Port B controlGPBDAT EQU 0x56000014 ;Port B dataGPBUP EQU 0x56000018 ;Pull-up control B;其它寄存器MISCCR EQU 0x56000080 ;Miscellaneous controlDCKCON EQU 0x56000084 ;DCLK0/1 controlEXTINT0 EQU 0x56000088 ;External interrupt control register 0EXTINT1 EQU 0x5600008c ;External interrupt control register 1EXTINT2 EQU 0x56000090 ;External interrupt control register 2EINTFLT0EQU 0x56000094 ;ReservedEINTFLT1EQU 0x56000098 ;ReservedE

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论