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.

[参考译文] RM48L952:在调试期间很少出现推测取指令、即使整个存储器已被填满一次也是如此

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/603810/rm48l952-speculative-fetch-appears-rarely-during-debugging-even-the-whole-memory-has-been-filled-once

器件型号:RM48L952
主题中讨论的其他器件:SEGGER

您好!

为了向 Segger (或 IAR)提出正确的问题 、如果您能猜测哪种操作可能会使 CPU 处于 ECC 损坏的状态、我将不胜感激、因为我很确定这是由我们的开发环境造成的。 我基本上重复了相同的"编译、下载和调试模式"、通常一切都正常、但这种预取问题很少引起人们的关注、即使闪存已被加载一次也是如此。

问题1:如果调试器由于某种原因有时会执行整个芯片擦除、ECC 是否会损坏(擦除是否清除 ECC 区域)-如果是、则此意外的整个芯片擦除可能是导致此类行为的潜在原因?

我正在使用 IAR IDE 和 Segger 的 Jlink、在我按照这里的说明填充整个存储器之后、已经对推测取问题进行了几次计数(确切地说是3或4、所以没有太多的比较我已经下载了多少代码) (我的同事也遇到过这种情况、因此这不应是用户或单个器件链问题)。
https://e2e.ti.com/support/microcontrollers/hercules/f/312/t/588269

在存储器填满1个完整的存储器后、我一直将映像大小恢复为"正常大小"、因此在正常调试中、不会反复对整个存储器进行编程。 我还使用 Segger 的比较作为"使用最快的方法"、因此它应该只刷写所需的部分、并且典型的编程需要几秒钟的时间。 由于这种情况只发生了几次、我下载了很多代码、因此这种预取错误的可能性很可能小于每毫秒、但当它达到时、需要一段时间才能了解根本原因-这就是它相当烦人的原因 解决这个问题。

FUNC_ERR_ADD 每次都与初始问题(0x135a98)中的 CPU 存储器未被填满相同、并且我们的代码仍然只有~0x20000长、因此正常编程不应触及该有问题的区域、如果正确理解、这2的 ECC 位就会非常独立 存储器位置不相邻、因此 ECC 写入中的"次要错误"不应损坏值... 在执行完整芯片闪存时、我已经用0xFF 填充了代码、以防出现这种情况。 当您擦除芯片并启用二进制填充并使用"IAR 闪存加载程序"来刷写整个芯片时、问题立即得到解决、之后您可以返回到"优化"下载。


相关信息:

-问题2:在生产中、您需要对整个闪存进行编程(因为它是首先使用 CPU)、因此需要生成填充的映像进行编程或配置编程工具、以便填充到闪存的末尾?

问题3:固件更新(尚未查看该部分、我知道有库可用于处理包括 ECC 在内的编程)、您需要手动(或执行该库)对0xff (或其他数据)进行编程吗? 最后一个被擦除扇区的末尾、以防代码未将其填充? 其他选项是在固件更新中也使用填充的二进制文件...

问题4:如果未使用的闪存区域中的某个位置仍然存在隐藏的 ECC 错误,它是否会始终被“立即”触发,或者可能需要一周或几个月(或从不)才会弹出? 在 main()之前,我没有遇到启动例程,看起来错误总是被激活~当操作系统启动和任务开始运行时,这一阶段仍处于良好的阶段,因为您很快就会注意到 nERROR 已关闭,并立即知道存在问题。

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

    您好!

    1.当闪存组/扇区被擦除时、相应的 ECC 区域也被擦除。 默认情况下不启用 ECC、应用必须启用 CPU 的 ECC 检查、以检查 CPU ATCM 和 BTCM 接口上的访问。 CPU 通过其事件总线发出一个 ECC 错误信号、这个信号机制缺省情况下不启用并且必须由应用启用。 在擦除/编程阶段、我们不会看到与 ECC 相关的错误、就像在另一个器件(RM57)中一样。 我不确定错误是否是由整个芯片擦除(bank1/2和 bank7)引起的。

    2.用相应的 ECC 填充未使用的闪存是为了解决 CPU 的推测访问问题。 我们不必填充所有未使用的闪存(减少下载时间)。 我认为填充最后使用的部门及其下一个部门可能已经足够了。  

    3.闪存 API (Fapi_issueProgrammingCommand (...)) 可以对数据缓冲区进行编程、并自动生成 ECC 并对其进行编程。 在应用程序代码被编程后、我们可以使用0xFFFFFFFF 手动对未使用的扇区进行编程、闪存 API 将对其 ECC 区域进行编程。

    4.如果推测从获取未使用的闪存位置、则我们可以得到不可纠正的 ECC 错误。 如果隐藏的 ECC 错误(如果有)远离代码末尾、则不会触发。

    此致、

    问  

     

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

    您好!

    我们在启动过程中按照 CPU 初始化文档中的建议激活了 ECC 检查。 因此、全芯片擦除可能是推测取指令错误的一个潜在原因? (***,另见员额底部)

    问题: 在我们的案例中、FUNC_ERR_ADD 一直是0x135a98 (***、请参阅文章的底部)发出任何提示(我们的代码仅为~0x20000长(6位与5位)、所以我们的代码应仅使用组0的扇区0-4的最大值、甚至不使用4。

    2.在这个帖子中,你建议为了防止推测取指令错误,整个闪存(两个组)应该被填满一次(这解决了我们最初的问题,并且花费了很长时间直到推测取指令再次命中)
    https://e2e.ti.com/support/microcontrollers/hercules/f/312/t/588269

    问题:知道它是"整个闪存"(如前一个线程中所述)还是"最后使用的扇区"、也许还有"下一个扇区"、这一点非常重要? 我不明白为什么您需要填充"上次使用和下一个"、因为"下一个"扇区应与之后的每个扇区相似(在正常 CPU 中、无需擦除该"下一个"扇区、因为它不是编程/使用的)。 如果"下一个问题"很重要、您可以简单地告诉您原因(我的问题4中的答案是否正确)? (***,另见员额底部)

    3.好的、可能需要一些"手动工作"。
    问题:它是否会自动"填充"上次使用(或编程-不知道其正确的字)扇区、或者您是否需要手动填充"上次使用的扇区"? 示例:我有0x15000长的代码、我是否需要手动从0x15000闪存到0x1FFFF、或者 API 是否自动执行此操作(由于我们的开发还不在该阶段、我甚至没有查看 API)。 自动填充将要求您以某种方式告知 API "我准备好了"、这就是我猜您需要手动填充的原因(现在只需尝试一下需要执行的操作、以防止这种相当烦人的功能在实际产品中弹出)。

    4.我 试图问这个错误的“时间范围”,根据你的回答,我知道它可能是10us,1s,1min,1周,1个月,或者永远不会这样,这只是一个纯粹的运气,什么地址是投机取的?
    问:现在您说代码位置的 ECC 错误位置很重要、甚至可能出现推测错误、推测取取机制是否以某种方式监控实际使用的代码区域并尝试读取这些区域附近的地址?

    ***在上一个线程(https://e2e.ti.com/support/microcontrollers/hercules/f/312/t/588269)中,您说过 FUNC_ERR_ADD 寄存器“如果寄存器值为0x135a98,UNC_ERR_ADD 应该为0x25B53 (0x135a98 >> 3)。”
    重新阅读(多次)寄存器描述后、我倾向于同意您的观点、但继续阅读、因为我设法重现了问题、这表明存在其他问题。

    "总线奇偶校验错误时、该寄存器捕获完整的32位传入地址。 它仅捕获22:3的地址以产生多位 ECC 错误"
    我理解了这一点(在经过最新测试后)、现在讨论的是整个 FUNC_ERR_ADD 寄存器、而不是 FUNC_ERR_ADD 寄存器内部的该字段 UNC_ERR_ADD (猜测寄存器内部不能存在寄存器) 这意味着完全不同、因此基本上会将0-2位屏蔽、使其远离错误地址、而其余位会按原样写入 UNC_ERR_ADD (无移位)。

    问题:您能否验证0x135a98作为整个寄存器值是否确实意味着0x25B53地址发生故障或实际上是0x135a98地址、这是本"我们的调试问题案例"中非常重要的信息、以便能够找到故障的根本原因? 继续阅读并查看我的实验...


    注意:我刚刚尝试重现0x24DBA 长度代码的问题、我擦除闪存、然后对该代码进行编程、一段时间后 SR3 = 0x00000080 (SR1中也有单个位错误)。 现在、FUNC_ERR_ADD 是0x139C10、在您的解释中、/8 = 0x27382 (==将是与代码最后一部分在同一扇区中的区域、但超出了实际代码)。

    在我将代码填充到0x3FFFF (到扇区4的末尾)后、这应该会有所帮助、因为它会将0x27382区域写入... 我仍然收到此推测取指令错误。 因此这不起作用、这意味着0x27382的地址范围不正确。 这是内存窗口视图、证明内存已被填满(使用0xAA 作为填充来将其与擦除状态0xff 隔开)、不知道为什么它在扇区5 (在 IAR 内存查看器中)中的某些0xff 之后开始显示"错误"、擦除后不会被触摸) 而 Jlink 拒绝读取超出该地址的数据,IAR 的内存查看器显示------之后的许多字节,其中一些是0xff 和一些0xFD (调试器是否以某种方式知道该地址无效,ECC 未设置,读取它可能会导致不可纠正的错误?)。 两种查看方法(IAR IDE 和触发器 Jlink.exe 命令行显示的结果相似、不同之处在于 SEGGER 拒绝从 IAR 开始显示'--'的位置读取
    J-Link>mem32 0x3FF80 256
    0003FF80 = AAAAAAAAAA AAAAAAAA AAAAAAAAAAAAAAAA
    0003FF90 = AAAAAAAAAA AAAAAAAA AAAAAAAAAAAAAAAA
    0003FFA0 = AAAAAAAA AAAAAAAA AAAAAAAAAAAAAAAA
    0003FFB0 = AAAAAAAAAA AAAAAAAAAA AAAAAAAAAAAAAAAA
    0003FFC0 = AAAAAAAAAA AAAAAAAAAA AAAAAAAAAAAAAAAA
    0003FFD0 = AAAAAAAA AAAAAAAA AAAAAAAAAAAAAAAAAA
    0003FFE0 = AAAAAAAAAA AAAAAAAAAA AAAAAAAAAAAAAAAA
    0003FFF0 = AAAAAAAA AAAAAAAA AAAAAAAAAAAAAAAA
    00040000 = FFFFFFFF FFFFDFFF

    然后我还填充了"下一个扇区"、因此填充进入0x5FFFF、也不起作用、推测取错误仍然出现(在复位矢量中是的、 我用调试器手动确认之前的 ESM 错误,代码设法进入 main(),我在启动时进行了大量 SafeTI 测试,该测试还检查函数条目中的错误引脚是否已打开,如果 CPU 行为不正常,代码将不会进入 main)....
    J-Link>mem32 0x5FF80 256
    0005FF80 = AAAAAAAAAA AAAAAAAA AAAAAAAAAAAAAAAA
    0005FF90 = AAAAAAAAAA AAAAAAAA AAAAAAAAAAAAAAAA
    0005FFA0 = AAAAAAAA AAAAAAAA AAAAAAAAAAAAAAAA
    0005FFB0 = AAAAAAAAAA AAAAAAAAAA AAAAAAAAAAAAAAAA
    0005FFC0 = AAAAAAAAAA AAAAAAAAAA AAAAAAAAAAAAAAAA
    0005FFD0 = AAAAAAAAAA AAAAAAAAAA AAAAAAAAAAAAAAAA
    0005FFE0 = AAAAAAAAAA AAAAAAAAAA AAAAAAAAAAAAAAAA
    0005FFF0 = AAAAAAAA AAAAAAAA AAAAAAAAAAAAAAAA

    然后我填入0x13FFFF (6位)(并删除了这些挂起的 ESM 错误)、推测取指令错误消失、代码再次按应有的方式运行。

    问题:这意味着 FUNC_ERR_ADD 寄存器 UNC_ERR_ADD 字段存储的违规地址与0x7屏蔽的地址相同、因此在伪代码中、地址存储机制遵循
    F_UNC_ERR_ADD = failed_address 和0x7)、并且错误发生在0x139C10地址范围上、该地址范围是组0中的扇区11?


    问题:根据我的测试、您之前的线程指令看起来是正确的、"整个闪存"应该被填充一次(在生产中)、并且在固件更新中、所有被擦除的扇区必须被填充。 推测取指令从离实际代码位置非常远的地方寻找代码、所以唯一的选择是按照您在前一个线程中最初的建议、实际填充整个芯片至少一次

    电源 很抱歉,长时间开机自检,直到我重现此问题为止:)
    PPS。 关于我们罕见的调试问题、根据这一最新经验、我非常确信这个"偶尔的预取错误会再次出现"-问题必须与全芯片擦除相关(调试器有时会意外擦除闪存、或者我出于某种原因手动擦除闪存 (但我没有理由在调试代码时手动擦除闪存:)即使在不使用 IAR 闪存加载程序的情况下也无法轻松地执行此操作,但当然,我仍然可能已经执行过此操作,特别是因为现在我只能理解至少一种方法来重新处理此操作)... 需要持续关注、我们会再次回来、重点关注我所做的事情。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你(们)好
    我没有详细阅读所有内容、只是我的两个看法:
    -闪存断点可能会破坏 ECC
    -"未使用的闪存":为什么不至少读取一次所有闪存?
    -全芯片擦除:至少如果您使用 J-Link 到闪存(在 C-Spy 选项中禁用闪存下载)、您可以选择擦除闪存的全部或部分部件