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.

[参考译文] CCS/F28M35H52C:Concerto GNU编译器支持ARM cortex m3内核

Guru**** 2578945 points
Other Parts Discussed in Thread: F28M35H52C, CONTROLSUITE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/634545/ccs-f28m35h52c-concerto-gnu-compiler-support-for-arm-cortex-m3-core

部件号:F28M35H52C
主题: controlSUITE中讨论的其他部件

工具/软件:Code Composer Studio

您好,

我正在尝试使用GNU ARM Linero编译器编译一个简单的盲应用程序,并在Concerto ARM cortex m3内核上运行它。 我使用基于F28M35H52C的Concerto评估板(请访问下面的链接)

 www.ti.com/.../tmdsdockh52c1

但是在CCS工作室,如果我选择GNU Linero编译器来构建我的应用程序,它会弹出一条警告,说CCS不会自动创建任何链接程序脚本或启动代码,这些基本上是关键的初始化文件,甚至是为了让一个简单的闪烁的应用程序运行。  

因此,我现在创建了自己的链接程序脚本和皮层m3内核的启动代码,类似于我从embedded.com网站上的一位作者那里阅读的文章。

现在我可以编译和链接项目了。 但是在调试过程中,当我进入main并尝试初始化外设寄存器以触发板载LED时,它可能会越过RCGC2寄存器,当我尝试步过GPIODIR寄存器时,代码中断进入某种未定义状态 (我认为它会重置)。 我认为链接程序脚本或启动函数是正确的。  

非常感谢有人能帮我解决这方面的问题。 我已经附上了我的整个项目,其中包含链接程序脚本和启动代码。  

这些文件非常通用,链接程序脚本命名为“concerto_f28m35h2c.lds”,启动文件命名为“startup _cs.c”。

e2e.ti.com/.../0410.Test.7z

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

    大多数Concerto客户使用TI ARM编译器构建ARM端代码。  您是否考虑过该解决方案?

    谢谢,此致,

    -George

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

    是的,我在Concerto ARM内核m3开发方面的前几个项目都涉及到TI编译器。

    但是,现在我打算将FreeRTOS移植到这个内核上,FreeRTOS需要GNU编译器,因此我迫切需要一个简单的盲程序来使用GNU编译器。

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

    您好,

    我一直在研究您的代码,从纯粹的编译器和项目的角度来看,我看不到它有任何问题。

    但是,在尝试向GPIO外围设备(GPIODATA或GPIODEN)写入数据之前,似乎未正确启用GPIO外围设备,这会导致预期的硬故障异常。

    当您调用GPIODATA之前,所有端口的所有GPIO寄存器返回"无法读取"状态时,我发现了这一点

    跳过GPIODATA后,xPSR寄存器的异常位字段显示0b1.1亿,它对应于硬故障异常。

    因此,这很快就脱离了编译器或工具的专业知识,因为设备论坛专家会知道如何正确初始化外设。  

    一个提示可能是尝试适应GCC并重建TI提供的支持库,并使用controlSUITE的单一示例的相同API。

    库源:C:\ti\controlSUITE\DEVICE_SUPPORT\f28m35x\V210\F28M35x_common\source
    Blinky示例: C:\ti\controlSUITE\DEVICE_SUPPORT\f28m35x\V210\F28M35x_Examples_Masters\Blinky\m3

    正如George所说,TI并未正式支持在该内核中使用GCC,因此您在集成工作中的知识很有可能领先于我们,但希望此帖子中的调试提示可以帮助您向前迈进。  

    希望这能有所帮助,

    拉斐尔

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

    您好,Rafael:

    感谢您的详细观察和回复。  

    在我继续发言之前,我提出了另一个看法。 如果我复制TI .gel文件中的同一条代码,则LED不会从.c文件初始化LED,而是正常亮起。 在这一点上,我感到十分困惑。 但是,我没有尝试过你的建议,下面是我的结果:   

    正如您建议使用TI支持的库一样,我集成了TI外设库源代码,支持cconcto cortex m3内核,结果证明是成功的,现在我能够点亮LED。 我认为它必须在初始化整个系统时钟时执行一些操作。  

    但目前有两个问题:

    1.指示灯工作正常,但它看起来只在我调试代码时执行,如果我对主板进行电源重置,应用程序似乎不会耗尽ROM。   

    2.作为下一步,我现在尝试初始化Systick计时器中断,在此尝试切换板载LED。 令我惊讶的是,中断从未触发。在进行故障排除时,我注意到Systick计数寄存器实际上正在倒计时,但中断实际上没有触发。  

    您能帮我解决这两个问题吗? 因为如果我能在ROM上中断和应用程序工作,我猜我会有一个强大的软件基础,以便我的项目能够顺利地继续下去。 正如您在回复中所述,如果我需要咨询其他设备专家支持团队,您可以将我的问题直接发送给相关团队。 如果我能在这方面获得设备专家的支持,我将不胜感激,因为我们正在计划尽快发布原型产品。   

    我已附上修订后的项目文件夹。  

    Thankse2e.ti.com/.../6232.Test.7z

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

    Preetham,

    [报价用户="Preetham Kashyap"]1. LED工作正常,但看起来它只是在我调试代码时执行,如果我对主板进行电源重置,应用程序似乎不会耗尽ROM。  [/引述]

    要使应用程序在独立模式下正常启动而不使用调试器,您必须了解并确保以下内容。

     >>应用程序必须编程到设备闪存中

     >>应用程序的入口点必须在闪存入口点进行编程,设备引导ROM将在引导结束时分支到该位置。

    >> 设备引导模式引脚应设置为引导至闪存配置。 设备TRM启动ROM章节对此有详细说明,请参阅TRM。

    TI controlSUITE中提供的闪烁示例支持上述所有功能,供您尝试。 您可以更改源代码以使用要切换的GPIO (连接到LED)并构建代码。

    如果您使用Code Composer Studio,则可以导入闪存示例并构建闪存配置,然后将其签出。 使用CCS获得此信息后,您可以检查所使用的链接器命令文件,并了解入口点部分是如何链接的。您可以迁移到不同的开发环境。 使用TI CCS将缩短您的开发时间,而且在论坛上也有很多支持。

    [QUETE USER="Preetham Kashyap]下一步,我要尝试初始化Systick计时器中断,在此尝试切换板载LED。 令我惊讶的是,中断从未触发。在进行故障排除时,我注意到Systick计数寄存器实际上正在倒计时,但中断实际上没有触发。  [/引述]

    controlSUITE附属资料 中有TI提供的Systick driverlib ( C:\ti\controlSUITE\device_support\f28m35x\v220\Mware\driverlib)。

    还有其他一些初始化Systick的示例,您可以参考它们来验证您是否为Systick正确设置了系统。  例如 :检查此项目。 C:\ti\controlSUITE\DEVICE_SUPPORT\f28m35x\v220\F28M35x_Examples_Masters\Enet_lwip\m3

    您必须注册中断处理程序并将NVIC基座初始化为用户内存。  计时器示例(C:\ti\controlSUITE\DEVICE_SUPPORT\f28m35x\v220\F28M35x_Examples_Master\timers\m3)显示了如何启用和配置中断,您可以使用代码中的Systick驱动程序库对Systick执行相同的操作。

    拥有TI CCS IDE环境也简化了对所有这些的检查。

    希望这有所帮助。

    此致

    Santosh Athuru

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

    您好,Santosh:

    感谢您的详细回复。  

    我觉得您的答案更倾向于使用TI控制套件外设库和TI编译器解决方案。

    然而,这与我要达到的目标完全相反。 在我之前的答复中,我把我的项目附加为一个zip文件,我使用GNU编译器编译并链接了它,我所有的问题都是基于GNU编译器,它要求我为cordto cortex m3内核编写启动代码和链接器脚本。  

    以下是我对各位建议的回应:

    1.我在项目中使用的.lds链接器文件与TI链接器工具使用的.cmd文件非常相似。 我还验证了闪存入口点应位于地址0x20.3万 (根据设备TRM)。 但是,我仍然不能在没有调试器的情况下作为独立运行此应用程序。  

    也许您可以在您的端运行我附加的项目并亲自验证。  

    2.关于Systick,我看到Systick外设得到了完美的初始化,我可以这样说是因为我可以在调试时验证Systick计数寄存器值是否确实减少了每个时钟周期。 但当该值达到零时,将不会触发中断。  

    我想您可以使用我的项目自行验证。  

    从我的角度看,在启动代码(中断向量表),链接程序脚本或在main.c文件中初始化系统时钟方面,我没有看到任何错误。

    因此,我需要您的设备专家帮助解决我在上述两个问题上可能缺少的问题。   

    期待您的回复。  

    谢谢

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

    Preetham,

    但是,这与我想要实现的目标完全相反。 在我之前的答复中,我把我的项目附加为一个zip文件,我使用GNU编译器编译并链接了它,我所有的问题都是基于GNU编译器,它要求我为cordto cortex m3内核编写启动代码和链接器脚本。  [/引述]

    您需要查看TI示例,并了解示例中的启动代码正在执行什么操作以及如何设置系统。 无论使用何种构建工具,设备初始化的功能都应保持不变。 您能否将您的器件初始化流程与TI示例中的流程进行比较?

    您可以比较TI CCS生成输出文件,例如:MAP文件与您生成的文件。 如果您使用相同的已知工作项目(例如:Blinky),并使用两个不同的工具链来构建它,并比较地图文件,您应该能够看到这些文件,并从相似点和不同点中找到一些东西。

    [报价用户="Preetham Kashyap"]

    1.我在项目中使用的.lds链接器文件与TI链接器工具使用的.cmd文件非常相似。 我还验证了闪存入口点应位于地址0x20.3万 (根据设备TRM)。 但是,我仍然不能在没有调试器的情况下作为独立运行此应用程序。  

    也许您可以在您的端运行我附加的项目并亲自验证。  

    [/引述]

    根据设备TRM部分6.5 7,闪存入口点为0x20.003万。 请验证您的链接器。 您还需要确认是否已将引导模式引脚设置为引导至闪存。

    [报价用户="Preetham Kashyap"]

    关于Systick,我看到Systick外设得到了完美的初始化,我可以这样说是因为我可以在调试时验证Systick计数寄存器值是否确实减少了每个时钟周期。 但当该值达到零时,将不会触发中断。  

    我想您可以使用我的项目自行验证。  

    [/引述]

    您是否能够查看我在上一篇文章中提到的TI示例代码? 或者,您是否有任何其他关于中断的工作示例?

    我建议您查看设备TRM和示例代码,并放置一个流程图,说明系统需要如何初始化。 在TRM和示例之间,我们提供了足够的信息供用户执行此操作。 完成此操作对于继续您的项目非常重要。

    很遗憾,我们无法运行您的项目来为您验证此情况。  在我们尝试指导和帮助论坛上的用户的同时,我们还致力于更新下一代MCU的宣传材料和发布宣传材料。  

    此致
    Santosh Athuru

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

    Santosh,

    现在我的中断工作正常,但我仍然无法让应用程序在独立模式下工作。  

    这意味着当我关闭并重新打开主板时,应用程序不会执行。  

    我已经验证了我的闪存入口点确实在0x20.003万,并且评估板上的引导模式引脚也设置为M3从闪存模式引导。  

    除此之外,我还修改了链接程序脚本,例如ram start,ram size和ram run变量会得到相应的值。  下面是我的链接器代码:

    /* F28M35H2C的内存映射*/

    output_format ("ELF32-littlearem","ELF32-bigarm","ELF32-littlearem")
    output_arch (ARM)
    条目(Reset_Handler)/*入口点*/


    内存

    /*ROM (Rx):原始= 0x20万,长度= 256k
    RAM (xrw):原点= 0x2000万,长度= 32K /*0x2000*/
    //RESETISR (Rx):源站= 0x20.003万,长度= 0x0008

    CSM_ECSL_Z1:原点= 0x20万,长度= 0x0024
    CSM_RSVD_Z1:原点= 0x20.0024万,长度= 0x000C
    INTVECS (Rx):原点= 0x20.003万,长度= 0x01BC
    FLASHLOAD (Rx):原点= 0x20.12万,长度= 0x2E00
    Flash (Rx):原点= 0x20.4万,长度= 0x7BF00
    CSM_RSVD_Z2:原点= 0x0027FF00,长度= 0x00DC
    CSM_ECSL_Z2:原点= 0x0027FFDC,长度= 0x0024
    C0 (rwx):原点= 0x2000万,长度= 0x4000
    C1 (rwx):原点= 0x2000.2万,长度= 0x2000
    BOOT_RSVD (Rx):原点= 0x2000.4万,长度= 0x0900
    C2 (rwx):原点= 0x2000.49万,长度= 0x1700
    C3 (rwx):原点= 0x2000.6万,长度= 0x2000
    S0 (rwx):原点= 0x2000.8万,长度= 0x2000
    S1 (rwx):原点= 0x2000A000,长度= 0x2000
    S2 (rwx):原点= 0x2000C000,长度= 0x2000
    S3 (rwx):原点= 0x2000E000,长度= 0x2000
    S4 (rwx):原点= 0x2001万,长度= 0x2000
    S5 (rwx):原点= 0x2001.2万,长度= 0x2000
    S6 (rwx):原点= 0x2001.4万,长度= 0x2000
    S7 (rwx):原点= 0x2001.6万,长度= 0x2000
    CTOMRAM (Rx):原点= 0x2007F000,长度= 0x0800
    MTOCRAM (rwx):原点= 0x2007F800,长度= 0x0800
    }

    /*应用程序使用的堆栈大小。 注:您需要调整*/
    stack_size = 1024;

    /*应用程序使用的堆大小。 注:您需要调整*/
    heap_size = 256;

    部分{

    .ISR_Vector:{/*矢量表首先进入ROM */
    Keep (*(.ISR_Vector))/*矢量表*/
    。 =对齐(4);
    }> INTVECS

    .text:{/*代码和常量*/
    。 =对齐(4);
    *(.text)/*.text部分(代码)*/
    *(.text*)/*.text*节(代码)*/
    *(.rodata)/*.rodata节(常量,字符串等) */
    *(.rodata*)/*.rodata*部分(常量,字符串等) */

    保留(*(.init))
    保留(*(.fini))

    。 =对齐(4);
    }>闪烁

    .preinit_array :{
    provide_hidden (__preinit_array_start =.);
    保留(*(.preinit_array*)
    provide_hidden (__preinit_array_end =.);
    }>闪烁

    init_array :{
    provide_hidden (__init_array_start =.);
    保留(*(sort(.init_array.*))
    保留(*(.init_array*)
    provide_hidden (__init_array_end =.);
    }>闪烁

    .fini数组:{
    provide_hidden (__fini_array_start =.);
    保留(*(.fini_array*)
    保留(*(sort(.fini_array.*))
    provide_hidden (__fini_array_end =.);
    }>闪烁

    .flashload:{
    。 =对齐(4);
    }>FLASHLOAD

    RamfuncsLoadStart = LOADADAM(.flashload);
    RamfuncsLoadSize = SIZEOF(.flashload);

    _etext =.;/*代码结尾的全局符号*/

    .vtable:{
    。 =对齐(4);
    }>C1.

    堆栈:{
    __stack_start__=.;
    。 =。 + stack_size;
    。 =对齐(4);
    __stack_end__=.;
    }>C1.

    数据:位于(_etext){
    __data_load = LOADADADADDDR (.data);
    __data_start =.;
    *(.data)/*.data节*/
    *(.data*)/*.data*节*/
    。 =对齐(4);
    __data_end__=.;
    _edata =__data_end__;
    }>C1.

    bss:{
    __bss_start__=.;
    *(.BSS)
    *(.BSS*)
    *(普通)
    。 =对齐(4);
    _ebss =.;/*在BSS结束处定义全局符号*/
    __bss_end__=.;
    }>C1.

    提供( end =_ebss );
    提供(_end =_ebss);
    提供(__end__=_ebss );

    堆:{
    __heap_start__=.;
    。 =。 +堆大小;
    。 =对齐(4);
    __heap_end__=.;
    }>C1.

    /*ramfuncs:LOADADADDR(FLASHLOAD),
    Run = C0,
    load_start( RamfuncsLoadStart ),
    load_size( RamfuncsLoadSize ),
    run_start( RamfuncsRunStart ),
    页面= 0*/

    .ramfuncs:{
    。 =对齐(4);
    }> C0
    RamfuncsRunStart = LOADADADDR(.ramfuncs);

    .flashinitram:{
    。 =。 +1;
    。 =对齐(4);
    }> C0

    PUTBUFFER:{

    }>MTOCRAM

    PUTWRITEIDX:{

    }>MTOCRAM

    GETREADIDX:{

    }>MTOCRAM

    GETBUFFER:{

    }> CTOMRAM

    GETWRITEIDX:{

    }> CTOMRAM

    PUTREADIDX:{

    }> CTOMRAM

    /*从标准库中删除信息*/
    /discard/:{
    libc.a (*)
    libm.a (*)
    libgcc.a (*)
    }
    }

    在我的主文件中,我还有:

    /*将Time Critical Flash设置代码复制到RAM - InitFlash()。 。
    * RamfuncsLoadStart,RamfuncsLoadSize和RamfuncsRunStart符号是
    *由链接程序创建。 */

    memcpy(&RamfuncsRunStart,&RamfuncsLoadStart,( size_t )&RamfuncsLoadSize );

    请您向我提供一些提示,说明我还应该在哪里寻找解决此问题的方法。

    期待您的回复。

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

    独立启动时的最佳规则是记住,程序在RAM中没有加载/初始化任何内容,因此无法正常运行。 RAM中任何初始化的数据都必须来自闪存,运行时C库将在程序到达main()之前处理此问题。 检查映射文件中是否有正在加载到RAM中的所有部分,并查看是否存在程序运行的初始化位置,如果是,则需要将它们移动到.cinit部分。 与RAMFUNCs部分类似,主代码执行memcpy (用于需要从RAM运行的任何函数),也将为初始化的数据提供一个副本。

    这里需要注意的一点是,我提到了基于我使用TI工具的经验的.cinit部分,但是如果您使用不同的工具链和不同的C支持库,则这些部分和例程可能会有所不同。

    使用CCS,在Concerto上调试这种方法更容易。以下是步骤。

    1.>在闪存中加载应用程序,但不要运行。 程序控制将在入口点或main()处停止。
    2.>现在打开拆卸窗口至闪存入口点位置并设置硬断开点。
    3.>现在执行调试器重置,这将重置MCU,程序控制将位于ROM中的重置入口点
    4.>现在确保将引导模式引脚设置为引导至闪存
    5>。 运行时,将运行ROM代码,该代码将解码引导模式引脚并引导至闪存,程序控制应达到Entrypoint。
    6.>现在,如果程序控件到达闪存入口点,但它没有到达main(),那么您会遇到CINIT部分的问题,其中并非所有常量都链接到闪存。
    7.>如果它到达main,则您可以逐步执行并调试问题所在的位置。
    8>但是,如果在步骤5结束时,程序控件未到达闪存入口点,则需要重新检查引导模式针脚。 发生这种情况的可能性很小。

    希望这有所帮助。

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

    另外请记住,应用程序[EDIT:] 不应 使用为执行引导ROM而保留的RAM,这在TRM中有说明,也显示在TI示例附带的TI链接器命令文件中。 如果用户选择重新使用引导ROM保留的RAM,则必须注意这些位置中没有任何初始化应用程序启动所需的数据。


    此致
    Santosh Athuru

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

    您好,Santosh:

    经过将近一周的研究,我仍然无法确定我如何缺少RAM部分的初始化。 我的项目具有所有必要的功能,可以将已初始化的部分从闪存复制到RAM。  

    作为一个运行时库,我使用的是libc.a. 这应该是正常的吗?  

    在我的复位矢量中,我将所有闪存数据复制到RAM,并将.bss部分填充为零。 以下是我的重置引导程序代码供您参考。

    作废Reset_Handler(void)

    extern int main(void);
    extern int __libc_init_array(void);
    外部unsigned __data_start;/*链接程序脚本中.data的起始位置*/
    外部未签名__data_end__;/*链接程序脚本中.data的结尾*/
    extern unsigned const __data_load;/*.data */的初始化值
    外部未签名__bss_start__;/*链接程序脚本中.bss的起始位置*/
    链接程序脚本中的extern unsigned __bss_end__;/*.bss结尾*/
    extern void software_init_hook(void)__attribute__((week));

    unsigned const *src;
    无符号*DST;

    //SystemInit();/* CMSIS系统初始化*/

    /*将数据段初始化程序从闪存复制到RAM... */
    src =&__data_load;
    对于(dst =&__data_start;dst <&__data_end__;+dst,+src){
    *dst =*src;
    }

    /*零填充RAM中的.BSS段... */
    对于(DST =&__bss_start__;DST <&__bss_end__;+DST){
    *DST = 0;
    }

    是否提供了/* init hook? */
    如果(&software_init_hook !=(void (*)(void))(0)){
    /*将控制权交给RTOS */
    software_init_hook();/*这也将调用__libc_init_array */
    }
    否则{
    /*调用C++中的所有静态构造函数(在C程序中无害)*/
    __libc_init_array();
    (void)main();/*应用程序的入口点;不应返回! */
    }

    /*以前的代码不应返回,而是在...的情况下断言... */
    断言失败("Reset_Handler",__LINE__);
    }

    我还检查了我的映射文件,并初始化了RAM的所有必要部分,程序才能正常工作。  

    现在我不能理解的是.cint部分以及如何在GNU链接器脚本上执行此操作。 请你在这方面作进一步的说明。   

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是的,我知道这一点,并且我注意到用于引导ROM的RAM不在我的应用程序中使用。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Preetham,
    在您的入口点代码Reset_Handler()中,最后您直接调用main()-您可以参考您的工具链文档或其他示例,如果这必须是一个_start或类似的,而这又是一个main()?

    例如,以下页面建议将其作为_开始?
    github.com/.../arm-none-eabi-gcc-4_6

    另一种了解方法是,如果不将入口点定义为Reset_Handler,则查看工具链将什么作为默认入口点? 您可能应该在Reset_Handler中调用该入口点?

    如果链接都经过验证,则可能是您没有调用正确的运行时库init例程。

    下次是否还可以附加地图文件?


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

    您好,Santosh:

    首先,我研究了__start()函数,我已经在Reset_Handler()中执行了所有的基本功能,这些功能在__start()中完成。

    我唯一不做的是调用SystemInit()函数。 这将处理控制器特定的初始化(如设置时钟源等),在我的情况下,我在main的开头执行此操作,就像在使用TI工具编译的示例中执行此操作一样。   

    [QUETE USER="Santosh Athuru ]另一种方法是,如果您不将入口点定义为Reset_Handler,则查看工具链将什么作为默认入口点? 您可能应该在Reset_Handler中调用该入口点?
    [/QUOT]我如何尝试?  

    如果链接已全部验证, 然后,您可能没有调用正确的运行时库初始化例程。[/QUETE]正如我前面提到的那样,我从使用GNU工具为STM32控制器开发的不同项目中看到了__START()函数,我只是在Reset_Handler()函数中执行同样的操作!!  

    Santosh Athuru 说:
    下次是否还可以附加地图文件?[/QUOT]附加地图文件。

    e2e.ti.com/.../Test.map.7z

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

    Preetham,

    感谢您提供地图文件:

    我看到您正在0x20.003万处加载长度为0x1B0的ISR_Vector部分。 这不正确。 在0x20.003万位置,您需要有一个分支到应用程序入口点的小例程。如下所示。 引导ROM在引导结束时分支为0x20.003万,然后调用Reset_Handler。 将ISR_Vector分配给链接程序命令文件中的其它闪存位置。

    无效

    ResetISR (无效)

    //跳至CCS C初始化例程。
    __ASM(".global _Reset_Handler\n"\}
                  " b.w _Reset_Handler");
    }

    也许上述修复可以解决您的问题。  

    感谢您验证__Start并将其与您的重置处理程序匹配。 _mainCRTStartup函数如何? 我看到此函数在您的工具中可用(基于地图文件),我已阅读到需要也调用此函数的某处? 只需检查此函数与您在入口点函数(重置处理程序)中的操作有何不同,在分支到main()之前,此函数是否执行了任何不同或额外的操作。

    [报价用户="Preetham Kashyap"]

    我唯一不做的是调用SystemInit()函数。 这将处理控制器特定的初始化(如设置时钟源等),在我的情况下,我在main的开头执行此操作,就像在使用TI工具编译的示例中执行此操作一样。   

    Santosh Athuru
    另一种了解方法是,如果不将入口点定义为Reset_Handler,则查看工具链将什么作为默认入口点? 您可能应该在Reset_Handler中调用该入口点?
    Santosh Athuru
    如果链接都经过验证,则可能是您没有调用正确的运行时库init例程。
    就像我前面提到的那样,我看到了使用GNU工具为STM32控制器开发的不同项目中的__start()函数,我只是在Reset_Handler()函数内做同样的事情!

    请查看以下地图文件中的更多说明:-

    为什么ramfuncs低于长度0x0的部分? 您是否没有将从RAM运行的代码? 如果在代码编辑器工作室中使用编译blinky M3示例,我至少得到0xbc长度的RAM函数。  

    .ramfuncs   0x2000万    0x0

    *(.ramfuncs)

            0x2000万         。 =对齐(0x4)

            0x2000万         RamfuncsRunStart = LOADADDR (.ramfuncs)

    此外,TI运行时库_cinit例程将.vtable从闪存复制到RAM。 在映射文件上显示的情况下,闪存中的矢量表加载到.ISR_Vector部分,需要通过启动代码将此部分中的数据移动到.table,或者必须初始化RAM中的vtable并相应地指定vtable偏移寄存器。

    此外,这些节.preinit_array和.init_array似乎与启动代码有一定的依赖性,请检查_mainCRTStartup函数。

    此致

    Santosh Athuru

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

    您好,Santosh:

    [报价用户="Santosh Athuru"]

    我看到您正在0x20.003万处加载长度为0x1B0的ISR_Vector部分。 这不正确。 在0x20.003万位置,您需要有一个分支到应用程序入口点的小例程。如下所示。 引导ROM在引导结束时分支为0x20.003万,然后调用Reset_Handler。 将ISR_Vector分配给链接程序命令文件中的其它闪存位置。

    无效

    ResetISR (无效)

    //跳至CCS C初始化例程。
    __ASM(".global _Reset_Handler\n"\}
                  " b.w _Reset_Handler");
    }

    也许上述修复可以解决您的问题。  

    [/引述]首先,我不明白为什么我目前的做法是错误的。 是否是因为Reset_Handler不在0x2.003万内?  

    第二,我尝试了你上面建议的方式,结果没有改善情况。 下面是我所做的:

    __attribute__((section(".esertisr"))  /*,其中它位于0x2.003万*/中
    void __reset__(void)

    __ASM(".global Reset_Handler\n"\}
          " b.w Reset_Handler");
    }

    我现在可以在调试时验证,当我选择在__reset__处开始调试分离时,它在此处停止,在反汇编视图中,我看到它在0x2.003万处。 它从这里分支到Reset_Handler,然后到main()。  

    但是我仍然无法使它在独立模式下运行。  

    附加修订的地图文件以供参考。  

     

    感谢您验证__Start并将其与您的重置处理程序匹配。 _mainCRTStartup函数如何? 我看到此函数在您的工具中可用(基于地图文件),我已阅读到需要也调用此函数的某处? 只需检查此函数与您在入口点函数(重置处理程序)中的操作有何不同,在分支到main()
    之前,此函数是否执行了任何不同或额外的操作。此特定函数来自预编译的GNU ARM工具链库(crt0.o)。 看起来同一个文件也有_start函数,也可以从地图文件中看到。 但我会尝试调查该职能的实际内容,如果有重要内容,我会尝试将其包括在内。  

    是的,控制器特定的初始化可以在main()中处理。 由于您将_start视为使用您的工具链构建的另一个项目的入口点,我强烈怀疑在0x20.003万处没有上述入口点功能是问题的原因。 但我仍想了解_mainCRTStartup 函数的用法。

    仍然没有看到上述任何改进,将尝试了解更多有关_mainCRTStartup函数的信息。  

    [报价用户="Santosh Athuru"]

    为什么ramfuncs低于长度0x0的部分? 您是否没有将从RAM运行的代码? 如果在代码编辑器工作室中使用编译blinky M3示例,我至少得到0xbc长度的RAM函数。  

    .ramfuncs   0x2000万    0x0

    *(.ramfuncs)

            0x2000万         。 =对齐(0x4)

            0x2000万         RamfuncsRunStart = LOADADDR (.ramfuncs)

    [/QUOT]此处,而不是.ramfuncs,我使用 .flashload部分来存储FlashInit和FlashSetup函数。 关于从RAM运行代码,我是在主要的. c文件中引用FlashInit函数,但请告诉我使用FlashSetup函数是否也有一些好处。  

    .vtable也由TI运行时库_cinit例程从闪存复制到RAM。 在地图文件上显示的情况下,闪存中的矢量表加载到.ISR_Vector部分, 本节中的数据需要通过启动代码移至.table,否则您必须初始化RAM中的vtable并相应地分配vtable偏移寄存器。[/QUOT]在这种情况下,我只尝试使用Systick ARM特定中断, 我只需注册这个特定的中断例程,如下所示

    IntRegister (FAULT_Systick,Systick_Handler);

    我看到IntRegister函数内的向量从闪存ISR_TABLE复制到RAM向量表,并根据需要初始化处理程序。 如果我的理解有误,请更正我。  

    您还能告诉我将整个矢量表从闪存复制到RAM有什么好处吗? 也许这是我可能错过的地方!!  

    Santosh Athuru 说:
    另外,这些部分.preinit_array和.init_array似乎与启动代码有一定的相关性,请检查_mainCRTStartup函数。

    我完全忽略了这一点,因为我不需要它。 或者,您是否认为它是一个重要的缺失部分?  

    e2e.ti.com/.../1643.Test.map.7z

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

    Preetham,

    您提到的由int_register函数从闪存复制到ram的ISR_TABLE是正确的。 该函数检查,复制并正确初始化NVIC_table偏移。 只需在调用int_register函数后检查0x2000_2000 RAM2000 RAM位置,查看矢量表是否正确加载。

    请继续对_mainCRTStartup函数进行调查,看看是否有任何代码需要处理Reset_handler,或者如果您从新的__reset__函数分支到_Start或_mainCRTStartup,而不分支到Reset_Handler,会发生什么情况? 它是否到达main()?

    您之前的操作方式是错误的,因为引导ROM在引导至闪存时处于引导结束位置,分支到0x0020_0030位置0030位置,我们希望此处有一个有效的指令,如BRANCH到RESET_handler。 如果您直接将引导程序表放在此处,则它们不是有效的指令,而是引导程序,因此设备不会启动应用程序。

    让我们集中关注下面的内容,  

    现在,我可以在调试时验证,当我选择在__reset__处开始调试分离时,它会在此处停止,在反汇编视图中,我看到它位于0x2.003万。 它从这里分支到Reset_Handler,然后到main()。  [/引述]

    由于您现在可以在0x0020_0030位置0030位置看到正确的分支指令,并且连接了调试器,您可以访问main(),我希望您在下面执行操作。 我列出了假设您正在使用CCS的步骤,但如果您正在使用其他步骤,请将这些步骤映射到IDE。

    A1.>在0x0020_0030位置0030位置放置一个断点。 如果您使用CCS,则应该能够从拆卸窗口中放置断开点。

    A2.>通过调试器重置CPU (不是重新启动,而是重置)-这应将程序控制置于设备引导ROM重置处理程序中。 不要担心来源不可用,您应该在拆卸窗口中看到一些说明。

    A3.>引导模式GPIO应设置为引导至闪存。

    A4.>点击RUN,这应该运行设备引导ROM重置处理程序中的代码。

    A5.>现在,0x0020_0030处0030处的断点应该会命中,CPU应该会停止。 如果它点击了,那么即使是在独立运行的情况下,您也可以确保程序控制已达到闪存入口点。

    A6.>现在在main()处放置一个中断点

    A7.>从[EDIT:]重新运行,如果它在步骤A5停止,您是否到达main()

    A8.>如果您到达main,则继续调试并查看故障的位置。

    如果您没有看到任何故障,但设备似乎仍然无法独立运行应用程序,请尝试以下步骤。

    S1>程序将随应用程序一起闪存。

    S2.>关闭主板电源并开机

    S3.>连接调试器

    S4.>加载应用程序的符号,不要再次加载完整的应用程序。

    S5.>从上面的步骤A1到A8继续,让我知道您看到的内容。

    此致
    Santosh Athuru

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

    您提到的由int_register函数从闪存复制到ram的ISR_table是正确的。 该函数检查,复制并正确初始化NVIC_table偏移。 只需在调用int_register函数后检查0x2000_2000 RAM2000 RAM位置,查看矢量表是否正确加载。

    是的,我在运行应用程序时在反汇编中选中了此项,汇编指令与ROM ISR_Vector部分中的相同。 因此,我相信矢量地址会被重新映射。

    按照您的调试说明操作后,下面是我的观察结果和观察结果的屏幕截图。  

    A1.>在0x0020_0030位置0030位置放置一个断点。 如果您使用CCS,您应该能够将中断点从拆卸窗口中放置。[/QUOT]下面是我在拆卸窗口中看到的在闪烁前和闪烁过程中的内容。 请注意,连接到主板时没有装配说明。 这是否意味着我没有读取任何启动ROM代码?  

      

    现在,在通过调试器运行应用程序之前,我在这里停下来,并按照您的指示在0x20.003万上放置一个中断点。  

    A2.>通过调试器重置CPU (不重新启动,而是重置)-这应将程序控制置于设备引导ROM重置处理程序。 不要担心源代码不可用,您应该在拆卸窗口中看到一些说明。

    这是一个有趣的地方,现在我开始在拆卸窗口中看到了位于0x100.1692万地址的组装代码!!  

    A3.>启动模式GPIO应设置为启动至闪存。[/QUOT]始终处于启动至闪存选项中。

    [报价用户="Santosh Athuru"]

    A4.>点击RUN,这应该运行设备引导ROM重置处理程序中的代码。

    A5.>现在,0x0020_0030处0030处的断点应该会命中,CPU应该会停止。 如果它点击了,那么即使是在独立运行的情况下,您也可以确保程序控制已达到闪存入口点。

    [/QUOT]这种情况永远不会发生,这意味着执行不会停止或遇到0x20.003万中的断点!!! 我猜它只是在未知的启动ROM世界中继续运行。  

    [报价用户="Santosh Athuru"]

    A6.>现在在main()处放置一个中断点

    A7.>从[EDIT:]重新运行,如果它在步骤A5停止,您是否到达main()

    A8.>如果您到达main,则继续调试并查看故障的位置。

    [/报价]就像我上面说的那样,即使是启动到闪存代码也永远不会出现!!!

    [报价用户="Santosh Athuru"]

    如果您没有看到任何故障,但设备似乎仍然无法独立运行应用程序,请尝试以下步骤。

    S1>程序将随应用程序一起闪存。

    S2.>关闭主板电源并开机

    S3.>连接调试器

    S4.>加载应用程序的符号,不要再次加载完整的应用程序。

    S5.>从上面的步骤A1到A8继续,让我知道您看到的内容。

    [/QUOT]也尝试了此操作,结果与上述相同。 这意味着当我尝试加载符号时,它现在在0x100.1692万时停止,并表示没有要加载的符号。 但正如以前所看到的,我开始在反汇编视图中看到一些汇编代码,当我运行它时,它从不运行应用程序,而只是在引导ROM代码中运行。  

    希望这能为您提供一些线索,让您知道我最后可能会出现什么问题。期待您的更新。  

    谢谢

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

    Preetham,

    好的,感谢他们提供的快照。 让我们集中讨论步骤A1-A8。 我们需要使CPU在闪存入口点0x20.003万处停止。

    我从下面的快照中看不到0x0020_0030位置0030位置的有效断点。 尝试右键单击0x0020_0030位置0030位置并设置HW断点。 您可以查看"断点"选项卡(在"注册"选项卡旁边,在"反汇编"窗口上方,查看是否存在有效的断点)。

    是否可以重试并按照以下步骤操作? 下次您发送以下快照时,是否可以显示"中断点"选项卡?

    还要尝试确定引导模式选择引脚的范围并确保它们高? 请告诉我它们是否高并且断点设置正确,执行CPU重置(芯片按钮)和运行(播放按钮)后,在0x0020_0030位置0030位置的断点处没有看到CPU停止。

    [报价用户="Preetham Kashyap"]

    现在,在通过调试器运行应用程序之前,我在这里停下来,并按照您的指示在0x20.003万上放置一个中断点。  

    [/引述]Preetham,

    [再次参考以下步骤]  

    A1.>在0x0020_0030位置0030位置放置一个断点。 如果您使用CCS,则应该能够从拆卸窗口中放置断开点。

    A2.>通过调试器重置CPU (不是重新启动,而是重置)-这应将程序控制置于设备引导ROM重置处理程序中。 不要担心来源不可用,您应该在拆卸窗口中看到一些说明。

    A3.>引导模式GPIO应设置为引导至闪存。

    A4.>点击RUN,这应该运行设备引导ROM重置处理程序中的代码。

    A5.>现在,0x0020_0030处0030处的断点应该会命中,CPU应该会停止。 如果它点击了,那么即使是在独立运行的情况下,您也可以确保程序控制已达到闪存入口点。

    A6.>现在在main()处放置一个中断点

    A7.>从[EDIT:]重新运行,如果它在步骤A5停止,您是否到达main()

    A8.>如果您到达main,则继续调试并查看故障的位置。

    此致

    Santosh Athuru

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

    您好,Santosh:

    很抱歉耽误您的时间,下面是我修改的快照和执行的相应步骤:

    1.单击Run (运行)-> Connect Target (连接目标)以连接目标

     

    2.现在,我通过单击“运行”->“加载”->“加载程序”来加载.out文件

    3.加载图像后,我到达__reset__(如果在__reset__处提到sto),我在函数堆栈部分看到一些有趣的东西。

      从地址0x2000.4118万跳转至地址0x20.003万,其中没有定义符号。

     

    4.现在,在单击“恢复”按钮之前,我在“反汇编”窗口中的地址0x20.003万上放置了一个断点,并单击了“CPU重置”按钮。

    5.单击CPU重置按钮后,这就是我停止的地方

    6.现在,如果我单击“恢复”!!! 它从未在0x20.003万地址停止??

    希望这些快照比以前共享的快照更清晰。 请告诉我您的想法。

    谢谢  

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

    Preetham,

    [报价用户="Preetham Kashyap"]

    3.加载图像后,我到达__reset__(如果在__reset__处提到sto),我在函数堆栈部分看到一些有趣的东西。

      从地址0x2000.4118万跳转至地址0x20.003万,其中没有定义符号。

    [/引述]

    是的,我还不确定为什么调用栈在此处显示0x2000.4118万。 让我们忽略这一点,直到我们找到实际问题。一旦确定引导至闪存入口点,我们将返回此问题。

    第5步,我觉得没问题。

    [报价用户="Preetham Kashyap"]

    如果我单击“继续”,现在就可以了!!! 它从未在0x20.003万地址停止??

    [/引述]

    您能否澄清在步骤6中单击播放按钮(暂停按钮左侧的按钮)?

    在步骤6中,如果暂停MCU,您会看到PC位于何处? 您是否监控示波器上的XRSn引脚以查看其是否正在切换?

    在步骤6中,由于它没有到达闪存入口点的中断点,您能否暂停MCU并告诉我您在0x2000.4万位置看到的值? 按照TRM.MCU的章节6.5 .5.3 ,有一个M-Boot ROM引导状态,我们可以监视它,以查看当您在重置后运行时,引导ROM中的内容。

    此致
    Santosh Athuru

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Preetham,
    如果您有任何更新,请告诉我,只是跟进。

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

    您好,Santosh:

    很抱歉耽误了时间,我本周要承担一项不同的任务。  我一定会在周一回来了解最新情况。

    谢谢

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

    您好,Santosh:

    以下是我对启动ROM状态值的观察:

    [QUETE USER="Santosh Athuru"]您能否澄清在第6步中单击"播放"按钮(暂停按钮左侧的按钮)?[/QUET]

    第一个映像正在从调试器运行应用程序,我在0x2000.4万处看不到任何值???

    这种情况下,系统在从中断点为0x20.003万的调试器运行它之前重置。 这是为了回答您的问题“天气或不天气”,我按“恢复”按钮。

    这是当我按下暂停按钮时停止的地方。  

    在步骤6中,由于它没有到达闪存入口点的中断点,您是否可以暂停MCU并告诉我您在0x2000.4万位置看到的值? 根据TRM.MCU的章节6.5 ,我们可以监控M-Boot 5.3 启动状态,以查看在重置后运行时启动ROM中的内容。

    在步骤6中,如果您暂停MCU,您会在哪里看到PC? 您是否监控示波器上的XRSn引脚以查看其是否正在切换?[/QUOT]

    我没有检查XRSn引脚上的真实信号值!!! 但是评估板上的DIP开关都处于向上位置,我也可以在独立模式下运行TI控制套件示例。 但我会尽快尝试给大家一些示波器屏幕截图。   

    希望这些屏幕截图能帮上忙。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Preetham,
    从上面的快照中,引导状态0x0.0107万表示设备已启动并行引导,并且当所有引导模式选择引脚都被拉低时会发生这种情况。 将引导模式选择引脚反转至高,设备应在0x0020_0030处0030处(闪存入口点)达到断开点。

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

    我的天啊……这是所有这些天的问题!!!

    它现在可以工作了……非常感谢您的帮助和耐心。 非常感谢。

    但我现在很好奇,使用TI编译器编译的控制套件应用如何在启动引脚拉低的情况下独立工作??

    谢谢
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Preetham,
    感谢您的确认,我相信您的调试过程经历了非常丰富和有用的阶段,您并不只是从这个问题开始。 这是一个很好的进展。

    controlSUITE示例或非controlSUITE示例的行为应相同。 除非引导模式选择引脚默认为闪存引导选项,否则设备将不会引导至闪存。 检查主板并监控示波器上的启动模式引脚选择值,并将其与设备TRM启动模式表进行比较,如果它们启动到闪存,您应该会看到原因。

    现在,请告诉我我们是否可以关闭此帖子。 我看到您在另一个论坛帖子中有一个新的设计问题,我们可以继续讨论。 但是,如果您仍需要处理启动和启动代码,请随时继续。

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

    您好,Santosh:

    controlSUITE 示例或非controlSUITE示例的行为应相同。 除非引导模式选择引脚默认为闪存引导选项,否则设备将不会引导至闪存。 检查主板并监控示波器上的启动模式引脚选择值,并将其与设备TRM启动模式表进行比较,如果它们启动到闪存,您应该会看到原因。
    [/QUOT]我认为我必须清楚地说明我从Concerto研讨会文档中读到的关于不同引导选项的信息。 所以我会这样做,并且可能会附加一个范围,让自己更熟悉这个选项。  

    现在,请告诉我我们是否可以关闭此帖子。 我看到您在另一个论坛帖子中有一个新的设计问题,我们可以继续讨论。 但如果您仍需要处理启动和启动代码,请随时继续。[/QUOT]我想我们可以关闭此帖子,当我在这方面取得一些进展时,如果这是一个好方法,我可能会创建一个新的线程。 如果不是,我们可以打开此帖子。 但我想您可以决定是否可以做出决定。  

    谢谢

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Preetham,
    谢谢。 我们关闭此帖子,如果您需要进一步的发展帮助,请打开另一个帖子。

    此致
    Santosh Athuru