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/TMS320F28379D:在闪存中加载代码时遇到一些问题

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/589868/ccs-tms320f28379d-i-get-some-problems-when-i-load-my-code-in-flash

器件型号:TMS320F28379D
Thread 中讨论的其他器件:CCStudio

工具/软件:Code Composer Studio

你(们)好。 

我刚刚使用一个简单代码解决了一些问题、其中我使用加载在 RAM 中的 CPU1和 CLA1以及2837xD_RAM_CLA_lnk_CPU1.cmd 文件、但进行了一些更改。 主要更改包括:

(笑声)

RAMGS0 -> PAGE =1在 PAGE = 0中
(笑声)
.text:>> RAMD0|RAMD1|RAMGS0,page = 0
(笑声)
Cla1Prog:> RAMLS4_LS5,page=0
(笑声)

然后

MemCfgRegs.LSxMSEL.bit.MSEL_LS4 = 1;
MemCfgRegs.LSxMSEL.bit.MSEL_LS5 = 1;
MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS4 = 1;
MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS5 = 1;

以分配正确的 CLA RAM 所有权。

现在、当我将其加载到闪存中时、我遇到了功能问题! 我获取 ILLEGAL_ISR()暂停。 我查看了一些线程,发现问题出在 InitFlash()和 delay_US()函数上:它们必须从闪存加载到 RAM。

我在使用2837xD_FLASH_CLA_lnk_CPU1.cmd 链接器文件时、如果我在命令文件预处理链接器选项中设置_FLASH 参数就足够了。 此外,在 InitFlash()上面有以下代码段:

#ifdef __cplusplus                                  ??? 我创建了 C 源文件
#ifdef __TI_Compiler_version__
#if __TI_Compiler_version__>=15009000       ??? 我使用 CGT 6.4.2、那么 ramfuncs 部分是否正常?
#pragma CODE_SECTION (".TI.ramfunc");
其他
#pragma CODE_SECTION ("ramfuncs");
#endif
#endif
#endif

我将 CCStudio 7与 6004002的__TI_Compiler_version__符号值一起使用(CGT 6.4.2 ->使用 TI v16.9.1.LTS 时,我遇到了很多编译问题)。 因此,有人向我解释如何在闪存中加载代码以避免 ILLEGAL_ISR()。 我想了解在监听汇编器代码和 CPU 寄存器时如何找到此错误的来源。

非常感谢您的帮助。

迭戈。

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

    迭戈、

    关于 ILLEGAL_ISR(): 您需要在应用程序中使用 memcpy()将 ramfuncs 段的内容从闪存复制到 RAM,然后应用程序才能从 RAM 执行这些函数。  否则、CPU 将从 RAM 中提取垃圾、并以 ILLEGAL_ISR()结束。

    例如、在 F2837xS_SYSCTRL.c 中从 void InitSysCtrl (void)函数复制的代码片段下面 使用 memcpy ()函数。  您是否使用了此函数?    

    #ifdef _flash

    //
    //将时间关键代码和闪存设置代码复制到 RAM。 这包括
    //以下函数:InitFlash()
    //
    // RamfuncsLoadStart、RamfuncsLoadSize 和 RamfuncsRunStart
    //符号由链接器创建。 请参阅器件.cmd 文件。
    //
    memcpy (&RamfuncsRunStart、&RamfuncsLoadStart、(size_t)&RamfuncsLoadSize);

    //
    //调用闪存初始化以设置闪存等待状态。 此函数必须执行的操作
    //驻留在 RAM 中。
    //
    InitFlash_BANK0 ();
    #endif

    在调试器中、您可以进入与 ramfuncs 相关的函数、以在反汇编窗口中注意到控制权进入 RAM (因为您在链接器命令文件中分配了一个闪存加载地址和一个 RAM 运行地址)。  如果 RAM 内容无效,从这些位置获取将转至 ILLEGAL_ISR()。

    关于 TI v16.9.1.LTS 的编译错误: 您是否尝试解决它们?  如果您需要任何帮助、请告知我们。

    谢谢、此致、
    Vamsi  

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

    你(们)好,Vamsi。

    非常感谢您的重播。

    我理解这一论点,但我的头脑中还有些雾。 我希望你能澄清。

    在主函数中,我调用的第一个 TI 函数是 InitSysCtrl():

    void main (void)
    {
    int i = 0;
    //
    //步骤1。 初始化系统控制:
    // PLL、看门狗、启用外设时钟
    //此示例函数位于 F2837xD_sysctrl.c 文件中。
    //
    InitSysCtrl();// DB -系统控制寄存器初始化 

    在此函数中、代码为:

    空 InitSysCtrl(void){
    
    //
    //禁用看门狗
    //
    DisableDog ();
    
    #ifdef _flash // DB -由 PRJ C2000编译器选项传递的参数
    //
    //将时间关键代码和闪存设置代码复制到 RAM。 这包括
    //以下函数:InitFlash()
    //
    // RamfuncsLoadStart、RamfuncsLoadSize 和 RamfuncsRunStart
    //符号由链接器创建。 请参阅器件.cmd 文件。
    //
    memcpy (&RamfuncsRunStart、&RamfuncsLoadStart、(size_t)&RamfuncsLoadSize);
    
    //
    //调用闪存初始化以设置闪存等待状态。 此函数必须执行的操作
    //驻留在 RAM 中。
    //
    InitFlash();
    #endif 

    因此、在  链接器参数选项中声明_flash 后、函数 memcpy 应能够将 InitFlash 代码从闪存复制到 RAM。 如果我看一下 InitFlash 文件声明、我会看到:

    #ifdef __cplusplus
    #ifdef __TI_Compiler_version__
    #if __TI_Compiler_version__>=15009000
    #pragma CODE_SECTION (".TI.ramfunc");
    其他
    #pragma CODE_SECTION ("ramfuncs");
    #endif
    #endif
    #endif
    
    void InitFlash (void)
    {
    EALLOW;
    
    //
    //将 VREADST 设置为闪存组加电所需的正确值
    //正确。 这将设置组加电延迟。
    //
    Flash0CtrlRegs.FBAC.bit.VREADST = 0x14; 

    遗憾的是、我看到所有 pragma 指令处于灰色状态、因为未声明__cplusplus。 为什么 TI 会做出这种选择 ?  不应该出现#pragma CODE_SECTION (InitFlash、"ramfuncs");首先、函数定义也适用于 c 源文件?

    此外、我需要像刚才对 RAM 程序版本所做的那样、将 LS4_LS5分配给 Cla1Prog 、因此我以这种方式修改了2837xD_FLASH_CLA_lnk_CPU1.cmd:

    //如果使用
    // CLA C 编译器
    //项目属性-> C2000链接器->高级选项->命令文件
    //预处理->--,用户必须在项目链接器设置中定义 CLA_C define
    #ifdef CLA_C
    //定义
    将由 CLA 编译器用于局部符号和 temps 的 CLA 暂存区的大小
    //还强制引用标记
    了//暂存区的特殊符号。
    CLA_暂 存区_size = 0x100;
    --undef_sym=__cla_scratchpad 结束
    --undef_sym=__cla_scratchpad 开始
    #endif //cla_C
    
    MEMORY
    {
    PAGE 0:
    /* begin 用于"引导至 SARAM"引导加载程序模式*/
    
    begin:origin = 0x080000、length = 0x000002
    RAMM0:origin = 0x000122、length = 0x0002DE
    RAMD0:origin = 0x00B000、length = 0x000800
    RAMGS0 :origin = 0x00C000、length = 0x001000
    RAMGS1 :origin = 0x00D000、length = 0x001000
    // RAMLS4:origin = 0x00A000、length = 0x000800
    // RAMLS5 :origin = 0x00A800,length = 0x000800
    RAMLS4_LS5:origin = 0x00A000、length = 0x001000
    RAMGS14 :origin = 0x01A000、length = 0x001000 /*仅在 F28379D、F28377D、F28375D 器件上可用。 移除其他设备上的线路。 */
    RAMGS15 :origin = 0x01B000、length = 0x001000 /*仅在 F28379D、F28377D、F28375D 器件上可用。 移除其他设备上的线路。 */
    复位:origin = 0x3FFFC0、length = 0x000002
    
    //闪存扇区*/
    FLASHA :origin = 0x080002、length = 0x001FFE//片上闪存*/
    FLASHB :origin = 0x082000、length = 0x002000//片上闪存*/
    FLASHC :origin = 0x084000、length = 0x002000//片上闪存*/
    FLASHD :origin = 0x086000、length = 0x002000//片上闪存*/
    FLASHE :origin = 0x088000、length = 0x008000//片上闪存*/
    FLASHF :origin = 0x090000、length = 0x008000//片上闪存*/
    FLASHG :origin = 0x098000、length = 0x008000//片上闪存*/
    FLASHH :origin = 0x0A0000、length = 0x008000//片上闪存*/
    FLASHI :origin = 0x0A8000、length = 0x008000//片上闪存*/
    FLASHJ :origin = 0x0B0000、length = 0x008000//片上闪存*/
    FLASHK :origin = 0x0B8000、length = 0x002000//片上闪存*/
    FLASHL :origin = 0x0BA000、length = 0x002000//片上闪存*/
    FLASHM :origin = 0x0BC000、length = 0x002000//片上闪存*/
    FLASHN :origin = 0x0BE000、length = 0x002000//片上闪存*/
    
    page 1:
    
    boot_RSVD :origin = 0x000002、length = 0x000120 // M0的一部分,引导 ROM 将此用于栈*/
    RAMM1 :origin = 0x000400、length = 0x000400 /*片上 RAM 块 M1 */
    
    RAMLS0:origin = 0x008000、length = 0x000800
    RAMLS1:origin = 0x008800,length = 0x000800
    RAMLS2:origin = 0x009000、length = 0x000800
    RAMLS3:origin = 0x009800,length = 0x000800
    
    // RAMGS0 :origin = 0x00C000、length = 0x001000
    // RAMGS1 :origin = 0x00D000、length = 0x001000
    RAMGS2 :origin = 0x00E000、length = 0x001000
    RAMGS3 :origin = 0x00F000、length = 0x001000
    RAMGS4 :origin = 0x010000,length = 0x001000
    RAMGS5 :origin = 0x011000,length = 0x001000
    RAMGS6 :origin = 0x012000,length = 0x001000
    RAMGS7 :origin = 0x013000、length = 0x001000
    RAMGS8 :origin = 0x014000、length = 0x001000
    RAMGS9 :origin = 0x015000,length = 0x001000
    RAMGS10 :origin = 0x016000,length = 0x001000
    RAMGS11 :origin = 0x017000、length = 0x001000
    RAMGS12 :origin = 0x018000、length = 0x001000 /*仅在 F28379D、F28377D、F28375D 器件上可用。 移除其他设备上的线路。 */
    RAMGS13 :origin = 0x019000、length = 0x001000 /*仅在 F28379D、F28377D、F28375D 器件上可用。 移除其他设备上的线路。 //
    
    CLA1_MSGRAMLOW:origin = 0x001480,length = 0x000080
    CLA1_MSGRAMHIGH:origin = 0x001500,length = 0x000080
    }
    
    
    SECTIONS
    {
    //分配程序区域:*/
    .cinit :> FLASHB PAGE = 0、ALIGN (4)
    .pinit :> FLASHB、 PAGE = 0、ALIGN (4)
    .text :> FLASHB PAGE = 0、ALIGN (4)
    codestart :>开始 PAGE = 0、ALIGN (4)
    
    /*分配未初始化的数据段:*/
    .stack :> RAMM1 PAGE = 1.ebss
    :> RAMLS2 PAGE = 1
    .esysmem :> RAMLS2 PAGE = 1
    
    /*初始化段进入闪存*/
    .econst :> FLASHB PAGE = 0、ALIGN (4)
    .switch :> FLASHB PAGE = 0、ALIGN (4)
    
    .reset :>重置, PAGE = 0,TYPE = DSECT //未使用,*//
    
    Filter_RegsFile:> RAMGS0,PAGE = 1
    Filter_RegsFile:> RAMGS2,PAGE = 1
    
    /* CLA 特定部分*/
    Cla1Prog :LOAD = FLASHD,
    运行= RAMLS4_LS5、
    load_start (_Cla1funcsLoadStart)、
    load_end (_Cla1funcsLoadEnd)、
    run_start (_Cla1funcsRunStart)、
    load_size (_Cla1funcsLoadSize)、
    PAGE = 0,ALIGN (4)
    
    CLADataLS0:>RAMLS0,PAGE=1
    CLADataLS1:>RAMLS1,PAGE=1
    
    Cla1ToCpuMsgRAM:>CLA1_MSGRAMLOW,PAGE = 1
    CpuToCla1MsgRAM:>CLA1_MSGMHRAIGH,PAGE = 1
    
    #if_0001_TI_VERSION_TI_VERSION_COMPI_#if_TI_VERSION_TI_VERSION_COMPI_#_COMPILDER_#TI_VERSION_000_
    
    .TI.ramfunc:{} load = FLASHD,
    //run = RAMLS4_LS5,
    run = RAMGS1,
    load_start (_RamfuncsLoadStart)、
    load_size (_RamfuncsLoadSize)、
    load_end (_RamfuncsLoadEnd)、
    run_start (_RamfuncsRunStart)、
    run_size (_RamfuncsRunSize)、
    run_end (_RamfuncsRunEnd),
    page = 0,align (4)
    #else
    ramfuncs:load = FLASHD,
    // 运行= RAMLS4_LS5、
    运行= RAMGS1、
    load_start (_RamfuncsLoadStart)、
    load_size (_RamfuncsLoadSize)、
    load_end (_RamfuncsLoadEnd)、
    run_start (_RamfuncsRunStart)、
    run_size (_RamfuncsRunSize)、
    run_end (_RamfuncsRunEnd)、
    PAGE = 0,ALIGN (4)
    #endif
    #endif
    
    //以下段定义适用于 SDFM 示例*//
    *
    Filter1_RegsFile:> RAMGS1,PAGE = 1,fill=0x1111
    Filter2_RegsFile:> RAMGS2,PAGE = 1,fill=0x2222
    Filter3_RegsFile:> RAMGS3,page = 0x3333,page = 1
    > RAMGS4,PAGE = 1,fill=0x4444
    */
    Filter1_RegsFile:> RAMGS3,PAGE = 1,fill=0x1111
    Filter2_RegsFile:> RAMGS4,PAGE = 1,fill=0x2222
    Filter3_RegsFile:> RAMGS5,PAGE = 1,fill=0x3333
    RegsFile: > RAMGS6、PAGE = 1、fill=0x4444
    
    #ifdef CLA_C
    /* CLA C 编译器段*/
    //
    //////必须分配给 CLA 具有写入访问
    权限的存储器。//
    CLAscratch :
    {*。obj (CLAscratch)
    。 += CLA_ScratchPad_size;
    *。obj (CLAscratch_end)}> RAMLS1、page = 1
    
    .scratchpad :> RAMLS1、 PAGE = 1.bss_cla
    :> RAMLS1、 PAGE = 1.CONST_CLA
    :LOAD = FLASHB、
    运行= RAMLS1、
    run_start (_Cla1ConstRunStart)、
    Load_start (_Cla1ConstLoadStart)、
    load_size (_Cla1ConstLoadSize)、
    PAGE = 1
    #endif //cla_C
    } 

    您是否检查它是否正确? 我再次以 ILLEGAL_ISR()结束。

    谢谢、此致、

    迭戈。

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

    迭戈、

    1)关于_FLASH 符号: 能否确认是否在项目的编译器编译设置中定义了_FLASH 符号?  您可以按如下方式进行导航: 右键单击工程->显示编译设置->编译-> C2000编译器->高级选项->预定义符号->预定义名称(在这里、您应该定义_FLASH)。

    2)关于#pragma: 对于 C++、 应在函数定义的正上方提及 pragma 指令。  您是指这些指令。  对于 C 语言、TI 在 F2837xD_SYSCTRL.c 文件顶部声明了 pragma 指令。  请参阅从该文件复制的以下片段。  这就是您的案例所需的内容。  

    #ifndef __cplusplus
      #ifdef __TI_Compiler_version__
        #if __TI_Compiler_version__>=15009000
          #pragma CODE_SECTION (InitFlash、".TI.ramfunc");
          #pragma CODE_SECTION (FlashOff、".TI.ramfunc");
        其他
          #pragma CODE_SECTION (InitFlash、"ramfuncs");
          #pragma CODE_SECTION (FlashOff、"ramfuncs");
        #endif
      #endif
    #endif

    3)关于链接器命令文件的更改: 我没有看到任何明显的问题、但我可以要求我们的 CLA 专家查看以防万一。

    4) 4)您是否通过单步执行代码来确定导致 ILLEGAL_ISR()的函数?

    谢谢、此致、
    Vamsi
     

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

    您好、Vamsi、

    我完全同意您的意见、因为我找到了一个小的权变措施、允许我在闪存上加载 CPU1/CLA1代码。 无论如何、说到、我必须更改 F2837xD_usDelay.asm 中的一条指令、如下所示:

    ;//############################################
    //$TI 发行版:F2837xD 支持库 V210 $
    ;//$发行 日期:星期二11月1日14:46:15 CDT 2016 $
    ;//版权所有:(C) 2013-2016 Texas Instruments Incorporated -
    ;//             http://www.ti.com/ 保留所有权利$
    ;//####################################################################################################
    
    .def _F28x_usDelay
    ; .sect ".TI.ramfunc";;DB @ ORIG
    .sect "ramfuncs";;DB @已添加
    
    .global __F28x_usDelay
    _F28x_usDelay:
    SUB ACC、#1
    Bf _f28x_usDelay、GEQ;如果 ACC >= 0、则环路
    LRETR 

    你告诉我为什么? 不幸的是,我的 CGT 是6.4.2,所以...

    非常感谢您的关注。

    此致。

    迭戈

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

    解决方法正确。 使用较新的编译器(15.9.0和更新版本)、我们过渡到使用".TI.ramfunc"部分来执行 RAM 函数。
    大多数文件都有编译器版本检查、但我可以确认 F2837xD_usDelay.asm 是唯一不检查的文件、因为编译器版本宏不可用于汇编器。 如果确实切换到更新的编译器、请确保将其切换回".TI.ramfunc"。

    我们将更好地记录这一点。

    此致
    Chris