了解C运行时环境(ARM)-从哪里开始 [英] Understanding C runtime environment (ARM) - where to start

查看:76
本文介绍了了解C运行时环境(ARM)-从哪里开始的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'am embedded developer working with ARM Cortex-M devices mainly. Recently I've switched to Linux and decided to learn more about the build/assemble/link process, how to write makefiles etc. as I was using IDEs (IAR, Keil, Eclipse etc.) where lot of stuff is automated and the user has actually no clue what is happening in the background. The target is to understand more of this low level process, how to use the tools properly and not just rely on the IDE default settings.

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

After writing a makefile I was able to build my application. However, I decided to perform the link process manually by invoking the linker directly (not through compiler) and surprisingly troubles showed up! Undefined references to libc, _init function in __libc_init_array, _exit etc. were the issues. After whole day of investigations I was able to include all the object files (crt0.o, crti.o) and libraries (libnosys.a) manually. Apparently the compiler is doing this stuff automatically.

克服这些麻烦之后,我发现,对于这些内部原理,我绝对一无所知.为什么我需要一些ctr0.o,crti.o等.它们来自哪里等等.它链接到编译器/链接器或C运行时库还是系统?

After overcoming these hassles I figured out, that I've absolutely no clue about these internals. Why do I need some ctr0.o, crti.o etc. Where those come from etc. Is it linked to the compiler/linker or C runtime libraries or the system?

我想详细了解这些内部组件,但是我不确定我实际上在寻找什么.是一个库,一个系统,一个编译器?

I would like to learn more about these internals, however, I'm not sure, what em I looking for actually. Is it a library, system, compiler all together?

我了解,系统(MCU)需要初始化RAM和其他内容中的变量,但是我错过了完整的画面.你能指导我读一本好书/手册,阅读这些东西吗?我到底在找什么?

I understand, that the system (MCU) need's to initialize the variables in RAM, and other stuff, however I miss the complete picture. Can you direct me to a good book/manuals, readings about these things, please? What am I looking for actually?

在与您讨论之后,我最有可能想出了我需要的东西,因此我将按照以下方式重新表述我的问题:

After discussions here with you I most probably figured out, what I need, so I would rephrase my question following way:

1)我已经收到一个MCU(例如STM32F4xx),我应该创建一个闪烁的LED示例.所有这些都应从头开始,拥有自己的启动代码,而不使用外部库等.

1) I've received an MCU (let's say STM32F4xx) and I should create a blinking LED example. All this should be done from scratch, own startup code, no usage external libraries etc.

2)在第二步中,有人告诉我所有这些工作已经由其他人完成(GCC工具链/标准库,MCU供应商启动文件等).因此,我只需要了解我的工作/将其与所做的事情联系起来,并比较它们之间的差异,为什么要采用这种方式,等等.

2) In the second step, someone told me that all this has already been done by others (GCC toolchain/standard libraries, MCU vendor startup files etc.). So I just need to understand/link my work with what was done and compare the differences, why they do it that way etc.

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

All this was answered by @mbjoe + I found some interesting reading: https://www.amazon.com/Embedded-Shoestring-experience-designing-software/dp/0750676094

感谢大家的帮助,并以正确的方式指导我!

Thank all of you for your help and directing me the right way!

推荐答案

您所指的模块(ctr0.o,crti.o,_init,__ libc_init_array,_exit)是IAR和/或基尔.正如您所说的那样,在运行main()函数之前需要它们来初始化环境(全局变量初始化,中断向量表等).

The modules you are referring to (ctr0.o, crti.o, _init, __libc_init_array, _exit) are prebuilt libraries/object files/functions by IAR and/or Keil. As you are saying they are needed to get the environment initialized (global variables initialization, interrupt vector table, etc.) before running your main() function.

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

At some point in those libraries/object files there will be a function in C or assembly like this:

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

    main();

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

您可能会研究以下示例,这些示例从头开始构建启动代码:

You may look into these examples that build the startup code from scratch:

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

这篇关于了解C运行时环境(ARM)-从哪里开始的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆