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.

[参考译文] TMS320F28377S:放置在闪存组0末尾的代码引起 NMI 中断(在0x000B FFF0-0x000B FFFF 范围内)

Guru**** 2451970 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/957549/tms320f28377s-code-placed-at-end-of-flash-bank-0-causes-nmi-interrupt-in-0x000b-fff0---0x000b-ffff-range

器件型号:TMS320F28377S

你(们)好  

我们的生产产品会导致我们遇到一些问题。 它基于 TI 28377微控制器。

我们使用的是 TI v18.1.4.LTS 工具链、SYS/BIOS 6.75.0.15、XDCtools 3.51.1.18_core。

如果我使用的是 JTAG、一切看起来都正常、因此 GEL 文件可能会做一些神奇的事情、但我们却不会这样做。 错误似乎随代码的变化而变化、因此错误并不总是位于这段代码中。

我在引导过程的早期(WD 被禁用)有一个 while 循环、然后连接到正在运行的目标并继续执行"引导"过程、从而设法重现错误。 这样、我成功捕获 NMI 中断并查看调用堆栈。 下面是这方面的图片:

您可能已经注意到,故障似乎是在 getCrcFromSection()函数中的 memcpy 周围发生的。 如果我将 JTAG 与标准28377s GEL 文件一起使用来初始化 CPU、这通常会起作用、因此该代码应该可以正常运行。

我已经注意到、这个代码被放置在0x000C 0000边界上、这是闪存组1的开始。 目前、我们在链接器 cmd 文件中有一个大闪存范围、该范围涵盖闪存组0和1 (这可能会改变)。 我已经查看了 CPU (sprz422i)关于"存储器:有效存储器之外的预取"的建议的勘误表、根据此结果、此 CPU 的这两个闪存组之间的边界没有限制。

我们已使用 InitFlash_BANK1()和 InitSysCtrl()(后者调用 InitFlash_BANK0())初始化两个闪存组

我已经尝试在 sectionFromName()之前设置一个断点 ,整个调用栈和变量看起来不错。 当我单步执行 sectionFromName/memcpy()时,会触发 NMI 中断,调用栈如之前所示。

我们看到的是与上述勘误表相关的流水线问题还是其他问题?

更新:
我已经尝试在闪存组0和1之间的边界之前和之后手动放置 getCrcFromSection()函数。

如果我完全避免0x000B FFF0-0x000B FFFF 范围、根据勘误表、这个 CPU 应该不需要这个范围、那么一切看起来都正常。

如果我将 getCrcFromSection()函数的一部分放在上述范围内,则会发生 NMI 异常。

勘误表错误吗?

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

    大家好、Mads Lind、

    感谢您将此事提请我们注意。

    GEL 文件禁用 ECC。  发生此故障时、您是否注意到 ECC 错误和/或 ITRAP?  此外、请检查 RESC、NMIFLG 和闪存 ECC 寄存 器的值(TRM 中的 UNC_ERR_ADDR_LOW 和 UNC_ERR_ADDR_HIGH)。

    我将与顾问作者核实、以确认该建议是否适用于 Bank0的末尾(即使立即有另一个银行、闪存包装程序也不同-我将在这方面询问)。  希望您为这两个组正确配置了等待状态。

    谢谢、此致、

    Vamsi

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

    你(们)好,Vamsi

    非常感谢快速响应。

    我刚才检查了您建议的寄存器。

    NMIFLG = 0x0009:  NMIINT 和 FLLUNCERR (闪存不可纠正的错误 NMI 标志)

    RESC = 0xC0000000:TRSTn_PIN_STATUS 和 XRSn_PIN_STATUS 为1、我认为这是正常的、正常上电。

    Flash0EccRegs:
    UNC_ERR_ADDR_LOW = 0x000C0000
    UNC_ERR_ADDR_LOW = 0

    Flash1EccRegs:
    UNC_ERR_ADDR_LOW = 0
    UNC_ERR_ADDR_LOW = 0

    那么、闪存组0是否看起来会在闪存组1的起始地址引起故障?  
    可能是因为正如您说的、闪存包装程序是不同的?

    两个闪存组均已正确配置。

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

    Mads Lind、

    感谢您检查这些寄存器。

    您能否在启用 ECC 的情况下将简单代码加载到 RAM 中以读取整个闪存(两个组)、而不是执行应用程序?  请勿擦除闪存中的应用程序-保持原样、只需检查 ECC 错误是否显示为读取错误。

    这有助于进一步调试。

    谢谢、此致、
    Vamsi

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

    你(们)好,Vamsi

    我在 RAM 中向应用添加了一个函数、因此不是单独的应用。 希望这已经足够好了。

    我在运行 InitSysCtrl 等之后执行了它、以便将 ramfuncs 从闪存复制到 RAM。

    #ifdef __TI_Compiler_version__
    #if __TI_Compiler_version__>=15009000
    #pragma CODE_SECTION (".TI.ramfunc");
    其他
    #pragma CODE_SECTION ("ramfuncs");
    #endif
    #endif
    void flashReadTest()
    {
    volatile uint16_t * flash_start =(uint16_t *) 0x00080000;
    volatile uint16_t * flash_end =(uint16_t *) 0x00100000;
    
    uint32_t SUM = 0;
    
    // ESTOP0;
    
    while (flash_start!= flash_end)
    {
    sum +=* flash_start++;
    }
    
    // ESTOP0;
    } 

    执行该函数时没有任何问题。

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

    Mads Lind、

    感谢您的测试和结果。

    在这个针对两个闪存包装程序的测试执行期间、ECC 检查是否被启用?

    在我们与设计团队讨论这一点时、现在请避免链接器 cmd 文件中 bank0的最后256位。   

    谢谢、此致、
    Vamsi

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

    你(们)好,Vamsi

    是的、两个闪存组都启用了 ECC。
    因此、结论可能是整个闪存区域的数据读取是可以的、但程序执行不是针对闪存组0的末尾。

    我现在已经采取措施来避免链接器文件中的区域。

    非常感谢快速支持:-)

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

    Mads Lind、

    感谢您的确认。

    当我从我们的设计团队获得更多详细信息时、我将在此处进行更新。  我现在要关闭此帖子。

    说明:  

    对于取指令:启用预取时、FMC0将从 Bank0空间中提取到 Bank1中的空间之外- FMC0无法访问该空间、因此会失败。

    数据读取:数据高速缓存填充不会超过当前的128位闪存字(在128位边界上对齐)。  因此、数据错误不应导致问题。   

    以上是我希望从您的实验中确认的内容-以确定此问题是由 FMC0在 Bank0之外预取而不是实际 ECC 错误导致的 (您得到的 ECC 错误不是实际的 ECC 错误-它是由于预取提供了错误的操作码)。

    此致、

    Vamsi

     

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

    FYI 对于可能引用此帖子的其他人:Bank0和 Bank1的最后256位应保留在此设备中。  我们将更新勘误表以反映相同情况。

    谢谢、此致、
    Vamsi

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

    Mads Lind、

    您对此还有其他问题吗?  或者我可以关闭此帖子吗?  请告诉我。

    谢谢、此致、
    Vamsi

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

    一切都很好,所以请继续,关闭这个:-)

    再次感谢您的快速响应。

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

    Mads Lind、

    感谢您的确认。

    此致、
    Vamsi