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.

[参考译文] TMS320F280025C:意外修改内存变量

Guru**** 2394305 points
Other Parts Discussed in Thread: TMS320F280025C

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1262481/tms320f280025c-memory-variable-being-modified-unexpectedly

器件型号:TMS320F280025C

你(们)好!

我一直在开发固件,突然我注意到一个无关的变量被更改,当我修改一些完全无关的代码。 在我看来、它与代码本身无关、更像是非法访问情形。  我确信这一点是因为我将变量修改为一个奇怪值的点跟踪到甚至在它到达我更改过的代码之前的点。

请注意、变量的值变为48、并且任何其他代码片段都不可能将其设置为该值。 (其范围通常为0-12)

我还将 TMS320F280025C 硬件交换到另一个样本上、以验证存储器是否未出现某种程度的损坏。  

如对从何处开始查找有任何建议、欢迎您提出。 我还在下面附上了我的闪存链接器文件。

提前感谢、

内存
{
begin:origin = 0x080000、length = 0x000002
BOOT_RSVD:origin = 0x00000002、length = 0x00000126
RAMM0:origin = 0x00000128、length = 0x000002D8
RAMM1:origin = 0x00000400、length = 0x000003F8 /*片上 RAM 块 M1 */
// RAMM1_RSVD:origin = 0x000007F8,length = 0x00000008 /*根据勘误建议"存储器:预取超出有效存储器"保留代码且不使用*/

/* RAMLS4:origin = 0x0000A000、length = 0x00000800
RAMLS5:origin = 0x0000A800、length = 0x00000800
RAMLS6:origin = 0x0000B000、length = 0x00000800
RAMLS7:origin = 0x0000B800,length = 0x00000800*/

/*组合所有 LS RAM */
RAMLS4567:origin = 0x0000A000、length = 0x00002000
RAMGS0:origin = 0x0000C000、length = 0x000007F8
// RAMGS0_RSVD:origin = 0x0000C7F8,length = 0x00000008 /*保留且不使用勘误建议"存储器:预取超出有效存储器"中的代码*/


// FLASHBANK1:origin = 0x00080000,length = 0x0000FFF0
// FLASH_BANK1_RSVD:origin = 0x0008FFF0,length = 0x00000010 /*根据勘误建议"存储器:预取超出有效存储器",保留代码,且不用于此代码*/
BootROM:origin = 0x003F0000、length = 0x00008000
BootROM_EXT:origin = 0x003F8000、length = 0x00007FC0
复位:origin = 0x003FFFC0、length = 0x00000002
/*闪存扇区*/
/*组0 */
FLASH_BANK0_SEC0:origin = 0x080002、length = 0x000FFE /*片上闪存*/
FLASH_BANK0_SEC1:origin = 0x081000、length = 0x001000 /*片上闪存*/
FLASH_BANK0_sec2:origin = 0x082000、length = 0x001000 /*片上闪存*/
FLASH_BANK0_SEC3:origin = 0x083000、length = 0x001000 /*片上闪存*/
FLASH_BANK0_SEC4:origin = 0x084000、length = 0x001000 /*片上闪存*/
FLASH_BANK0_SEC5:origin = 0x085000,length = 0x001000 /*片上闪存*/
FLASH_BANK0_SEC6:origin = 0x086000、length = 0x001000 /*片上闪存*/
FLASH_BANK0_sec7:origin = 0x087000、length = 0x001000 /*片上闪存*/
FLASH_BANK0_SEC8:origin = 0x088000、length = 0x001000 /*片上闪存*/
FLASH_BANK0_SEC9:origin = 0x089000、length = 0x001000 /*片上闪存*/
FLASH_BANK0_SEC10:origin = 0x08A000、length = 0x001000 /*片上闪存*/
FLASH_BANK0_SEC11:origin = 0x08B000、length = 0x001000 /*片上闪存*/
FLASH_BANK0_SEC12:origin = 0x08C000、length = 0x001000 /*片上闪存*/
FLASH_BANK0_SEC13:origin = 0x08D000、length = 0x001000 /*片上闪存*/
FLASH_BANK0_SEC14:origin = 0x08E000,length = 0x001000 /*片上闪存*/
FLASH_BANK0_SEC15:origin = 0x08F000、length = 0x000FF0 /*片上闪存*/
// FLASH_BANK0_SEC15_RSVD:origin = 0x08FFF0,length = 0x000010 /*保留代码,且不使用勘误建议"存储器:预取有效存储器之外的代码"*/


部分
{
codestart :> beging, align (8)
.text:>> FLASH_BANK0_SEC1 | FLASH_BANK0_SEC2 | FLASH_BANK0_SEC3 | FLASH_BANK0_SEC4 | FLASH_BANK0_SEC5 | FLASH_BANK0_SEC6 | FLASH_BANK0_SEC7、ALIGN (8)
.cinit:> FLASH_BANK0_SEC0、align (8)
.switch:> FLASH_BANK0_SEC0、ALIGN (8)
.reset:> reset,type = DSECT /*未使用,*/

.stack:> RAMM1

//.init_array:> FLASH_BANK0_SEC1、ALIGN (8)//ss 因某种原因未使用
.bss :> RAMLS4567
.bss:输出:> RAMLS4567
bss:CIO:> RAMGS0
.const:>> FLASH_BANK0_SEC9| FLASH_BANK0_SEC10,ALIGN (8)//SS 问题与扇区9
.data:> RAMLS4567
.sysmem:> RAMLS4567

ramgs0:> RAMGS0

/*分配 IQ 数学领域:*/
IQMath :> RAMLS4567
IQmathTables :> RAMLS4567

.TI.ramfunc:load = FLASH_BANK0_SEC0、//WAS sec1
运行= RAMGS0、
Load_start (RamfuncsLoadStart)、
Load_Size (RamfuncsLoadSize)、
Load_End (RamfuncsLoadEnd)、
RUN_START (RamfuncsRunStart)、
RUN_SIZE (RamfuncsRunSize)、
RUN_END (RamfuncsRunEnd)、
对齐(8)


/*
//========================================
//文件结尾。
//========================================
*/

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

    Steven、

    如果你打开一个内存窗口(View->Memory Browser)、你应该能够在地址字段中键入变量名称、并且 CCS 将拉高那个内存区域(你可能需要执行@var_name、我现在无法回忆)。  然后、我们可以看到它存储在何处。  然后、我会回头查看链接器文件、看看所有内容被分配给该区域、看看是否存在一些冲突。

    您还可以查看.map 文件(应与.out 文件位于同一目录中)以交叉检查.cmd 文件在该区域中存储的内容。

    乍一看、这可能与 GS0有些冲突、因为您正在将代码复制到该区域、但我也看到.bss:CIO 也映射在那里。  还有一个段定义"ramgs0"也在这里指定、不确定您是否在.c 文件中将其用于数据段等。  我不确定链接器是否知道有任何冲突、因为代码加载到闪存、从 RAM 运行...  

    我认为这不是堆栈溢出、我没有在上面的链接器中看到分配给 RAMM1的任何其他内容。

    此致!

    马修

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

    您好、Adam、

    感谢您的快速响应。

    关于 链接器分配代码:"ramgs0:> RAMGS0"  和 ".bss:cio      :> RAMGS0 ",

    默认情况下、这位于链接器文件中、我没有修改它。

    我试图打开内存浏览器、但无法搜索@名称的变量名称(显示"unable to go to specified address")、但我手动找到了0xA4C0的位置、如下所示(变量名称是 screenPage)。

    然后我 检查了映射文件、出于某种原因、该变量被显示在位置 a286中、有一种原因。 是否有任何想法、这是否正常/可能?  

    有趣的是 、RAMLS4567似乎是它的位置、因为它始于0xA000:

     RAMLS4567     : origin=0x0000A000, length =0x00002000

    有一些命令/行可在链接器文件中为 RAMLS4567分配内存(请参阅原始发布)。 有什么建议可以尝试?  

    如果以上设置看起来没问题、请告诉我是否也应该检查堆栈。 c_int00的栈使用量似乎很高、不确定这是否正常:


    再次感谢、

    周老师

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

    对不起,我在上一篇文章中指的是 Matthew。 为您提供快速更新、

    作为一个实验,我尝试手动分配一些部分 RAMLS4 RAMLS5 RAMLS6 RAMLS7位置,而不是单一的 RAMLS4567。  它现在似乎可以正常工作、不会覆盖该变量、 由于原始  RAMLS4567分配是 TI 的默认设置、 我仍不确定是什么原因会导致该变量被覆盖-我担心这会再次发生、下次可能不会如此明显?

    请告诉我可以考虑在链接器文件中进行修复来防止这种情况发生。

    非常感谢

    .stack:> RAMM1

    //.init_array:> FLASH_BANK0_SEC1、ALIGN (8)//ss 因某种原因未使用
    .bss :> RAMLS4
    .bss:输出:> RAMLS4
    bss:CIO:> RAMGS0
    .const:>> FLASH_BANK0_SEC10| FLASH_BANK0_SEC11,ALIGN (8)//SS 问题与扇区9
    .data :> RAMLS6
    .sysmem :> RAMLS5

    ramgs0:> RAMGS0

    /*分配 IQ 数学领域:*/
    IQMath :> RAMLS5
    IQmathTables :> RAMLS5

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

    Steven、

    我很高兴您解决了这个问题、但同意不会将此过载的根本原因加到该存储器区域中。  我还没有看到物理存储器中的分配与.map 文件也不匹配。

    即使定义了连续存储器、链接器也不应重复分配存储器地址、即即使.bss 和.data 正在"共享"同一空间、链接器也应为每个空间提供唯一的位置/跨区。  当您唯一分配了这些段时、您已经使其具有了方向、因此链接器无法执行此操作、即使您的器件不需要这样做(至少我认为这是这样)

    screenPage 是否被分配给.bss (未初始化的数据)或.data (已初始化的数据)?  

    如果您返回到原始的.map 文件、您会看到它在0xA4C0 (您在其中看到了存储器中的 screenPage 变量)中应该是什么。

    此致!

    马修

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

    Matthew、您好!  

    非常感谢您的答复。 感谢您确认这种双重行为与可疑行为不符。 我设法找到了由于 阵列位置写入(通过指针)超过阵列定义的最大大小而导致的原因。 这种随机位置写入可以严重破坏,虽然我不知道我会如何找到它,如果我没有注意到错误的代码。  

    无论哪种方式,我很高兴找到原因!

    再次感谢、

    周老师

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

    Steven、

    谢谢你的跟进,很高兴我们找到了罪魁祸首。

    我想提一下我们在硬件中具有的一些功能、这些功能可能对将来有所帮助;无论是用于调试还是一般情况。

    在 TRM https://www.ti.com/lit/pdf/spruin7 中的第3.11节内存控制器模块/3.11.1.5访问保护:

    我们能够从 CPU 强制执行读取/写入/获取保护、或在存储器块的基础上从 DMA 强制执行写入保护。  操作不仅会被阻止、还会记录未正确访问的地址。  这也会触发 ISR。

    如果这些数据在某些初始化之后是静态的、您可以在 HW 中阻止对其进行修改。  如果该区域中的所有存储器都是静态的等等、则需要这样做;但这样做可能有助于捕捉此类情况、或根本防止发生此类情况。

    此致!
    马修

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

    谢谢 Matthew、我对此一无所知。 我认为这肯定会对未来发展有所帮助、