您好,欢迎访问三七文档
ARM启动代码浅析主讲:李日和组员:张本涛王忠强郑亚杰启动代码浅析#includestm32f10x.h#includestdio.hintmain(){while(1);}单片机上电复位后为什么能进入用户定义的main函数呢?启动代码与链接文件启动代码浅析功能硬件初始化引导C代码特征通常用汇编语言编写程序复位运行入口点代码量小程序流程设置中断、异常入口初始化堆栈指针、地址重映射数据区初始化C代码入口函数调用初始化I/O设备启动代码浅析异常向量表__VectorsDCD__initial_sp;TopofStackDCDReset_Handler;ResetHandlerDCDNMI_Handler;NMIHandlerDCDHardFault_Handler;HardFaultHandlerDCDMemManage_Handler;MPUFaultHandlerDCDBusFault_Handler;BusFaultHandlerDCDUsageFault_Handler;UsageFaultHandlerDCD0;ReservedDCD0;ReservedDCD0;ReservedDCD0;ReservedDCDSVC_Handler;SVCallHandlerDCDDebugMon_Handler;DebugMonitor复位未定义指令软件中断预取指令中止数据中止IRQFIQ_start:bresetldrpc,_undefined_instructionldrpc,_software_interruptldrpc,_prefetch_abortldrpc,_data_abortldrpc,_not_usedldrpc,_irqldrpc,_fiq_undefined_instruction:.wordundefined_instruction_software_interrupt:.wordsoftware_interrupt_prefetch_abort:.wordprefetch_abort_data_abort:.worddata_abort_not_used:.wordnot_used_irq:.wordirq_fiq:.wordfiqSTM32F10X系列AT91SAM7系列注意:M3的Vector只是指针,第一个是指向stack的,第二个是指向复位程序的地址,而ARM7/9的Vector都是跳转指令或者pc加载指令。启动代码浅析ARM中断向量设置方法方法一:在中断向量表中放置一条分支指令如:IRQEntryBHandleIRQ;跳转范围较小,相对于PC前后32MBBHandlerReset=ADDPC,PC,#offset方法二:在中断向量表中放置一条PC寄存器加载指令如:LDRPC,=HandlerReset;全范围跳转,偏移量为4KBLDRPC,=HandlerReset=MOVPC,(RO+offset)注意:LDR指令可以全地址范围跳转,而B指令只能在前后32MB范围内跳转;芯片具有Remap功能时,当向量表位于内部RAM或外部存储器中,用B指令可能跳转不到正确的位置。启动代码浅析堆栈指针初始化用户模式(usr)FIQ模式(fiq)IRQ模式(irq)管理模式(svr)中止模式(abt)未定义模式(und)系统模式(sys)启动代码浅析ldrr0,=_sstack/*设置r0指向栈顶*/msrCPSR_c,#ARM_MODE_UND|I_BIT|F_BIT/*选择未定义模式*/movsp,r0subr0,r0,#UND_STACK_SIZEmsrCPSR_c,#ARM_MODE_ABT|I_BIT|F_BIT/*切换到中止模式*/movsp,r0subr0,r0,#ABT_STACK_SIZEmsrCPSR_c,#ARM_MODE_FIQ|I_BIT|F_BIT/*切换到快速中断模式*/movsp,r0subr0,r0,#FIQ_STACK_SIZE/*adjustr0pastFIQstack*/msrCPSR_c,#ARM_MODE_IRQ|I_BIT|F_BIT/*切换到中断模式*/movsp,r0subr0,r0,#IRQ_STACK_SIZEmsrCPSR_c,#ARM_MODE_SVC|I_BIT|F_BIT/*切换到管理模式*/movsp,r0subr0,r0,#SVC_STACK_SIZEmsrCPSR_c,#ARM_MODE_SYS|I_BIT|F_BIT/*切换到系统模式*/movsp,r0栈内存分布………………………………UndmodeAbtmodeFIQmodeIRQmodeSVCmodeSysmode目录报告内容模式选择及重映射启动代码浅析CPSR程序状态寄存器MsrCPSR_c,#ARM_MODE_SVC|I_BIT|F_BIT//选择管理模式ldrr3,=0xFFE00020movr4,#1strr4,[r3]/*重映射*/voidNVIC_SetVectorTable(u32NVIC_VectTab,u32Offset)MOVr9,#0x08000000MOVr10,#0x20000000LDMIAr9!,{r0-r7}STMIAr10!,{r0-r7}LDMIAr9!,{r0-r7}STMIAr10!,{r0-r7}目录报告内容数据初始化启动代码浅析目录报告内容启动代码浅析主要有三个段.text段.data段.bss段.data段:用来存储已经初始化的全局变量,也属于静态内存分配区,会占用程序文件空间。.bss段:用来存储未初始化的全局变量和静态变量,不会占用程序文件空间,不存储这些变量在外存上,但是还是会占用一部分空间,这些空间用来标识未初始化的变量大小、属性等信息OUTPUT_FORMAT(elf32-littlearm)OUTPUT_ARCH(arm)ENTRY(_start)MEMORY{flash:ORIGIN=0x8000000,LENGTH=0x80000ram:ORIGIN=0x20000000,LENGTH=0x10000}SECTIONS{.text:{*(.text)}flash.data:{*(.data)}ramATflash.bss:{*(.bss)}ramATflash}链接脚本例子目录报告内容启动代码浅析数据拷贝.ram0x40:{_ram_lma=LOADADDR(.ram);_ram_start=.;*(.ram.text)*(.ram.data)_ram_end=.;}ramATrom链接脚本externint_ram_start,_ram_end,_ram_lma;src=&_ram_lma;dst=&_ram_start;while(dst&_ram_end)*dst++=*src++;C代码目录报告内容
本文标题:启动代码分析
链接地址:https://www.777doc.com/doc-1770671 .html