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.

[参考译文] TM4C129ENCPDT:带有 SSI 的 UDMA 在发送时似乎会破坏每个32位字的一个位

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/738551/tm4c129encpdt-udma-with-ssi-seems-to-corrupt-one-bit-of-each-32-bit-word-on-transmit

器件型号:TM4C129ENCPDT

我的应用正在与 SPI 闪存芯片通信。 当我在紧凑的优化环路中直接访问 SSI 外设时、代码工作完美。 我已尝试通过将数据传输从直接 SSI 访问更改为 UDMA 来提高性能。 我在直接 SSI 访问中保留了 Flash 存储器命令字节和地址字节(通常为4字节地址)、因此只有较长的 Flash 数据传输由 UDMA 处理。

为了提高效率、我将 UDMA 通道控制设置为 UDMA_SIZE_8 | UDMA_ARB_4。 通道传输为 UDMA_MODE_PING_PONG。 通道属性设置了 UDMA_ATTR_USEBURST、我认为我要小心等待 SSI 忙线取消置位、然后只将 UDMA 大小编程为4个字节的倍数。

症状是我的数据几乎完全正确地传输、但传输过程中的随机点开始出现一个位错误。 在或第5个32位字中、大约22个字节、就像0x00004000正在或写入我的数据流中一样。 该位错误是字对齐的、不是字节对齐的、因此我首先怀疑 uDMA 设置是否正确、因为 SSI 以8位字大小运行。 我尝试短暂地关闭了 USEBURST、但这似乎使事情变得更糟。

请注意、在大多数情况下、我可以让 Flash 存储器读取工作、但有时会被一个32位字移位-所有正确的数据都会出现、但传输过程中有一个字太晚了。 如上所述、这个特定的错误报告发生在闪存存储器写入操作期间。 我已经使用逻辑分析仪确认、当数据写入外部闪存芯片时、线缆上的数据损坏。 因此、当我读回损坏的数据时、它确实与线路上实际发送的数据相匹配。

除了寻求一般性帮助、基于上述问题、我还想知道是否有某种方法可以清除或复位我缺失的 UDMA 外设。 这似乎特别重要、因为访问外部 SPI 闪存涉及单字节命令、地址字节和有望更大的 UDMA 缓冲器传输的混合。

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

    这看起来是 e2e.ti.com/.../738554的重复线程

    今天、我们将回复这个较新的主题、并关闭这个主题。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这是一个非常不同的错误(错误的数据、而不是在错误的位置更正数据)、在不同的条件下发生、并发生在随机偏移而不是可预测的偏移。 但是、如果您可以用一个答案来解决这两个问题、那么我会将这个标记为已解决。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Brian、

    我看到、您的大部分帖子都是相同的、因此我不容易理解这些问题是完全无关的。 我们多次看到重复的帖子、其中第二个帖子刚刚对其进行了"编辑"、这一帖子以这种方式出现、很抱歉我没有注意到这些差异。

    我可以单独处理两个线程、但对于这一个、我需要在评论之前进一步研究。

    在此期间、您需要快速检查您的端点、是否可以确保不会发生堆栈溢出? 有时、数据可能会因此而损坏。 我怀疑您通过我们过去的信函了解您的透彻程度会有这样的问题、但最好核实这种情况不会发生。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Brian、

    您是否在应用中使用深度睡眠模式?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [报价用户="Ralph Jacobi]\n 在此期间、您可以快速检查您的端点、是否可以确保不会发生堆栈溢出? 有时、数据可能会因此而损坏。 如果您通过我们过去的信函了解您的详细程度、我怀疑您是否会遇到这样的问题、但最好验证是否没有发生这种情况。[/引述]

    我让链接器为堆栈分配2KB、我的固件使用的字节似乎小于500字节。

    (我修改了1ms 节拍中断以跟踪最小值和最大 SP 值。 如果有更易于使用的工具跟踪堆栈、请向正确的方向指明我。)

    P.S. 完全不使用睡眠模式、深度模式或其他模式。

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

    您好 Brian、

    我有一种更科学的方法、使用 CCS 存储器浏览器。 下面我要介绍的步骤是在 MSP430上完成的、但也可以通过 TM4C 实现。

    对于 TM4C、请在.map 中查找栈位置、如下所示:

    要测试堆栈溢出、应执行以下步骤:

    1. 在 Debug 文件夹内的.map 文件中标识栈的起始存储器位置

    2. 进入调试模式、但不开始运行代码
    3. 转至“View”(查看)->“Memory Browser”(内存浏览器)
    4. 在输入框中输入堆栈的地址
      1. 在上面的示例中、该地址为0x0000420c (您需要在其前面添加0x!)

    5. 这将向您显示堆栈内容
    6. 接下来、使用已知数据填充堆栈内容:
      1. 转至“Tools”(工具)->“Fill Memory”(填充内存)
      2. 输入起始地址=.map 文件的栈地址
      3. length =栈大小/2 (在我的示例中为500、因此500/2 = 250)–这是因为每个存储器位置存储栈的2个字节
      4. 数据值= 0xAA (或0x55、或其他易于识别的值)

    7. 内存浏览器现在应如下所示:

    8. 由于堆栈已被完全覆盖、因此将导入该堆栈以在运行代码之前恢复初始堆栈设置。 这可以通过以下两种方式之一来实现:
      1. 使用“软重置”
      2. 退出调试模式并重新进入调试模式
        1. 我必须对某些项目执行此操作、但通常软复位会起作用
      3. 正确完成后、存储器浏览器应在栈顶或底端具有非0xAA 字节:

    9. 现在、根据应用程序运行代码足够长的时间
      1. 如果发生溢出、所有输入的数据(我的示例中为0xAA)将不再位于栈中

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

    感谢您的科学方法。 您的技术确认2048个堆栈字节中仅使用480个堆栈字节。 我之前的技术显示了495个字节左右、这表明这两种方法都是相关的。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这些错误中的任何一个都没有取得太大的进展、因此我不想留下这样一个印象、即这个问题已经得到任何解决。