估计很多入门单片机编程的人在考虑单片机工作的时候(包括曾经的我,呵呵)都是从main()开始考虑的,很少有初手会去考量单片机在上电到执行main()这期间都干了什么。但等你接触多了的时候,你就会慢慢的去考虑这期间单片机干的事,这也是你从菜鸟到老鸟的过渡了,等你真正掌握了这一点,你就会对单片机有一个重新的认识(反正我是这样的),出现问题的时候也会站在一个全局的角度来思考,因此往往很快就解决了问题,这也就是初手和老手的很大的一个差别所在了,哈哈。下面我就以Kinetis为例说说它的上电启动顺序,让新手可以更深层次的去领悟单片机的工作原理,呵呵,老手就可以略过了,我怕自己写不好丢人啊,呵呵~ (1)上电起初,单片机的电压调节器会把整个系统置于POR(上电复位)状态的上电阶段,一直到工作电压达到了可以让单片机正常工作的电压阈值之后才释放这个上电阶段,进入复位阶段; (2)在复位保持期间,由单片机内部的模式控制复位逻辑统筹支配整个复位阶段的执行顺序; (3)首先MCG模块使能,并默认为FEI时钟模式; (4)相应模块的时钟使能,包括Coreclock,Systemclock,Flashclock,busclock等这些不需要门控(clock gate,M4的特色)控制的时钟; (5)Flash控制器从复位状态释放(注意这时外部RESET脚仍然保持低电平),并且执行一系列的初始化操作(因为要为接下来的代码执行做准备了); (6)单片机/RESET引脚释放,但是系统复位状态继续保持,一直到上面的Flash控制器初始化完毕(如果Flash控制器提前初始化好,则/RESET引脚释放后立即从POR状态苏醒); (7)Kinetis从复位状态唤醒之后,开始设置堆栈(stack),程序计数器(PC)和连接寄存器(LR)(这里需要说明的是,在ARM架构中stack指针即寄存器组里的R13,PC指针为R14,LR指针为R15)。具体设置为(具体流程我在启动代码分析里面提到过):从中断向量表地址0读取内容给堆栈指针,地址4读取内容给PC指针,LR寄存器设置为0xFFFF_FFFF。 (8)上面三个寄存器设置好了之后,单片机就开始从PC指针指向的地址开始执行代码了,剩下的就是我以前写过的从零入手系列启动代码分析那部分的流程了,最后才转到main开始执行。
|