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/LAUNCHXL-F2.8379万D:RAM上的代码工作正常,闪存上的代码损坏

Guru**** 2585275 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/655030/ccs-launchxl-f28379d-code-works-fine-on-ram-corrupted-on-flash

部件号:LAUNCHXL-F2.8379万D

工具/软件:Code Composer Studio

在过去的9个月里,我一直在开发一个程序,直到最近,它在RAM或闪存上运行良好。 我通常会为RAM进行编译,因为程序在调试时加载速度要快得多。 我最近对该程序做了大约2周的更改-一直在验证它在RAM配置上是否起作用。 但是昨天我在闪存上测试了它,它的失败非常惊人。  

有时程序会在非法ISR上停止,有时在调试器未意识到的情况下停止,最令人震惊的是,C++类中的成员数据将随机更改。 事实上,这可能是程序不断停止的原因,因为重要类的一个成员变量是函数指针,用于从帮助程序中获取当前的GPIO或ADC值。 虽然有检查以确保指针不为空,但我猜指针有时会被更改(因为我看到该类中的所有其他内容都发生了变化),当调用update函数时,它会很高兴地崩溃。 如果从未初始化或使用此类,我似乎无法使其崩溃。  我应该清楚,从RAM运行时不会出现这些问题。

考虑到这是某种重叠损坏, 我已经根据以前的版本和其他C2000示例重新验证了linker.cmd文件。 我还想知道这是否与第一次使用堆实例化对象有关-但如果我静态定义对象,这种情况仍会发生。 作为附带说明,我打开了所有警告(没有任何警告),并且所有代码都是c++(此更改之前所有的代码都是c,但我真的希望使用类和其他几个功能,以便更容易封装各种内容)。

如果有任何关于跟踪此情况的提示,我将不胜感激。

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

    我意识到添加我的闪存链接器文件可能会很有帮助(再次证明这些错误仅在闪存中发生):

    内存
    {
    第0页://page
    0是程序代码
    
    	// begin用于“引导至闪存”引导加载程序模式
    	开始 	:原始= 0x8万,长度= 0x0.0002万	//实际加载到FLASHA
    	RAMM0中 	:Origin = 0x0.0122万,length = 0x0002DE	//为BOOT_RSVD
    	RAMD0提取的部分 	:原点= 0x00B000,长度= 0x0.08万
    
    	//Cla1Prog
    	RAMLS0_CLA_PROG	:原点= 0x0.8万,长度= 0x0.08万
    	FLASHM			:原点= 0x0BC000,长度= 0x0.2万
    
    	RAMLS2			:原点= 0x0.9万,长度= 0x0.08万
    	RAMLS3			:原点= 0x0.98万,长度= 0x0.08万
    	RAMLS4			
    				:0:0:0 原点= 0x00A800,长度= 0x0.08万
    
    	//当前GS0-3
    	RAMGS_CPU1 _PAGE0			:原点= 0x00C000,长度= 0x0.4万
    
    	重置 	:原始= 0x3FFFC0,长度= 0x0.0002万
    
    	//闪存扇区
    	// A,B,C,D,... K,L,M,N为8k长
    	// E,F,G,H,I,J为32k长
    	FLASHA :原点= 0x8.0002万,长度= 0x001FFE	//为BEGIN
    	FLASHB取出的块 :原点= 0x8.2万,长度= 0x0.2万
    	FLASHC :原点= 0x8.4万,长度= 0x0.2万
    	FLASHD :origin = 0x8.6万,长度= 0x0.2万
    
    
    
    第1页:
    //page 1用于数据
    
    	boot_RSVD :原点= 0x0.0002万,长度= 0x0.012万 /* M0的一部分,引导ROM将使用此堆栈*/
    	RAMM1_STACK :原点= 0x0.04万,长度= 0x0.04万 /*片上RAM块M1 */
    	RAMD1 :原始= 0x00B800,长度= 0x0.08万
    
    	//CLA_DATA
    	RAMLS1_CLA_DATA	:原始= 0x0.88万,长度= 0x0.08万
    
    	//CLA和CPU消息RAM (完全小,因此未使用)
    	//CLA1_MSG_CLA_TO_CPU:原始= 0x0.148万	,长度= 0x0.008万 //CLAtoCPU/CLAS1/CLUS_1=
    	0x0000MP1/CLUS_1_1_0 	
    
    	
    			:Origin = 0x1万,length = 0x0.8万
    
    	//heap -填充0以便更容易识别(当前为GS12-15)
    	RAMGS_heap				:origin = 0x1.8万,length = 0x0.4万
    
    	//对于CLA常量
    	FLASHN			:origin = 0x0BE000,length = 0x0.2万
    }
    
    节
    {//
    	分配程序区域:
    	codegstart :>开始, 页面= 0,对齐(4)
    	.cit :> FLASHA,		page = 0,align(4)
    	。Pinit :> FLASHA,		page = 0,align(4)
    	.text :>> FLASHA | FLASHB | FLASHC | FLASHD Page =0,align(4)
    
    	//分配未初始化的数据部分:
    	.stack :> RAMM1_STACK,		page = 1
    	.ebss :> RAMGS_CPU1_Page1,	页面= 1
    	。esysmem :> RAMGS_heap,	page = 1
    	.cio :> RAMGS_CPU1_Page1,	page = 1
    
    	//初始化的节转至Flash
    	.econst :>> FLASHA | FLASHB | FLASHC | FLASHD 页面= 0,对齐(4)
    	.switch :> FLASHA 页面= 0,对齐(4)
    
    	.reset :>重置, Page =0,type = DSECT /*未使用,*/
    
    #ifdef __TI_Compiler_version__
    #if __TI_Compiler_version__>= 1500.9万
    .ti.ramfunc:{} load = FLASHA,
    RUN = RAMM0,
    load_start(_RamfuncsLoadStart),
    load_size (_RamfuncsLoadSize),
    load_end (_RamfuncsLoadEnd),
    run_start(_RamfuncsRunStart),
    Run_Size (_RamfuncsRunSize),
    Run_End(_RamfuncsRunEnd),
    页面= 0,对齐(4)
    #else
    ramfuncs :负载= FLASHA,
    RUN = RAMM0,
    load_start(_RamfuncsLoadStart),
    load_size (_RamfuncsLoadSize),
    load_end (_RamfuncsLoadEnd),
    run_start(_RamfuncsRunStart),
    Run_Size (_RamfuncsRunSize),
    Run_End(_RamfuncsRunEnd),
    Page =0,align(4)
    #endif
    #endif
    
    
    #ifdef CLA_C
    // CLA特定部分
    
    	//必须保留“Cla1Prog”名称
    	Cla1Prog		:load = FLASHM,
    运行= RAMLS1_CLA_PROG,
    load_start (_Cla1funcsLoadStart),
    load_end (_Cla1funcsLoadEnd),
    run_start(_Cla1funcsRunStart),
    load_size (_Cla1funcsLoadSize),
    Page =0,align(4)/CLA_to_CPU_msg_ram
    
    	:> CLA1_MSG_CLA_to_CPU,	page = 1//CCPU_to_CLA_msg_ram
    	:> CLA1_MSG_CPU_to_CLA,	page = 1
    
    	CLA_DATA		:> RAMLS1_CLA_DATA,	page = 1.MLchpad
    		:> RAMLSS1_CLA_CLA = RASS_CLA =	
    				
    		数据,CLA = 1,CLA =数据,CLA_CLA = RASS_CLA 1
    运行= RAMLS1_CLA_DATA,
    Run_start(_Cla1ConstRunStart),
    load_start (_Cla1ConstLoadStart),
    Load_Size (_Cla1ConstLoadSize),
    页面= 1
    #endif //CLA_C
    
    } 

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

    亚当

    我过去也遇到过类似的问题。 下面是一些调试建议,我觉得很有用:  

    在RAM中运行代码时,请确定代码运行时间,以查看代码运行时间是否与可用时间的边缘相对应。

    —在编译时,请使用优化设置。 有时,事情被优化到错误的位置,代码在运行时失败。

    检查堆栈的使用情况,查看您有时不会覆盖分配的内存。  

    逐步执行代码中的任何自定义汇编函数。 我看到这些在不同的编译器下的行为不同。

    如果您最近升级了CCS版本,则您使用的编译器可能已更改。 尝试使用旧版本重新编译

    如果所有其他操作都失败,请将代码恢复到工作状态,进行二进制搜索,直到代码中断并比较差异。

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

    感谢您的建议。 我想强调的一点是,我使用相同的项目,使用相同的编译器设置(包括优化)来生成RAM和闪存版本。 因此,除了在启动过程中出现的init_flash代码之外,如果我理解正确,所有代码都应该完全相同。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    供将来参考。 它似乎现在正在工作,可能是以下内容的某种组合:

    • 我增加了RAM配置文件中的堆空间,但没有增加闪存配置文件。 因为我从未明确测试分配是否失败,所以这里可能失败了。 当我直接用RAM配置文件替换闪存配置文件(并添加了flash_定义)时,我注意到了这一点。 我将确保在将来测试我的所有分配。
    • 由于我向主ISR添加代码已有很长时间,我忘记了在其内部使用的所有内容(以及从外部初始化或写入的内容)都应该标记为易失性。 我也做了这些改动。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Adam,感谢您发布您的调查结果,这些结果可以帮助社区中的其他人。