我对由于加电引起的复位有疑问:
1.据我所知,微控制器硬连线是从一些特定的存储器位置开始,例如0000H上电。在0000h,是否写入中断服务程序用于复位(堆栈指针和程序计数器的初始化等)或复位地址在0000h(比如7000),以便微控制器跳转到7000地址并写入堆栈和PC的初始化
2.Who写这个重置服务程序?它是微控制器芯片的制造商(英特尔或微芯片等)或任何程序员可以改变这个复位服务程序(例如,程序员在上电复位时将电脑从7000h改为4000h,导致第一条指令从4000取而不是7000)。
3.如何将堆栈指针和程序计数器初始化为相应的初始地址,因为上电微控制器不处于将地址放入堆栈指针和程序计数器寄存器的状态(直到复位服务程序才进行初始化)。
提前致谢
答案 0 :(得分:2)
处理器内核通常会像你说的某种表的起始地址那样是一个地址列表,或者像执行指令的ARM一样。缠绕在核心但芯片内部可能会有所不同。不像8051,mips,arm,xscale等芯片供应商特定的核心将具有更广泛的不同答案。例如,一些微控制器供应商将查看带式引脚,如果在复位释放后带子以某种方式接线,则它将从芯片内部的特殊启动闪存执行,例如,您可以使用引导加载程序对用户启动闪存进行编程。 。如果表带没有以某种方式绑定,那么有时它会引导您的用户代码。我知道的一个供应商仍然启动它们的引导加载程序闪存,如果向量表具有有效的校验和,那么它们会跳转到向量表中的复位向量,否则它们将处于引导加载程序模式,等待您与它们通信。
当你进入更大的处理器,非微控制器,其中软件存在于处理器外部的启动闪存(处理器的独立芯片)或某些在重置之前以某种方式管理的ram等。这些通常遵循规则对于核心,从地址0xFFFFFFF0开始,或者从地址0x00000000开始,如果那里有垃圾,那么很好地解决未定义的指令向量,如果那是垃圾,只是挂在那里或坐在无限循环中调用未定义的指令向量。这适用于ARM,例如你可以构建一个带有从工厂擦除的启动闪存的板(所有0xFF)然后你可以使用jtag来停止手臂并在第一次编程闪存并且你没有必须拆焊或套接字或预编程任何东西。只要您的引导程序没有悬挂臂,您就可以拥有不可思议的设计。 (实际上你经常可以把手臂放在复位状态,并且仍然可以使用jtag调试器来处理它,而不用担心使用jtag引脚或悬挂臂芯的坏代码)。
简短回答:有多少不同的处理器芯片供应商?有许多不同的解决方案,您可以考虑多种解决方案,并且已经部署了更多解决方案。将重置处理程序地址放在内存中的已知位置是最常见的。
编辑:
问题2和3.如果您购买芯片,某些微控制器具有此受保护的引导加载程序,但即使这样,您通常也会编写将由产品使用的引导代码。部分启动代码是初始化堆栈指针并准备内存并调出部分芯片和所有这些好东西。有时芯片供应商会提供示例。如果您购买的是板级产品,那么通常您会找到一个板级支持包(BSP),其中包含工作示例代码以启动电路板并可能做一些事情。比如说beagleboard或open-rd或embeddedarm.com带有引导加载程序(u-boot或其他),有些已预先安装了linux。像这样的板子用户通常只是写一些linux应用程序/驱动程序并将它们添加到bsp中,但是你并不局限于此,你经常被欢迎完全重写并替换引导程序。编写引导加载程序的人必须设置堆栈并启动硬件等。
像gameboy advance或nds之类的系统,供应商有一些调用你的启动代码的启动代码。所以他们可能有堆栈和这样的设置,但他们正在交给你,系统的大部分可能会启动,你只需要决定如何切片记忆,你想要你的堆栈,数据,程序,等 有些供应商希望保持这种东西的控制或秘密,其他供应商则不然。在某些情况下,您最终可能会得到一块没有示例代码的电路板或芯片,只有一些数据表和参考手册。如果你想进入这个行业虽然你需要准备编写这个启动代码(在汇编程序中),可能会调用一些C代码来启动系统的其余部分,那么这可能会启动主操作系统或申请或其他。微型滚轮听起来就像你正在玩的那样,你的问题的答案在芯片供应商用户指南中,有些供应商比其他供应商更好。在文档中搜索单词reset或boot,试图弄清楚它们的引导方案是什么。我建议你用“美元票”来选择更好的供应商。一个供应商有糟糕的文档,秘密文档,糟糕的支持,不给他们你的钱,花钱你的钱可以免费下载,写得很好的文档,写得好的例子和用户论坛与全职员工一起回答问题。有时除了严肃的付费客户之外,文档都不可用,这取决于市场。大多数通用嵌入式系统虽然是公开记录的。质量差异很大,但文档等都在那里。
答案 1 :(得分:2)
参考您的编号:
硬件复位过程取决于处理器,将在部件的数据表或参考手册中进行详细描述,但您的描述通常是情况 - 不同的架构可能会有微妙的变化
虽然一些微控制器包含一个可能包含启动代码的基于ROM的启动加载程序,但通常这种启动加载程序仅用于通过通信端口加载代码,可直接编程闪存或加载和执行二级引导加载程序到RAM,然后编程闪存。就C运行时启动而言,这是随编译器/工具链提供的,或者您自己在汇编程序中编写它。通常,即使编译器供应商提供了启动代码,它也会作为源提供,以便与您的应用程序进行组装和链接。编译器供应商无法始终了解内存映射,SDRAM映射和时序,或处理器时钟速度或硬件中使用的振荡器晶振等内容,因此启动代码通常需要通过必须实现的初始化存根来进行自定义或扩展。你的硬件。
在ARM Cortex-M设备上实际上,初始PC和堆栈指针实际上是由硬件加载的,它们存储在复位地址并在加电时加载。但是在一般情况下你是对的,复位地址要么包含启动代码,要么包含启动代码的向量,在前Cortex ARM架构中,复位地址实际上包含跳转指令而不是真正的向量地址。无论哪种方式,C / C ++运行时的启动代码必须至少初始化堆栈指针,初始化静态数据,执行任何必要的C库初始化并跳转到main()。对于C ++,它还必须在调用main()之前执行任何全局静态对象的构造函数。
答案 2 :(得分:1)
完全取决于您使用的控制器/嵌入式系统。我在游戏开发中使用的那些IP点在RAM中的起始地址。编译器提供的引导代码初始化static / const内存,设置堆栈指针,然后将执行跳转到某种类型的main()例程。较旧的系统也从固定地址开始,但您必须手动设置堆栈,启动向量表以及汇编程序中的其他内容。对于我已经完成的工作,起始汇编程序文件的通用名称是CRT0.s。
所以1.你是对的。微处理器必须从某个固定地址开始。 2. ISR可以由制造商或编译器创建者提供,或者您可以自己编写一个ISR,具体取决于相关系统的复杂程度。 3.堆栈和初始编程器计数器通常通过某种类型的引导程序来处理,这些程序通常可以用您自己的代码覆盖。见上文。
最后:步骤取决于芯片。如果存在任何类型的电源中断,RAM可能会被加扰,并且应该重写所有ISR向量表和启动代码,并且应该像应用程序一样启动应用程序。但是,请阅读您的文档!我确信那里有特定于平台的东西会根据你的具体情况回答这些问题。