执行微控制器启动代码之前会发生什么?或 Power-On/Reset 序列?

What happens before Micro-controller Startup Code being executed? or Power-On/Reset Sequence?

我所知道的如下,如有错误请指正,对于基于任何微控制器的汽车引导加载程序,我们将有

就开机顺序而言,我知道,

  1. 来自启动代码(微商提供,飞思卡尔,ST Micro等,)控制权将转移到PBL(Primary 引导加载程序)使用跳转或函数指针。
  2. PBL 会将 SBL(辅助引导加载程序)下载到 RAM 中,这将 包含闪存驱动程序,能够下载应用程序。
  3. SBL会将应用程序下载到闪存区。

但是在执行启动代码之前或者刚刚上电之后会发生什么? 我知道每个控制器在开机 POST(开机自检)后都会执行某种代码,但在引导加载程序开始执行之前仍然不清楚操作顺序。

如果有人能提供一个到达启动代码的操作序列,那将是一个很大的帮助?

不知道您使用的是哪种微控制器,这应该足够通用:

  1. 微控制器中的硬件将多个寄存器重置为其记录的值。这包括 PC,程序计数器。
  2. 如果微控制器具有可配置的复位向量,则可以从几个选项中选择该值,其他控制器始终使用相同的值。
  3. PC指向位置的代码是启动代码。

注意:读取控制器的数据sheet总是好的!

我发现这种不常见的混淆很有趣。

POST 是一般的软件,但你的问题太模糊了。通常,当有人谈论 POST 时,他们谈论的是基于 x86 的计算机,这只是软件,发生在您感到困惑的部分之后,并且 computer/processor 到 运行,它有一个目的,增加价值,所以它就在那里。

微控制器通常没有主引导程序或辅助引导程序,它们只是启动 运行ning 您的应用程序。在 dozens/hundreds 中,我有 used/examined 试图想出任何有主要或次要的。想不出任何副手。特别是某些品牌确实具有通常由它们编程的引导加载程序,您无法更改或可以更改。进入引导加载程序的方式因品牌而异,通常是带子,有时是寄存器中的非易失性位。

首先,处理器及其周围的芯片很笨,非常笨。只做人类告诉他们的事情。令人难以置信的简单机器。虽然从这个角度来看,单片机和完整系统之间的区别几乎相同,但单片机更简单、更可靠(出于各种原因)。答案的根源始于处理器或处理器核心或核心或任何术语 可能会帮助你。在单片机中,这只是整个芯片中的一个乐高积木块,甚至不一定是芯片中最大的块。当您查看基于 arm 的芯片,如 stm32 和其他带有 cortex-m(或带有 ARMV7TDMI 的旧芯片)的 lego 块是从 arm 购买的 ip,芯片的其余部分是从一个或多个供应商处购买的其他 ip,或者在-自制逻辑。 sram 和 flash 可能是芯片供应商为特定代工厂的特定工艺购买的 ip(就像其他单元库项目一样,简单的门,如 AND、OR、NOT 和更复杂的门)。

无论这是什么处理器核心,它都有自己的体系结构和指令集。虽然我们知道一些架构是使用微代码实现的,但 mcus 不太可能,更 cisc 可能没有意义,但 arms 和 mips 等绝对不是。但是对于这种理解,微编码与否无关紧要,有驱动处理器的位模式,机器代码。我们都听说过芯片是由晶体管构成的,事实确实如此。晶体管是简单性的一部分,您可以在维基百科上查找基本的与、或、非门。您可以(低效地)从这些基本块中构建其余部分。一条特定的指令会刺激逻辑,晶体管以某种方式引起一系列事件,1 和 0 以特定的顺序执行您要求的事情。逻辑不限于执行处理器指令,大多数逻辑不是处理器指令的解码和执行的一部分,即使它们同样是愚蠢的项目也是如此。一个 sram 有很多位(每个位有四个晶体管以某种方式连接),带有地址和数据总线,sram 的逻辑在写入或读取时点亮这些位的行和列。然后在解码地址总线等的 sram 前面有更多逻辑

正如另一个答案中提到的,当电源上电然后释放复位时,芯片中基于触发器的项目即我们在手册中阅读的寄存器加上幕后的无数其他项目被设置为他们的通过晶体管的接线完成的复位值。许多状态机启动,它们类似于程序,但是是硬连线的。等待重置变高,一旦重置变高,那么如果状态机的输入是这个,状态机的输入是那个,那么我可以进入下一个状态。从一个状态到下一个状态的规则是在逻辑上实现的。例如,带有内存和闪存的芯片可能首先在 ram 上执行 bist,可能不在 mcu 中,没有意义,这是逻辑而不是软件执行此操作,这不是您在中想到的 post你的laptop/desktop/server。闪存或 ram 或 adcs 或其他逻辑可能需要一定数量的时钟来在释放复位之前解决它们的逻辑(芯片边缘的复位不一定硬连接到芯片中的所有项目,通常它是门控的,延迟的, ETC)。所以有一个开机状态机来管理它,当芯片准备就绪时,处理器本身将被释放,这可能是几个或几十个时钟周期之后。时钟本身必须稳定下来,而逻辑设计就是为了等待它。

当处理器从复位中释放时,它可能有一些时钟来解决其设计中的问题,它会有一个或多个状态机来启动各种块,然后基于架构设计该处理器执行以下两项操作之一,从已知地址(处理器地址 space 中的地址,不一定是芯片视图中的地址)获取其第一条指令,或者它使用向量 table 方法,它从已知地址读取一个值,读取的值是第一条指令的地址,它获取该指令。到第一个 fetch 没有软件,这是逻辑。

取决于芯片供应商如何设计芯片,他们如何定义地址 space,并了解芯片或电路板设计中的寻址不是某种通用的东西,对程序员来说它是,但实际上并非如此。有许多带地址的总线,这些地址 space 特定于设计的那部分。当您看到 stm32 或其他带有引导加载程序和 strap(boot0/boot1 引脚)时,处理器总线另一端的逻辑可能会在众所周知的地址处看到一个提取(意味着实现逻辑的两个人)为逻辑编写软件的人知道这是事情开始的特定地址,如果你不把东西放在那里,它就不会 boot/work) 但如前所述,芯片供应商可以做任何他们想做的事那而且经常这样做。作为程序员,这很容易理解,因为逻辑并不比软件更神奇:

if strap == 0  return flash_bank_0[address&mask]
else           return flash_bank_1[address&mask]

对于这段代码前面解码的某个地址范围,而且两个bank都可以直接寻址:

如果地址[24]==0 return flash_bank_0[地址&掩码] else return flash_bank_1[地址&掩码]

通过这种方式,您可以在 stm32 中看到地址 0x00000000 和 0x08000000 或其他供应商芯片中的地址 0x00000000 和 0x01000000,例如映射到相同的(闪存)内存。

原因是 cortex-ms 是基于矢量的,有一个 table 地址指向代码,而不仅仅是已知地址处的指令(例如全尺寸手臂 arm7、arm9、 arm11,皮质-a)。您使用它的方式是将 table 中的重置地址设置为基于 0x08000000,因此当处理器读取 0x000000xx 时,它被告知从 0x0800xxxx 获取指令并且它确实如此。当表带是另一种方式时,它会找到一个不同的闪光灯,它可能有也可能没有固定的 space,它可能只能从 if-then-else 中看到。 (使用 cortex-m 和 SWD 调试器和软件很容易看到)。

stm32 的逻辑是,如果 strap 设置为 运行,用户应用程序将获取我猜的四个字,如果第一个或特定的是全 1 或某些芯片全为 0 (很多时候flash/rom重置为1,因为版本中有保存晶体管的逻辑,所以该位为0,但我们看到它是1,位都反转了,但这不是硬和快速规则,非常常见)logic/state 机器将为 stm32 实现没有用户应用程序并将加载引导加载程序。现在很有可能设计实际上总是启动引导加载程序并且那里有查看应用程序闪存的软件,但我认为我自己和该站点上的其他人认为情况并非如此,但我们 none 在那里工作也没有设计的可见性。在任何一种情况下,处理器然后开始执行它找到的东西并且它被告知从这个地址获取并且它确实这样做了,这是非常愚蠢的,程序员必须确保东西在那个地址,并且每条指令都必须布局为了像火车轨道一样正确,任何间隙或错误都会使轨道偏离 rails,否则火车很愚蠢,它只会沿着轨道行驶。作为人类,我们称软件为 post 或引导加载程序或应用程序或其他名称。它只是软件。一旦处理器启动,如果某些软件加载并且 运行s 其他软件处理器不知道它是愚蠢的,它只是继续执行它在轨道上滚动时输入的指令。

简答:

功率上升到芯片指定的水平。在芯片指定的时间复位应该被释放。这会释放状态机以根据需要准备好芯片并释放处理器。基于其设计的处理器要么从已知位置获取其第一条指令,要么从已知位置读取,并且用户植入的值是第一条指令所在的地址。在那之后,根据芯片的架构,第一条指令的执行和基于该指令的更多指令的执行将继续,直到它崩溃或关闭或复位。

没有魔法。

那里有许多很好的开放内核,您可以使用免费工具对其进行仿真,并查看(使用免费工具)使该芯片工作的内部信号,您可以看到 post 重置 activity 导致第一次获取,然后从那里执行所有操作。