【原创】浅谈Kinetis上电启动顺序
1赞在这个夜黑风高又夹杂着蒙蒙细雨的晚上(耳边还不时传来蚊子的嗡嗡声,是真烦人啊),的确是无心科研,所以写博客是一个不错的选择,哈哈,而且今天也的确有点小心得要分享出来,所以。。。
这个小心得还是从下午我给手里的小七(htc G7)刷机说起(所以说感悟无所不在啊,哈哈)。下午闲着无聊,终于禁不住诱惑给我的小七刷了MIUI V4(自从前段时间看小米2发布会时就对这个新版本觊觎已久了,嘿嘿),升级到了Android 4.0,尝鲜下所谓的冰激凌三明治(ICS),虽然刷完机之后感觉卡了好多没有以前运行顺畅了(毕竟俺的g7硬件配置上还是有些过时了),不过在不断开机重启的刷机的过程中(刷过机的都懂的,呵呵),我突然冒出个想法,手机里的CPU在开机的时候的启动顺序是怎样的呢,当然由于手机系统的复杂性,我还是自知一时半刻搞不清楚了,所以就转移视线到手中现成的Kinetis了。查找了一番资料,终于有所收获,呵呵,不敢独享,这里就简单说说分享一下,不过可能有些不完善,欢迎指正。不多说了,上正题:
估计很多入门单片机编程的人在考虑单片机工作的时候(包括曾经的我,呵呵)都是从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开始执行。
嘿嘿,回过头看下,其实单片机在执行main之前还是作了相当一部分工作的(其实大都是为main的执行做些准备工作的)。在我带着走了一遍之后,不知道让大家对单片机的执行流程更透彻些了没,正所谓知其然还要知其所以然,希望博友们能有所收获,不懂的可以在下面留言,我会尽量解答,呵呵,未完待续~