embedded - 固件文件的常见结构是什么?

标签 embedded executable firmware

我在嵌入式编程方面完全是 n00b。假设我正在使用编译器构建固件。此操作的结果是一个文件将被闪存到(我猜)MCU 的闪存中,例如 ARM 或 AVR。

我的问题是:此类生成的包含固件的文件使用哪些常见结构(如果有)?

我来自桌面开发,我知道例如对于 Windows,编译器很可能会生成 PE或 PE+,而类 Unix 系统我可能会得到 ELFCOFF ,但对嵌入式系统一无所知。

我也明白这在很大程度上取决于许多因素(编译器、ISA、MCU 供应商、操作系统等),所以我至少可以举一个例子。

更新:我将对所有提供使用结构示例的答案进行投票,并将选择我认为最能调查最先进技术的答案。

最佳答案

固件文件是 Executable and Linkable File ,通常处理为二进制 (.bin) 或文本表示的二进制 (.hex)。

此二进制文件是写入嵌入式闪存的确切内存。当您第一次为电路板供电时,内部引导加载程序会将执行重定向到您的固件入口点,通常位于地址 0x0。

从那里开始运行的是你的代码,这就是为什么你有一个启动代码(通常是 startup.s 文件),它将配置时钟、堆栈指针寄存器、向量表、将数据部分加载到 RAM(你的初始化变量),清除零初始化部分,也许您希望将代码复制到 RAM 并跳转到副本以避免从 FLASH 运行代码(在某些平台上可能更快),等等。

在操作系统上运行时,所有这些平台选择和资源都不受用户代码的控制,您只能链接到操作系统库并使用提供的 API 来执行低级操作。在嵌入式中,它是 100% 的用户代码,您可以访问硬件并管理其资源。

毫不奇怪,操作系统以与固件类似的方式启动,因为两者都与处理器、内存和 I/O 接触。

所有这一切,也就是说:固件的结构类似于任何已编译程序的结构。在加载期间由操作系统组织在内存中的数据部分和代码部分,或者在嵌入式运行时由程序本身组织。

一个主要区别是 firwmare 二进制中的内存寻址,通常地址是 physical RAM address ,因为您在大多数微 Controller 上没有内存映射功能。这对用户是透明的,编译器会将其抽象出来。

另一个显着的区别是堆栈指针,在操作系统上,用户代码不会自己为堆栈保留内存,它会在操作系统上中继。使用固件时,出于与以前相同的原因,您必须在用户代码中执行此操作,没有中间人为您管理它。编译器的链接描述文件将保留相应配置的堆栈和堆内存,并且将有一个 stack_pointer .map 文件上的符号让您知道它指向的位置。你不会在操作系统程序的 map 文件中找到它。

关于embedded - 固件文件的常见结构是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40853918/

相关文章:

c - 在此代码中可以将 8 位或 16 位值存储到 16 位对齐缓冲区吗?

arduino - boot_app0.bin 和 bootloader_dio_80m.bin 文件有什么用? (ESP32-Arduino 集成开发环境)

Android:不同型号的原始固件识别字符串

linux - 使用来自不同系统的 GDB 分析核心转储会给出 .dynamic 部分警告

c++ - 如何释放 Kiss FFT 分配的内存?

c++ - CodeLite 未指定可执行文件,使用 'target exec' 错误

c++ - Mac - C++ - 创建 file.exe

c - 未声明的变量。 [标题问题]

c - 用 C 编写注释的更好方法是什么?

java - 创建使用 Sqlite DB 的 eclipse 项目的 .jar