了解 C 运行时环境 (ARM) - 从哪里开始

2024-02-26

我是一名嵌入式开发人员,主要使用 ARM Cortex-M 设备。最近,我切换到 Linux,并决定了解更多有关构建/组装/链接过程、如何编写 makefile 等的信息,因为我使用的是 IDE(IAR、Keil、Eclipse 等),其中很多东西都是自动化的,并且用户可以使用实际上不知道后台发生了什么。目标是更多地了解这个低级过程,以及如何正确使用这些工具,而不仅仅是依赖 IDE 默认设置。

编写 makefile 后,我就可以构建我的应用程序。然而,我决定通过直接调用链接器(而不是通过编译器)来手动执行链接过程,令人惊讶的是出现了问题!对 libc、__libc_init_array 中的 _init 函数、_exit 等未定义的引用是问题所在。经过一整天的调查,我能够手动包含所有目标文件(crt0.o、crti.o)和库(libnosys.a)。显然编译器会自动做这些事情。

在克服了这些麻烦之后,我发现我对这些内部结构完全一无所知。为什么我需要一些 ctr0.o、crti.o 等。它们从哪里来等。它是否链接到编译器/链接器或 C 运行时库或系统?

我想了解更多有关这些内部结构的信息,但是,我不确定我实际上在寻找什么。它是一个库、系统、编译器吗?

我明白,系统(MCU)需要初始化 RAM 中的变量和其他东西,但是我错过了完整的图片。您能给我推荐一本关于这些事情的好书/手册吗?我实际上在寻找什么?

Edit:

在与您讨论之后,我很可能弄清楚了我需要什么,所以我将按照以下方式重新表述我的问题:

1) 我收到了一个 MCU(假设是 STM32F4xx),我应该创建一个闪烁的 LED 示例。所有这些都应该从头开始,自己的启动代码,不使用外部库等。

2)在第二步中,有人告诉我这一切都已经被其他人完成了(GCC工具链/标准库、MCU供应商启动文件等)。所以我只需要理解/将我的工作与所做的事情联系起来,并比较差异,为什么他们这样做等等。

所有这些都得到了 @mbjoe 的回答+我发现了一些有趣的读物:https://www.amazon.com/Embedded-Shoestring-experience-designing-software/dp/0750676094 https://rads.stackoverflow.com/amzn/click/com/0750676094

感谢大家的帮助并指导我正确的方法!


您所指的模块(ctr0.o、crti.o、_init、__libc_init_array、_exit)是由 IAR 和/或 Keil 预构建的库/目标文件/函数。正如您所说,在运行 main() 函数之前,需要它们来初始化环境(全局变量初始化、中断向量表等)。

在这些库/目标文件中的某个时刻,C 或汇编语言中将会有一个如下所示的函数:

void startup(void)
{ 
    ... init code ...

    main();

    while(1);   // or _exit()
}

您可以查看这些从头开始构建启动代码的示例:

http://www.embedded.com/design/mcus-processors-and-socs/4007119/Building-Bare-Metal-ARM-Systems-with-GNU-Part-1--入门 http://www.embedded.com/design/mcus-processors-and-socs/4007119/Building-Bare-Metal-ARM-Systems-with-GNU-Part-1--Getting-Started

https://github.com/payne92/bare-metal-arm https://github.com/payne92/bare-metal-arm

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解 C 运行时环境 (ARM) - 从哪里开始 的相关文章

随机推荐