我对用于微控制器(如AVR atmega)的引导加载程序和启动代码之间的区别感到非常困惑,我还有一些需要回答的问题:
我能同时使用这两种吗?或者当我使用一种,我不能使用另一种?
在重新启动AVR时,哪一个应该先运行?
哪一个是用汇编写的,哪个是用C写的?
引导加载器可以执行启动代码功能吗?类似(将任何初始化的数据从ROM复制到RAM,初始化处理器的堆栈指针,调用main,...etc)。
在AVR中哪一个是“内置”的,我应该开发哪一个?
提前谢谢!
发布于 2016-04-20 22:29:03
我认为你说的是引导,而不是引导加载器。C引导程序确实希望在程序集中编写,否则就会出现鸡和蛋问题。您可以用C编写其中的一些代码,但C代码不能完全符合标准(不能假设bss中的变量为零,如果C代码同时执行这两种操作,也不能初始化预初始化变量)。
需要引导一种高级语言与微控制器或特定的指令集无关,它是全局需要的。一种高级语言,即使是C,也有某些假设(已经设置了堆栈指针,用初始值定义的全局变量是该值,而其他变量是零,任何C库准备(堆位置))都是在main()之前完成的,或者在进入C的入口点之前完成的。其他语言也是如此。
这就是为什么引导程序通常在asm中的原因,因为它没有这些规则,而且它可以访问高级语言没有的堆栈指针。
如果你愿意放弃一些语言兼容性,那么引导程序就会更简单。使用arm cortex的硬件提供了一种解决方案,用于在没有代码的情况下初始化堆栈指针,如果您希望将其用于入口点,则启动到C中,但是如果这样做,则不会得到全局变量初始化,因此如果愿意放弃它,则只需要一种方法来定义向量表(asm指令到目前为止是最简单的,因为所有工具都在那里)。
现在,也许您所称的启动代码,我称之为引导。
引导加载程序是用任何你喜欢的语言编写的程序,它会弹出芯片或系统。它可以打开时钟或打开ddr或擦除内存,以启用ecc,无论您需要什么。然后启动主应用程序(用任何语言编写,引导加载程序和主应用程序都按照上面提到的语言规则启动代码,作为我使用的术语引导)。这是引导加载程序的引导部分。加载程序部分意味着有人可以在启动应用程序时中断引导进程,允许开发人员以某种方式试验不同的应用程序,要么用非易失性ram覆盖应用程序,要么将应用程序加载到ram中,然后运行应用程序,而不是正常的引导路径。
有些引导加载器是按部分设计的,以便您可以使用引导加载程序更新引导加载程序,例如,可以设计引导加载程序,以便它在执行其他操作之前将自己复制到ram中,然后如果您想修改引导加载程序本身,可以使用引导加载程序覆盖闪存,希望不要自己砖头。您还可以设置一些保护来防止这种情况,比如有两个引导加载程序,第一个具有检查自身是否损坏的代码,或者如果您有一个带或者它启动次要程序的任何东西,则次要程序可以用来覆盖主程序可以覆盖次要程序的主程序。您仍然有一个鸡和鸡蛋的问题,在前面的一些小代码,检查带或做一个检查和之前,开始进入其余的代码。你打破了它,你仍然是砖。
像AVR这样的芯片有硬件恢复的方式,也有硬件保护的引导加载器,有时是工厂编程,然后你才能得到芯片,你可以用皮带或按下键或任何东西来启动和重新加载你的应用程序。
发布于 2016-04-20 20:39:10
“启动代码”实际上称为C运行时。它是由编译器添加到程序中的。您可以在安装了WinAVR和Atmel Studio的src文件中看到汇编程序代码。它将被称为crt5.asm,这取决于您使用的是哪个处理器。
如果您想修改C运行时,可以。编写自己的副本,并使用编译器开关--nostartfiles编译程序文件。您可以用程序集或C编写它,但是程序集更容易。
引导加载器是程序代码,它也被调用在C运行时和程序代码之前运行。代码测试是否满足条件,就像按下按钮一样。如果按下按钮,引导加载程序将新代码加载到闪存中。否则,代码跳转到重置向量,C运行时和代码正常运行。
引导加载程序的代码位于flash接近尾端的一个特殊部分,一些熔断器设置将导致在那里开始执行,而不是像通常那样在闪存开始时在重置向量处开始执行。
关于C与汇编语言的问题,答案是任何代码都可以用两种语言编写。编译器将把源代码转换为被称为目标代码的目标体系结构的机器指令。通常,在编译成对象代码之前,有一个编译器选项输出转换为程序集指令的C源代码,以便您可以查看它。如果您想用C编写代码,然后在组装阶段修改代码,这是很方便的。
https://stackoverflow.com/questions/36754306
复制相似问题