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.

[参考译文] TMS320F2.8035万:MCU在"normal"和"debug"中的运行方式不同

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/580852/tms320f28035-mcu-runs-differently-in-normal-and-debug

部件号:TMS320F2.8035万
主题:controlSUITE中讨论的其他部件

您好,

我的原型上有一个非常奇怪的问题。 在所有其他条件相同的情况下,MCU在正常通电或程序重新加载后(不执行电源循环)不会以相同的方式"操作"。 不幸的是,当MCU未连接到仿真器时,异常行为就会出现,这意味着当程序不能正常运行时(在调试模式下,它确实按预期运行),我看不到程序正在发生什么。

当我重新加载程序并运行它(使用调试器),然后拔下调试器时,一切都正常。 几个继电器(即GPIO)按预期切换,当我在功率转换器的输入上添加一点电压时,PWM脉冲按预期发生。

当我打开电路板时,继电器按预期切换,但奇怪的是,将转换器输入上的电压相加不会触发PWM脉冲。 程序至少部分正常运行,因为我检查的两个GPIO完全按照预期运行,我也可以在XCLOCKOUT引脚上看到一些时钟...但没有PWM。  

是否有人知道在“调试”模式和“正常”模式下会有什么不同,从而导致程序无法正常运行?  

提前感谢!

Adrien

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

    Adrien,

    RAM中是否有任何已初始化的常量? 如果是这样,则 只有在连接仿真器并加载程序时才会加载它们(但不会在“冷”加电时)。 如果是这种情况,请检查您的.map文件吗?

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

    希望与同事分享此说明:

     

    这是指.const节,它不是由.cinit初始化的。  它应链接到非易失性存储器。  如果使用RAM并链接到RAM,则.const仅在仿真器加载时初始化。 示例如下:

     

    const int x=5;   // x置于.econst中。  无法在C代码中更改。

    int y=5;         // y被放入.ebss中,5被放入.cinit中

     

    econst部分必须链接到非易失性,否则不能独立工作(没有仿真器)。

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

    非常感谢您的回答。 不幸的是,这似乎不是问题。 我试图去除一些变量上的"难题",但问题是一样的。

    此外(我可能错了,我从来没有花太多时间看事物在内存中的存储位置,并假定默认值是合理的),如果我正确读取.map和.cmd文件,则const变量已经在闪存中。

    从.map文件:  

    econst 0003 003f600万 0000.0118万
    003f600万 0000.01万 DSP2803x_PieVect.obj (.econst:_PieVectorTableInit)
    003f610万 0000.001万 control_C28x.obj (.econst:_IqDivOffset)
    003f611万 0000.0008万 control_C28x.obj (.econst:_IqDivShift) 

    从.cmd文件(TI默认为"F2.8035万_CLA_C.cmd"):  

    内存
    {
    第0页:/*程序内存*/
    /*内存(RAM/FLASE/OTP)块可移至Page1以进行数据分配*/
    RAMM0 :原点= 0x0.005万,长度= 0x0003B0 /*片上RAM块M0 */
    RAML3 :原点= 0x0.9万,长度= 0x0.1万 /*片上RAM块L3 */
    OTP :原点= 0x3D7800,长度= 0x0.04万 /*片上OTP */
    FLASHH :原点= 0x3E8000,长度= 0x0.2万 /*片上闪存*/
    FLASHG :原点= 0x3EA000,长度= 0x0.2万 /*片上闪存*/
    FLASHF :原点= 0x3EC000,长度= 0x0.2万 /*片上闪存*/
    FLASHE :原点= 0x3EE000,长度= 0x0.2万 /*片上闪存*/
    FLASHD :原点= 0x3F0000,长度= 0x0.2万 /*片上闪存*/
    FLASHC :原点= 0x3F2000,长度= 0x0.2万 /*片上闪存*/
    FLASHA :原点= 0x3F6000,长度= 0x001F80 /*片上闪存*/
    CSM_RSVD:原点= 0x3F7F80,长度= 0x0.0076万 /* FLASHA的一部分。 在使用CSM时使用所有0x0000编程。 */
    开始 :原点= 0x3F7FF6,长度= 0x0.0002万 /* FLASHA的一部分。 用于“引导至闪存”引导加载程序模式。 */
    CSM_PWL_P0:原点= 0x3F7FF8,长度= 0x0.0008万 /* FLASHA的一部分。 FLASHA */
    
    IQTABLES中的CSM密码位置:Origin = 0x3FE000,length = 0x000B50 /*引导ROM中的IQ数学表*/
    IQTABLES2:原点= 0x3FEB50,长度= 0x0.0008万C /*引导ROM中的IQ数学表*/
    IQTABLES3:Origin = 0x3FEBDC,length = 0x0000AA	/*引导ROM中的IQ数学表*/
    
    ROM :原点= 0x3FF27C,长度= 0x000D44 /* Boot ROM */
    reset :原点= 0x3FFFC0,长度= 0x0.0002万 /*引导ROM */
    矢量的一部分 :原点= 0x3FFFC2,长度= 0x0.0003万E /*启动ROM的一部分*/
    
    第1页:/*数据存储器*/
    /*内存(RAM/FLASE/OTP)块可以移动到PAGE0以进行程序分配*/
    /*寄存器保留在Page1上 */
    boot_rsvd:origin = 0x0万,length = 0x0.005万 /* M0的一部分,引导ROM将使用此堆栈*/
    RAMM1 :原点= 0x0.04万,长度= 0x0.04万 /*片上RAM块M1 */
    RAML0 :原点= 0x0.8万,长度= 0x0.08万 /*片上RAM块L0 */
    CLARAM0 :原点= 0x0.88万,长度= 0x0.04万
    CLARAM1 :原点= 0x008C00,长度= 0x0.04万
    
    CLA1_MSGRAMLOW:原点= 0x0.148万,长度= 0x0.008万
    CLA1_MSGRAMHIGH:原点= 0x0.15万,长度= 0x0.008万
    
    FLASHB :原点= 0x3F4000,长度= 0x0.2万 /*片上闪存*/
    
    }/*
    
    将段分配给内存块。
    注意:
    DSP28_CodeStartBranch.asm中的codegstart用户定义部分用于重定向代码
    引导至闪存时执行
    ramfuncs用户定义的部分,用于存储将从Flash复制到RAM
    */
    
    部分
    {/*.分配
    
    程序区域:*/
    .cinit的函数 :> FLASHA 页面= 0
    。Pinit :> FLASHA, 页面= 0
    .text :>> FLASHC | FLASHE 页面= 0
    代码开始 :>开始 页面= 0
    ramfuncts :负载= FLASHD,
    RUN = RAMM0,
    load_start(_RamfuncsLoadStart),
    load_end (_RamfuncsLoadEnd),
    run_start(_RamfuncsRunStart),
    页面= 0
    
    csmpasswds :> CSM_PWL_P0页面= 0
    CSM_rsvd. :> CSM_RSVD page = 0
    
    /*分配未初始化的数据段:*/
    .stack :> RAMM1. 页面= 1
    个.CIO :>> RAML0 | RAMM1 页面= 1
    .sysmem :> RAMM1. 页面= 1
    .ebss :> RAML0 页面= 1
    个.esysmem :> RAML0 页面= 1.
    
    
    /*初始化部分进入Flash *//*
    要使SDFlash对这些部分进行编程,必须将它们分配到第0页*/
    .econst :> FLASHA 页面= 0
    。switch :> FLASHA 页面= 0
    
    /*分配IQ数学领域:*/
    IQmath :> FLASHA 页面= 0 /*数学代码*/
    IQmathTables :> IQTABLES,PAGE = 0,TYPE = NoLoad
    
    BSS_CLA 		:> CLARAM0,PAGE = 1
    .scratchpad :> CLARAM0,第= 1页
    
    Cla1Prog :负载= FLASHD,
    RUN = RAML3,
    load_start (_Cla1funcsLoadStart),
    load_end (_Cla1funcsLoadEnd),
    run_start(_Cla1funcsRunStart),
    load_size (_Cla1funcsLoadSize),
    页面= 0
    
    Cla1ToCpuMsgRAM :> CLA1_MSGRAMLOW,页=1
    CpuToCla1MsgRAMs. :> CLA1_MSGRAMHIGH,page = 1
    Cla1DataRam0		:> CLARAM0,		page = 1
    Cla1DataRam1		:> CLARAM1,		page = 1
    
    组 	:负载= FLASHB,
    RUN = CLARAM1,
    load_start(_Cla1mathTablesLoadStart),
    Load_End(_Cla1mathTablesLoadEnd),
    Run_start(_Cla1mathTablesRunStart),
    Load_Size (_Cla1mathTablesLoadSize),
    页面= 1.
    
    {
    CLA1mathTables
    .const_CLA
    }
    	
    CLAskatch :
    {*。obj (CLAskatch)
    。 += CLA_ScratchPad_Size;
    *.obj(CLAScatch_end)}> CLARAM0,
    					Page =1
    					
    /*如果调用IQNexp()或IQexp(),则取消注释以下部分
    从IQMath.lib库中执行函数,以便利用
    引导ROM中的相关IQ Math表(这可节省空间和引导ROM
    为1等待状态)。 如果此部分未取消注释,请使用IQmathTables2.
    将加载到其他存储器(SARAM,闪存等)中并将占用
    打开空间,但0等待状态是可能的。
    */*
    
    IQmathTables2 :> IQTABLES2, page =0,type = NoLoad
    {
    
    IQMath.lib<IQNexpTable.obj>(IQmathTablesRam)
    
    }
    */
    /*如果调用IQNasin()或IQasin(),请取消对以下部分的注释
    从IQMath.lib库中执行函数,以便利用
    引导ROM中的相关IQ Math表(这可节省空间和引导ROM
    为1等待状态)。 如果此部分未取消注释,请使用IQmathTables2.
    将加载到其他存储器(SARAM,闪存等)中并将占用
    打开空间,但0等待状态是可能的。
    */
    /*
    IQmathTables3:> IQTABLES3,page =0,type = NoLoad
    {
    
    IQMath.lib<IQNasinTable.obj>(IQmathTablesRam)
    
    }
    */
    
    /*.reset是编译器使用的标准部分。 它包含
    _c_int00 for C Code的起始地址*/*。 /*
    /*使用引导ROM时
    ,不需要此部分和CPU矢量*/*表。 因此,默认类型在此处设置为*/*
    DSECT */
    .reset :>重置, Page =0,type = DSECT
    引导程序 :>引导程序 页面=0,类型= DSECT
    
    } 

    我曾尝试在某些情况下切换GPIO,因为这似乎起作用。  

    应用是PFC转换器。 电压控制环路位于C28x中,而电流控制环路位于CLA中。 主C28x中断中的平均电流参考(_IQ类型)计算得出结果(GPIO在"IrefDC >0)条件下正确切换), 但下一步,"AC"电流参考(浮点型,用于CLA)似乎疯狂(GPIO在一段时间内随机切换,然后在"Iref > 0.0 "条件下停在错误位置)。  

    我不知道这是否有帮助。 IQmath似乎也是在内存(?)中以不同方式管理的东西,所以这可能是问题的一部分吗?

    再次感谢您的帮助。

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

    您好,

    当您使用JTAG仿真器将程序加载到MCU中时,CCS用0填充任何单化RAM。 因此,如果有任何未明确初始化的变量,则可能会出现不同的行为。

    此外,从您的内存映射来看,您正在使用C编译器对CLA进行编程。 如果在针对CLA的C代码中声明任何常量(例如增益或饱和值),则必须自己初始化它们。 Hareesh提到的.cinit函数不会处理它。 该过程类似于使用ramfuncs部分执行的操作,但使用.const_CLA部分执行的操作。

    以下主题可能对您有所帮助: https://e2e.ti.com/support/development_tools/compiler/f/343/p/53.5988万/1962459</s>196.2459万

    谢谢,

    PB

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

    您好,

    非常感谢Pierre的回答。 我需要深入挖掘并将我的头缠绕在您指出的链接上,但这肯定是事实。

    到目前为止,我在.const_CLA部分中没有任何内容。 它甚至未初始化。 我在CLA代码中使用的所有变量都在一个.c文件中初始化。

    在Control_C28x.c中:

    #pragma data_section(f_dutyMax,"CpuToCla1MsgRAM");
    #pragma data_section(f_dutyMin,"CpuToCla1MsgRAM");
    #pragma data_section(f_I_Ki, "CpuToCla1MsgRAM");
    #pragma data_section(f_I_KP,"CpuToCla1MsgRAM");
    
    
    float32	f_dutyMax = Duty_MAX;
    float32	f_dutyMin = 100.0 ;
    float32	f_I_KI = 3.0 ;
    float32	f_I_KP = 10.0 ; 

    在Control.h中(在Control_CLA.CLA中使用):  

    extern float32	f_dutyMax;
    extern float32	f_dutyMin;
    extern float32	f_I_KI;
    extern float32	f_I_KP; 

    使用controlSUITE中提供的CLA示例(这是我使用CLA的第一个项目)和 wiki上的信息,我将.CLA文件中使用的所有变量放入了.c文件中进行初始化,并使用相关  pragma (#pragma data_section(XXX,"CpuToClA1MsgRAM");或#YYma data_section(MsY,"ClagRAM"To1")进行初始化。 从示例和维基来看,这看起来是一条好路,但显然,我被误导了。  

    我想我会再去弄清楚这一点。 由于这些都不是非常直观的,所以最好有一个如何在controlSUITE中正确执行操作的示例...

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

    您好,

    有一些我不明白的事... 我的操作方式是,CLA使用的所有变量都声明在常规的C28 .c文件中,并存储在CLA可访问区域的RAM中。 由于(非常量)变量是在C28 .c文件中声明的,它们是否被初始化为正常(非常量)变量? 如果是这样,它是否也应该在非调试模式下工作? (在这种情况下,如果某些变量变得不变,但仍不更改任何其他内容,它是否会失败?)

    提前感谢!

    Adrien

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

    您好Adrien:

    Adrien thurin 说:
    由于(非常量)变量是在C28 .c文件中声明的,它们是否未初始化为正常(非常量)变量?[/QUOT]

    是的,正确。 如果在共享头文件中创建了原型,并在.c文件中定义了它们,则可以对它们进行初始化。 如果变量仅是.cA文件的全局变量(即不共享且仅具有文件作用域),则不会初始化它们,因为没有等效的.cinit来初始化这些变量。

    如果更简单,您可以简单地在C28x和CLA之间共享所有全局, 在将RAM的控制权移交给CLA之前,让C28x对其进行初始化。在.CLA文件中定义的全局将放置在“.bss_CLA”部分,而共享全局则需要使用pragma手动放置。

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

    您好,Vishal,

    感谢您的回答。 完全合理!

    我仍然不能让它发挥作用,我的想法有点不够。 有一些改进:PWM开关,但切换没有意义(而以前,它们根本不会启动)。 这一改进发生在我在CLA时钟通电后移动CLA初始化(这是一个愚蠢的错误!)。 我还使用相应的pragma在C28x . c文件中移动了CLA使用的所有变量(甚至以前的本地CLA变量现在都是全局变量,并在C28x . c文件中定义)。 MAP文件显示所有CLA变量都在Cla1ToCpuMsgRAM (由CLA修改的变量)或CpuToCla1MsgRAM (已读取但未由CLA修改的变量)中。 初始化过程与controlSUITE中的示例几乎相同。  然而,在调试模式和重置后,切换方式却截然不同:调试模式中正弦电流的可变负载循环,0或最大占空比/全部或无非调试模式。 看起来控制循环已经疯狂了,如果未正确读取增益,引用或其他变量,可能会出现这种情况。  

    如果你对可能发生的事情有任何想法,或者我可以做些什么来解决问题,那将会非常有帮助。

    再次感谢大家,

    Adrien

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

    您好,

    我知道问题的后半部分是什么。 我有一个数组用来存储多个度量值,以便执行浮动平均值。 它已初始化如下:

    _IQ MyArray[N]={0}; 

    似乎在调试模式下,整个阵列初始化为0。 但在调试之外,情况似乎并不是这样,导致浮动平均值以非零值(有时意外为负值)开始。 因此,所有控制环路都具有弹道。

    最后,一个简单的循环将整个阵列初始化为0,解决了问题。

    感谢大家的帮助。

    Adrien