找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 11260|回复: 4
收起左侧

MCU在运行到main()之前都干了什么

[复制链接]
ID:51024 发表于 2014-8-10 22:15 | 显示全部楼层 |阅读模式
 很多ARM工程师想当然的以为,自己开发的应用程序,用AK100Pro仿真器下载进入调试,MCU的PC指针必定停留在main()函数的入口。但实际上,在运行到main()前,MCU还做了很多事情。这里以一个LPC1700的Keil工程为例说明。

  MCU上电复位后,通常会从一个固定的地址开始启动,比如ARM7复位后的入口地址为0x00000000;或者类似Cortex-M内核从中断向量表中取出入口地址,中断向量表的地址必须是固定的。

  LPC1700为Cortex-M3内核,所以启动时会从中断向量表(地址0x00000000)处取出入口地址和堆栈指针,分别加载到PC和SP中。

  入口地址处通常放的是芯片相关的启动代码。这部分代码要完成很多芯片初始化的动作,由于与特定型号芯片相关,所以不能随随便便地就用到别的型号芯片上。通常我们会使用官方提供的例程,然后以此为基础进行必要的修改。以下是LPC1700的初始化代码,所有硬件相关的初始化操作放在了SystemInit()函数中。


    SystemInit()完成的功能可以有:设置看门狗、外部存储器接口、内核时钟等等。当然,这些代码有些是可以放到后面的main()函数中完成,但有些则必须放在运行到__main之前完成。

  芯片初始化完成后,接下来是执行C运行环境的初始化。C环境的初始化主要包含两点:

  按照分散加载文件的配置,将相应的数据段和代码段拷贝到相关位置,将ZI段清零。通过这个功能可以将C代码中未指定初始化值的全局变量和静态变量对应的内存清零,然后将指定初始化的全局变量和静态变量对应的内存初始化。另外,如果有通过分散加载文件设置代码存储在Flash中,然后自动搬运到RAM中运行(该功能将在后续文章中细讲),也会在该阶段完成这个自动搬运工作。

  之后是初始化C库,完成后才跳转到main()。

  以下是LPC1700工程的一段初始化代码,不同的工程配置,反汇编出来的结果略有不同。






  所以说,在main()运行前,MCU其实已经做了很多工作了。如果程序下载没有出现问题,但是就是跑不到main(),有可能不是仿真器的问题。是否会是main()之前的初始化操作异常?

-------------------------------

后面继续分享这种小的技术总结。如有不对,欢迎拍砖。

评分

参与人数 1黑币 +5 收起 理由
zhangli019 + 5 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:100713 发表于 2015-12-29 14:23 | 显示全部楼层
感谢感谢感谢感谢
回复

使用道具 举报

ID:136037 发表于 2016-8-5 10:34 | 显示全部楼层
楼主写的好,我来帮你消灭孤单的回复。
回复

使用道具 举报

ID:137764 发表于 2016-8-28 18:44 | 显示全部楼层
后面继续分享这种小的技术总结
回复

使用道具 举报

ID:164507 发表于 2017-2-13 20:57 | 显示全部楼层
单片机根据启动模式以及BOOT的管脚电平进入每部固化好的程序
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表