This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS570LC4357:是否将“#39;_c_int00'或“#39;_main&#39 用作 entry_point?

Guru**** 2524480 points
Other Parts Discussed in Thread: HALCOGEN

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1552981/tms570lc4357-is-there-any-difference-whether-_c_int00-or-_main-are-used-as-entry_point

器件型号:TMS570LC4357
主题中讨论的其他器件:HALCOGEN

工具/软件:

TI ARM CGT 编译器允许使用-- entry_point 指定入口点

HALCoGen 生成_c_int00 作为入口函数、因此在链接时可以省略该选项

编译器会手动说明部分中的状态  定义入口点(--entry_point 选项)

•符号_c_int00 的值(如果存在)。 如果要链接由 C 编译器生成的代码、则_c_int00 符号必须作为入口点。

•符号_main 的值(如果存在)

为什么_c_int00 有额外的信息、而不是_main 的信息

主要问题是:是否存在 不限 使用_main 而非_c_int00 作为入口函数时生成的二进制代码有何差异?

#pragma CODE_STATE(_c_int00, 32)
#pragma INTERRUPT(_c_int00, RESET)
void _c_int00(void) { }

比较

#pragma CODE_STATE(_main, 32)
#pragma INTERRUPT(_main, RESET)
void _main(void) { }

在链接的 C 工程中(为清晰起见,我们明确希望设置 RTS 库):

armcl.exe
..
--run_linker
...
--library=rtsv7R4_A_be_v3D16_eabi.lib
...
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    对延迟的回复表示歉意!


    是的、将 _main  _c_int00 用作入口函数时、执行流程和生成的二进制文件存在根本差异。 该函数 _c_int00 是 C 运行时支持入口点、负责在 main 调用函数之前进行硬件和软件初始化。  _main 用作直接入口点会绕过这种关键的初始化。

    详细阐述

    提供的文档说明了 _c_int00  _main  Hercules 微控制器的不同作用和在其启动序列中的作用。

    c_int00 的角色

     _c_int00 函数是器件复位后立即执行的初始入口点。 其地址直接放置在异常向量表的复位向量位置。 其主要职责是执行低级硬件和 C 运行时环境初始化。

    • 文档“在基于 HerculesTm 的微控制器上共享异常矢量“指出:“复位矢量中的第一个条目是直接分支到用于初始化控制器的_c_int00 函数。“ 它还将复位矢量的目标称为“主硬件初始化例程“。
    • 本文档和“CAN Bus Bootloader for HerculesTm Microcontrollers (用于 HerculesTm 微控制器的 CAN 总线引导加载程序)“中的汇编代码示例显示了显式分支到 _c_int00的复位矢量。

    异常向量表示例(来自 SPNA236):

    ; interrupt vectors resetEntry: 0x00 b _c_int00

    这表明在复位时、处理器立即跳转到并执行 _c_int00 标签处的代码。 此代码通常是运行时支持 (RTS) 库的一部分、用于设置堆栈、初始化全局变量、然后调用用户的 main 函数。

    main 的角色

     _main 函数是用户 C 应用程序代码的标准入口点。 然而、这并不意味着由硬件复位直接调用。 相反、 _c_int00在建立必要的运行时环境后、它由引导代码(从开始)调用。

    • 文档“基本 PBIST 配置和对电流消耗的影响“列出了一个源文件、 Boot.asm并将其函数描述为:“初始化堆栈、调用_init 和_main“。 这清楚地表明 _main 在堆栈初始化之后、在引导序列的后面部分调用。

    下表来自 PBIST 示例项目、显示了负责调用的文件 _main

    文件名 说明
    intvecs.asm 中断矢量设置文件。
    boot.asm 初始化堆栈、调用_init 和_main。
    swi_util.asm SWI 中断服务例程。
    System_Init 初始化系统、启用外设。
    SCI1_RS232.c RS232 功能。
    TMS570_PBIT_Test.c 演示 PBIST。
    TMS570_PBIT_Test.pjt 工程文件中。

    结论

    使用 _main 作为直接入口点(例如,使用) #pragma INTERRUPT(_main, RESET)将指示处理器 _main 在重置时立即跳转到。 这将绕过通常由执行的基本设置例程 _c_int00、如栈指针初始化和变量初始化。 这几乎肯定会导致不正确的程序行为或系统崩溃。

    编译器手册注释 _c_int00 “如果要链接 C 编译器生成的代码、则必须是入口点“存在的原因是 C 环境具有关于机器状态的固有假设(例如,有效栈)、并且 _c_int00 是 TI 工具链提供的用于满足这些假设的标准机制。

    --
    此致、
    Jagadish。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢这个非常详细的解释! 但我不确定我是否完全明白了。

    但是、我只是重命名函数(并修复*。c 和*。asm 文件中的所有引用)时、仍然没有完全得到区别、即我会执行所有硬件等操作。在函数中进行初始化、只是函数的名称不同。

    如果有一个由名称创建的* just*差异,为什么有编译器选项?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    对延迟的回复表示歉意。

    c_int00 是由 TI 的编译器(和 HALCoGen)生成的默认启动入口点。

    它不是用户代码、而是由 C 运行时支持 (RTS) 库提供的启动例程。

    它处理:

    C 环境的低级初始化。

    初始化.data 和.bss 段(将初始化的变量从闪存复制到 RAM,消除未初始化的变量)。

    设置堆栈、堆等

    初始化完成后调用 main()。

    因此、_c_int00 可确保程序在有效的 C 环境中启动。

    _main 只是 C 应用程序的 main 函数。

    如果通知链接器直接跳转到_main 作为入口点、则会绕过启动代码 (_c_int00)。

    这意味着全局/静态变量不会正确初始化、也不会设置 C 运行时、您需要在执行任何 C 代码之前负责所有低级初始化。

    [引述 userid=“418899" url="“ url="~“~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1552981/tms570lc4357-is-there-any-difference-whether-_c_int00-or-_main-are-used-as-entry_point/5988371

    但是、我只是重命名函数(并修复*。c 和*。asm 文件中的所有引用)时、仍然没有完全得到区别、即我会执行所有硬件等操作。在函数中进行初始化、只是函数的名称不同。

    如果有一个由名称创建的* just*差异,为什么有编译器选项?

    [/报价]

    您可以使用不同的名称对其进行重命名:

    例如、我使用 _c_int01 重命名它、在编译代码和执行代码时没有看到任何问题。

    唯一的问题是、如果我们从 HALCoGen 重新生成代码、它将再次使用“_c_int00"对“对其进行重命名

    如果你不想发生这种情况,那么你应该这样做:

    您应该在 HALCoGen 中更改函数名称:

    如果您在此处进行更改、这将更改所有相应位置的函数名称:

    --
    此致、
    Jagadish。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我仍然不明白为什么你继续说

    如果告知链接器直接跳转到_main 作为入口点、 您绕过启动代码 (_c_int00)。

    我的启动代码位于_main() 中、我将 HALCoGen、链接器脚本等中的所有引用从_c_int00 更改为 _main。

    是的、我绕过了 _c_int00(我需要的内容)函数、并在_main 中执行我要执行的所有操作(包括启动代码)、因此不会绕过启动代码。

    我真的不明白这会如何造成问题、但我想理解。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [quote userid=“418899" url="“ url="~“~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1552981/tms570lc4357-is-there-any-difference-whether-_c_int00-or-_main-are-used-as-entry_point/5995078 url=“我的启动代码位于_main () 中、我将 HALCoGen、链接器脚本等中的所有引用从_c_int00 更改为  _main。[quote userid=“418899" url="“ url="~“~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1552981/tms570lc4357-is-there-any-difference-whether-_c_int00-or-_main-are-used-as-entry_point/5995078 是的、我绕过了_c_int00 函数、因此我不想引用启动代码[、也不想引用启动代码[

    如果你这样做,那么应该没有任何问题。