【发布时间】:2016-08-10 22:29:09
【问题描述】:
我正在使用 Atmel Studio 7.0。
当我试图理解freeRTOS的代码时,我来到了这个功能。
/*
* Low-level initialization routine called during startup, before the main
* function.
* This version comes in replacement to the default one provided by the Newlib
* add-ons library.
* Newlib add-ons' _init_startup only calls init_exceptions, but Newlib add-ons'
* exception vectors are not compatible with the SCALL management in the current
* FreeRTOS port. More low-level initializations are besides added here.
*/
int _init_startup(void);
int _init_startup(void)
{
/* Import the Exception Vector Base Address. */
extern void _evba;
#if configHEAP_INIT
extern void __heap_start__;
extern void __heap_end__;
portBASE_TYPE *pxMem;
#endif
...
正如您在评论中看到的那样,这个函数在 main 之前被调用,但是我不明白是谁调用了这个函数。
经过一番研究,我说这个函数可以在链接描述文件中调用,但事实并非如此,链接描述文件看起来像:
/* Default linker script, for normal executables */
OUTPUT_FORMAT("elf32-avr32", "elf32-avr32",
"elf32-avr32")
OUTPUT_ARCH(avr32:uc)
ENTRY(_start)
/* Do we need any of these for elf?
__DYNAMIC = 0; */
我希望在此文件中找到对 _init_startup 的调用,但事实并非如此。
总结一下我的问题:
1- 我在哪里可以找到_init_startup的电话
2- 为什么在链接器脚本中我有ENTRY(_start) 而不是ENTRY(main)
3- 我在哪里可以找到_start 的定义
非常感谢。
【问题讨论】:
-
芯片上电或复位时,会跳转到内存中的特定地址(开始执行代码)。链接器安排启动代码映射到该地址。
-
_start(或start)很可能是汇编文件中的标签,您还可以在其中找到对您找到的 C 函数的调用。 -
@EOF 感谢您的反馈;是的,但我想知道在 main 之前执行了哪些代码,如果是“在 main 之前执行的代码”,在链接器脚本中调用它的位置或确切的位置?
-
@DanielJour 是的,它看起来像那样,但让我抓狂的是我没有找到这个 .s,here,它说 crt0.s 在我的工具链中调用了这个函数我只有 crt.o,目标文件,这意味着我不知道发生了什么。我认为这不公平。
-
每个系统都有某种方式的启动例程,通常通过复位中断向量直接调用,它设置了非常基础的 ABI:堆栈指针、看门狗和 LVD、内存映射、初始化。 bss 和 .data 部分等。完成后,它会调用
main。在现代嵌入式编译器上,您通常可以通过编译器免费获得此代码。