嵌入式系统中启动代码的流程,启动加载程序的概念?

时间:2010-08-03 04:39:50

标签: c assembly embedded microcontroller boot

我正在使用嵌入式主板,但我不知道启动代码(C /汇编)的流程。

在嵌入式系统的情况下,我们是否可以讨论启动操作所采取的一般模块/步骤。

只需高级概述(算法)即可。欢迎使用所有示例。

/卡努__

5 个答案:

答案 0 :(得分:25)

  1. CPU上电复位,并跳转到定​​义的点:复位向量,闪存开始,ROM等。
  2. 运行启动代码(crt-C运行时)。这是您的编译器/ libc生成的一段重要代码,它执行:
    1. 配置并打开任何外部存储器(如果绝对需要,否则留待以后的用户代码使用)。
    2. 建立堆栈指针
    3. 清除.bss段(通常)。 .bss是未初始化(或归零)全局内存区域的名称。没有初始化值(超过0)的全局变量,数组等位于此处。微控制器的一般做法是遍历该区域并在启动时将所有字节设置为0。
    4. 从.text结尾复制非const .data。由于大多数微控制器都是从闪存运行的,因此无法在那里存储可变数据。对于诸如int thisGlobal = 5;之类的语句,必须将thisGlobal的值从持久区域(通常在闪存中的程序之后,由链接器生成)复制到RAM。这适用于静态值和函数中的静态值。未定义的值不会被复制,而是作为步骤2的一部分清除。
    5. 执行其他静态初始化程序。
    6. 致电main()
  3. 从此处开始运行您的代码。通常,CPU处于中断关闭状态(取决于平台)。

答案 1 :(得分:3)

相当开放式的问题,但这里有一些我已经掌握的东西。

对于super simple processor,没有真正的启动代码。 cpu获得电源,然后开始在其内存中运行第一条指令:没有麻烦。

再远一点,我们有像avr和pic那样的mcu。这些启动代码非常少。唯一真正需要做的是设置具有适当地址的interrupt jump table。之后,由应用程序代码(唯一的程序)来完成它的工作。好消息是,作为开发人员,您通常不必担心这些事情:that's libc is for

之后我们就会有简单的基于臂的芯片;比avr和pic更复杂,但仍然非常简单。这些还必须设置中断表,以及确保正确设置时钟,并启动芯片组件上的任何所需(基本中断等)。看看this pdf from Atmel,它详细介绍了ARM 7芯片的启动过程。

我们拥有完整的PC(x86,amd64等)。这些的启动代码实际上是BIOS,which are horrendously complicated

答案 2 :(得分:1)

最大的问题是您的嵌入式系统是否会运行操作系统。一般来说,你要么想要运行你的操作系统,要么启动某种形式的控制反转(我记得一个学校项目的一个例子就是一个telnet,它会使用RL-ARM或开源tcp / ip来监听请求堆栈,然后有回调,它将在接收/接收数据时执行),或进入你自己的控制循环(可能显示一个菜单然后循环,直到按下一个键)。

答案 3 :(得分:1)

C / C ++启动代码的功能

  1. 禁用所有中断
  2. 将任何已初始化的数据从ROM复制到RAM
  3. 未初始化的数据区域设置为零。
  4. 为空间分配空间并初始化堆栈
  5. 初始化处理器的堆栈指针
  6. 创建并初始化堆
  7. 为所有全局变量执行构造函数和初始值设定项(仅限C ++)
  8. 启用中断
  9. 致电主要

答案 4 :(得分:0)

然后放置“BOOT LOADER”在哪里?它应该放在启动代码之前吗? 根据我的理解,从复位向量控制进入引导加载程序。在那里,代码等待一小段时间,期间数据被闪存/下载到控制器/处理器。如果它没有检测到数据,那么控件将转移到aatrus指定的下一步。但我怀疑是否可以重写BOOT LOADER代码。例如:UART引导加载程序是否可以更改为ETHERNET / CAN引导加载程序,或者使用任何协议发送的数据是否使用网关转换为UART然后闪烁。