在对K60开发应用程序或编写硬件模块的驱动程序之前,我们需要对其启动流程有所了解。也许对一些简单的8位或者16位单片机进行系统开发时,我们往往不用去关心其启动代码部分,一般都是直接使用开发环境默认给出的启动代码,没必要去改。但是对于像ARM这类的复杂的32位片上系统来说,在启动代码部分,需要通过软件对一些硬件资源进行配置和设置一定的工作状态,这样我们就不得不去认真的了解它了。下面就以飞思卡尔tower系统上的片子MK60N512VMD100为例分析官方提供的Demo程序的启动流程。 简单的概括下K60的启动流程,主要分为四个部分(咳咳,我自作主张的分的,大家不要拍砖啊,呵呵): (1)初始化K60的通用寄存器(R0~R12),使能全局中断,跳转到start函数; (2)关闭看门狗,在调试阶段一般关闭它,毕竟老是频繁的喂狗也是挺麻烦的; (3)复制中断向量表、初始化的数据和以__ramfunc声明的子函数到RAM区(一定程度上提高了代码执行速度),并清零零初始化数据区; (4)初始化系统时钟; 在逐步分解介绍之前,必须要首先了解下*.icf文件,我默认采用128KB_Pflash配置模式,所以这里打开128KB_Pflash.icf文件,由于这个代码较多,所以就挑重要的说了: /*******************************用到的,捡重要的说,可能不是挨着的语句******************************* define symbol __ICFEDIT_intvec_start__ = 0x00000000;//这个是声明,中断向量表的默认存放地址 define symbol __code_start__ = 0x00000410;//声明程序代码开始地址 define exported symbol __VECTOR_TABLE = 0x00000000;//默认的中断向量表存放地址=楼上,呵呵 define exported symbol __VECTOR_RAM = 0x1fff8000;//需要复制到RAM去的中断向量表的地址
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };// 把.intvec代码段中的只读部分放在存储空间mem中的__ICFEDIT_intvec_start__ 地址上
place at address mem:__code_start__ { readonly section .noinit };//把 .noinit段中的只读部分放到地址空间 __code_start__开始的地址上
************************************************************************************************************/ .intvec 这个段可以在vectors.c文件中找得到,上图了又: 这里可以看到,系统默认是把中断向量表放到了.intvec段里,由上面可以看到也就是默认放到了0x00000000地址。 (1)下面逐步分解,其中第一步可以在crt0.s文件里找到,如下: ;AREA Crt0, CODE, READONLY ; name this block of code SECTION .noinit : CODE ; 下面这部分汇编代码放到.noinit段里地址为0x00000410(从上面分析可以看到)
EXPORT __startup
__startup ; __startup标号,其实这个是复位向量,在中断向量表里可以查到为vector001
MOV r0,#0 ; 清零所有通用寄存器
MOV r1,#0
MOV r2,#0
MOV r3,#0
MOV r4,#0
MOV r5,#0
MOV r6,#0
MOV r7,#0
MOV r8,#0
MOV r9,#0
MOV r10,#0
MOV r11,#0
MOV r12,#0
CPSIE i ; 打开全局中断
import start
BL start ; 跳转到start的C函数
__done
B __done
END
可能有些人会迷惑为什么CPU会复位之后从__startup标号开始执行,这里我以CPU的角度走一遍这个流程,CPU上电复位或者其他方式复位之后,它会首先从0x00000000地址读取堆栈指针到SP,然后再从0x00000004地址(注意地址总线为32位,所以每次跳4个字节才能读取下个地址)读取程序指针到PC,最后CPU就跳到PC指针所指向的地址开始执行程序了,至于从0x00000004读取的PC指针指向的地址是哪呢,那就是上面所说的__startup标号指向的程序地址了,这个我们可以在vector.h文件里找到,如下:
|