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.

[参考译文] TMDXRM57LHDK:EMAC (LwIP)和串行接口导致数据提取错误

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/570712/tmdxrm57lhdk-emac-lwip-and-serial-interface-cause-a-data-fetch-error

器件型号:TMDXRM57LHDK
主题中讨论的其他器件:HALCOGEN

您好!

我不知道如何解决这个问题。 希望您能给我一些提示。

我正在使用 lwip 1.4.1和不带操作系统的德州仪器 HDK RM57。

我的计划的工作原理:

  • 传感器数据在异步模式下通过串行接口传入
  • 接收完所有数据后、通过 TCP 将其发送到 PC 上的客户端(服务器为 HDK)

问题:

  • 经过一段随机时间(通常大约一小时)后、程序崩溃、出现"数据获取"错误

我注意到的事项:

  • L4、L4_ABT、L4_USR 寄存器指向串行接口的问题(错误地址)。 我知道 L4寄存器指向的任何内容不一定意味着问题在于该指令。 L4寄存器是在调试器或电路板注意到问题时设置的、但问题发生的时间可能是之前的几条指令。 但是、我还注意到、当问题发生时、我在串行接口的接收中断例程中使用的缓冲器(在双缓冲器中)指向允许的存储器区域之外的地址。 这个缓冲器是我的应用的一部分、而不是系统级缓冲器。

我执行的测试:

  • 我将程序在没有 TCP 服务器的情况下运行了一整天。 传感器数据正以异步模式接收并由主循环处理。 程序未崩溃。
  • 我将程序 TCP 服务器一起运行了一整天、使用一个初始化一次且从未更改的静态缓冲区。 连接到传感器的串行接口未激活。 程序未崩溃。
  • 我将程序 TCP 服务器一起运行了4个小时、并使用双静态缓冲区、该缓冲区每60ms 使用虚拟值更新一次。 连接到传感器的串行接口未激活。 程序未崩溃。 (我这样做是为了测试我的复制功能是否有故障)。
  • 我尝试同时运行 TCP 服务器和传感器串行接口、但没有将串行缓冲区复制到 TCP 缓冲区。 TCP 服务器在一个测试中发送了从未更改的单个静态缓冲区、在另一个测试中发送了双静态缓冲区(每60ms 使用虚拟值更新一次)。  在这两个测试中、程序都崩溃

仅当 TCP 和异步串行通信同时处于活动状态时、才会出现此问题。

(可能相关) PC 上的 TCP 客户端实际上是一个显示我的传感器数据的 GUI。 连接后、传感器数据的"图像"每~2秒"跳跃"一次。 数据错误。 我认为这可能是串行缓冲区到 TCP 缓冲区的复制错误。 但是、在电路板通过 TCP 发送数据之前、它会对数据进行处理并检查数据是否错误或损坏。 如果是、它会发送多个错误信号(LED 和串行调试数据)。 当 GUI 中的图像跳转时、我还会从板上获取错误信号(这意味着数据实际上是错误的)。 当服务器未连接到 GUI 时、我会从电路板上获得这些错误信号。

这似乎是 TCP 服务器以某种方式影响串行接口(或同一存储器区域?)的中断例程 (并以某种方式破坏其缓冲器?)。  

如何检查谁在回收内存? 如何检查 EMAC 驱动程序和串行接口处理程序? 如何检查"端口"是否正在重入不可重入的函数?  "port"是 LwIP 对器件和 LwIP API 之间某种接口的调用。 我从 德州仪器教程获得的端口

我在嵌入式编程方面没有太多经验。 我不知道如何对此进行更深入的调查。 我还可以检查什么以及如何检查? 我的端口可能不正确? 是否有人端口连接到我可以比较的 HDK RM57?  

如果您理解我对问题的描述、您认为原因可能是什么? 如果您不理解、请告诉我们、以便我可以更好地解释。

非常感谢您的帮助。

此致、

Julio

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

    感谢您对问题的详细解释。 目前、我仍在努力了解这一问题、并考虑寻找潜在问题的可能位置。 如果您不介意、我想稍微思考一下这个问题、然后在我有时间调查和考虑需要关注的领域后、再与您讨论这个问题。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、Chuck、

    感谢您花时间帮助我。

    我只想指出昨天发生的一些新情况。

    简介:

    我提到过在完全接收到传感器数据后、我会对其进行处理。 作为处理的一次性初始化步骤、我将类型为 float、float []和 float [](以及其他)的一些全局变量设置为一些值。 每次需要处理数据时都会使用此变量。

    问题:

    我尝试获取错误以检查某些寄存器、但昨天未出现数据获取错误、但"新"问题可能与此相关。

    服务器停止发送数据(tcp_write 返回-11、即 NO_CONNECTION)。 串行接口保持正常工作。 我在初始化中设置的全局变量具有损坏的数据。 他们的价值观发生了变化。

    这种情况怎么会发生?

    如果问题相关、这可能有助于您了解问题。

    谢谢、此致、

    Julio

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

    可能会发生几个潜在问题。

    首先、您可能会用尽帧/消息缓冲器/帧/消息缓冲器的空间。 我不是 LWIP 应用演示的专家、但我的理解是、它在存储帧/消息信息的位置上进行了一些有限的内存分配。 如果超过此空间、则可能会损坏 SCI 缓冲区以及全局变量。 考虑到您最初报告的问题、您将开始定期获取错误数据、这似乎是最可能的。 您似乎在使用所有分配的空间、直到最后一个空间是指向随机数据的错误指针、作为消息缓冲器、其中消息缓冲器指针已损坏或溢出了分配的空间。

    不太可能的情况是、您运行的堆栈会导致 SRAM 数据损坏。 但这似乎不太可能、因为至少部分应用程序仍在继续运行。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、Chuck、

    感谢你的帮助。

    是否可以在存储器映射中增加堆栈段的大小? 现在它大约为5k、一个传感器数据缓冲器大约为2.2k。 如果串行中断处于活动状态、并且 TCP 接口同时发送、则堆栈必须保存两个接口的上下文以及主循环的正常上下文、对吧? 可能是堆栈不够大、所有内容都损坏了?

    谢谢、此致、

    Julio

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

    你好、Chuck、  

    我认为我找到了数据提取错误的原因。 我写入的数据多于我应该写入串行缓冲区的数据。 我没有测试/检查要写入的数据量。 我运行程序大约2小时、但未发生数据获取错误。 我将运行一整晚、看看该程序明天是否仍在运行。

    我认为会发生以下情况:

    • 答: 程序从串行缓冲区读取即将到来的电报的"大小"。 我直接使用该值而不是将其作为串行接口需要等待的数据量进行测试。
    • B:当 TCP 接口发送数据时、它会中断串行接口例程。 有时需要很长时间、当它返回到串行中断时、内部串行缓冲器中的数据会更新(损坏?)。  

    如果在读取下一条消息的"大小"时发生 B、则该值可能大于实际的缓冲区大小。 由于我执行了 A 操作、因此我生成了数据提取错误。 现在、我只需检查 该值是否在缓冲器限制范围内、它似乎起作用。

    我现在有另一个问题:(是否应该为此打开一个新的线程?)

    当 TCP 服务器处于活动状态时、串行缓冲区仍会"损坏"、因为在读取串行消息的任何部分时可能会出现 B。

    我尝试通过在 Halcogen 中将串行中断处理程序从 IRQ 更改为 FIQ 来提高串行中断的优先级。

    不幸的是、这不起作用。 启动后几秒钟、程序崩溃、并出现另一个数据获取错误。

    我缺少什么?

    此致、

    Julio

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

    很高兴听到您能够超越数据中止问题、现在我们将讨论更多与实施相关的问题。 有关中断优先级的更多信息、请参阅此主题: e2e.ti.com/.../59793

    该主题详细讨论了优先级的工作方式。 您可以在配置中断通道分配以及更改为 FIQ 时调整优先级。 此外、您是否在进入 SCI 中断后重新启用中断? 如果是这样、请等到服务路由结束再启用、以使 EMAC 中断不被嵌套(只要 EMAC 中断也是 IRQ)。 COLD 还使用一个标志来检查进入上述状态 B 时 SCI 中断是否中断。 即、如果 SCI Rx 正在进行中、请根据标志的状态在完成 EMAC Tx 之前完成它。 Tx 需要成为基于中断的函数是否有原因? 即、这是否与 PC 发出的传输请求有关? 如果没有令人信服的理由让此中断成为基础、您可以执行轮询实现、或者冷启动系统事件、其中仅在传感器中有完整数据时通过 TCP 进行传输。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你好、Chuck、

    我希望你还在附近:-)

    根据您上一篇文章中的链接、我关于 TCP TX 例程中断串行 Rx 例程的理论是错误的。 它表示另一个 IRQ (即使是更高优先级的 IRQ)不能中断已经在进行的中断例程。

    我现在的新理论是、串行中断在 EMAC 例程被处理时被触发、因此串行接口必须等待。 在等待时、新数据将到达、缓冲区将被覆盖或新数据丢失。 这对您来说有道理吗?

    从参考手册中、我知道有两个串行接收缓冲器:SCIRXSHF 和 SCIRD。 "第一个帧会获取所有的传入数据、当完全接收到帧时、数据会传输到第二个帧。 当该传输发生时、RXRDY 标志置位、并产生接收中断"。

    如果在程序处于 TCP 中断中时生成串行中断、在 SCIRXSHF 上新到达的数据会发生什么情况? 我想、SCIRXSHF 会不断获取数据以避免丢失某些数据、对吧? 这意味着将有多个帧到达。 即使最后一个中断尚未被处理、这个新数据是否会被复制到 SCIRD (因为已接收到一个完整的帧)? 如果是这种情况、我可以采取哪些措施来避免数据丢失?

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

    如果您处于 TCP 中断的中间位置、当接收到数据并且 SCI Rx 中断因此被抑制/延迟时、数据仍将从 SCIRXSHF 寄存器传输到 SCIRD 寄存器(两级缓冲器) 但是、如果您在 SCIRXSHF 接收到另一条消息之前无法访问它、SCIRD 中的数据将被过度写入并丢失、从而导致溢出错误(如果尚未启用此错误、您可以启用此错误。 您至少可以检查状态寄存器中的错误标志)。 但是、我认为您正在参考 SCI 的多缓冲模式、其中有8个缓冲区、用于在收到数据时从 SCIRXSHF 寄存器中移动数据。 这里的技巧是能够设置接收/预期的字节数、以设置帧/缓冲区深度的长度。

    这里的真正解决方案是尽可能少地在中断中花费时间、并仅使用中断将数据转储到接收到的数据结构中。 用于 TCP 数据或 SCI 数据。 即、进入 ISR、将数据复制到 RAM 缓冲区以供后续处理、重新启用中断并退出。 然后、所有处理都可以在应用层中进行。 这仍然不会阻止中断延迟、但希望它允许您在收到另一条消息之前捕获数据。 实际上、您只能通过启用 TCP 中断内部中断来避免这种情况、这样它就可以允许来自 SCI 的嵌套中断、从而可以捕获数据并复制到 RAM。 TCP 传输完成后、您可以将 SCI 数据移动到其所属位置并调整缓冲区。 (理想情况下、您将有一个基于 RAM 的环形缓冲器(FIFO)用于 SCI 接收数据、其中中断仅将数据放置在环形缓冲器中、而 SCI 数据在非中断级别进行处理。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、Chuck、

    再次感谢您的帮助。 我真的很感谢。

    [引用用户="Chuck Davenport"]

    如果您处于 TCP 中断的中间位置、当接收到数据并且 SCI Rx 中断因此被抑制/延迟时、数据仍将从 SCIRXSHF 寄存器传输到 SCIRD 寄存器(两级缓冲器) 但是、如果您在 SCIRXSHF 接收到另一条消息之前无法访问它、SCIRD 中的数据将被过度写入并丢失、从而导致溢出错误(如果尚未启用此错误、您可以启用此错误。 您至少可以检查状态寄存器中的错误标志)。 但是、我认为您正在参考 SCI 的多缓冲模式、其中有8个缓冲区、用于在收到数据时从 SCIRXSHF 寄存器中移动数据。 这里的技巧是能够设置接收/预期的字节数、以设置帧/缓冲区深度的长度。

    [/报价]

    我在启用时能够看到溢出错误。 那么、至少我现在知道发生了什么。 您刚才提到我使用的是多缓冲模式。 我不确定。 在"技术参考手册"中、我只 能看到将 SCI/LIN 设置为多缓冲模式的选项。 我还能对 SCI3执行该操作吗?  我已经在 SCI 接收函数上设置预期的数据量、并且在接收到该数据量后获得 sciNotification。 但是、我认为 sci3HighLevelInterrupt 在接收到每个帧后被调用。  

    我进行了以下测试:

    • 传感器需要67ms 的时间来发送数据、然后暂停10ms、并在接下来的67ms 开始发送下一个串行电报。
    • 我处理完整数据并通过 TCP 发送(原始)。 这需要大约6-10ms、这是新串行数据到达时、可能是发生错误的原因、因为我需要在电报的前4个字节中执行一些同步检查、并在接下来的2个字节中检查电报的大小。 这意味着我一次读取一个字节的前6个字节(sciReceive (UART3、1、buffer))、这增加了 TCP 阻塞接收流的几率。
    • 测试是在我完成所有这些检查并完成'sciReceive (UART3、Size、buffer)'后通过 TCP 发送数据

    现在、我会降低溢出误差的频率。 但是、我希望不再看到它。 这使我相信我不使用多缓冲模式。 如果我添加另一个 TCP 连接、则溢出错误会再次频繁发生。

    [引用用户="Chuck Davenport"]
    这里的真正解决方案是尽可能少地在中断中花费时间、并仅使用中断将数据转储到接收到的数据结构中。 用于 TCP 数据或 SCI 数据。 即、进入 ISR、将数据复制到 RAM 缓冲区以供后续处理、重新启用中断并退出。 然后、所有处理都可以在应用层中进行。 这仍然不会阻止中断延迟、但希望它允许您在收到另一条消息之前捕获数据。 实际上、您只能通过启用 TCP 中断内部中断来避免这种情况、这样它就可以允许来自 SCI 的嵌套中断、从而可以捕获数据并复制到 RAM。 TCP 传输完成后、您可以将 SCI 数据移动到其所属位置并调整缓冲区。 (理想情况下、您将有一个基于 RAM 的环形缓冲器(FIFO)用于 SCI 接收数据、其中中断仅将数据放置在环形缓冲器中、而 SCI 数据在非中断级别进行处理。

    [/报价]
    我不知道 LwIP 端口(来自德州仪器(TI)教程)在 TX 中断中的具体作用。 我会假设它会尽量减少时间、这也是我所做的。 我尝试使用嵌套 IRQ 的想法、以便串行接口能够中断 TCP 接口。 但电路板会崩溃。 我还尝试将 SCI 设置为与 FIQ 配合使用、但结果相同。 我想端口的 TCP 中断没有被设计成被中断。
    使用 SCI3与 DMA 会怎么样? 这是否有助于将所有传入数据发送到 DMA 缓冲区、同时避免从 TCP 进行阻止?
    此致、
    Julio
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Julio Cesar Aguilar Zerpa"]

    再次感谢您的帮助。 我真的很感谢。

    卡盘 Davenport

    如果您处于 TCP 中断的中间位置、当接收到数据并且 SCI Rx 中断因此被抑制/延迟时、数据仍将从 SCIRXSHF 寄存器传输到 SCIRD 寄存器(两级缓冲器) 但是、如果您在 SCIRXSHF 接收到另一条消息之前无法访问它、SCIRD 中的数据将被过度写入并丢失、从而导致溢出错误(如果尚未启用此错误、您可以启用此错误。 您至少可以检查状态寄存器中的错误标志)。 但是、我认为您正在参考 SCI 的多缓冲模式、其中有8个缓冲区、用于在收到数据时从 SCIRXSHF 寄存器中移动数据。 这里的技巧是能够设置接收/预期的字节数、以设置帧/缓冲区深度的长度。

    我进行了以下测试:

    • 传感器需要67ms 的时间来发送数据、然后暂停10ms、并在接下来的67ms 开始发送下一个串行电报。
    • 我处理完整数据并通过 TCP 发送(原始)。 这需要大约6-10ms、这是新串行数据到达时、可能是发生错误的原因、因为我需要在电报的前4个字节中执行一些同步检查、并在接下来的2个字节中检查电报的大小。 这意味着我一次读取一个字节的前6个字节(sciReceive (UART3、1、buffer))、这增加了 TCP 阻塞接收流的几率。
    • 测试是在我完成所有这些检查并完成'sciReceive (UART3、Size、buffer)'后通过 TCP 发送数据

    现在、我会降低溢出误差的频率。 但是、我希望不再看到它。 这使我相信我不使用多缓冲模式。 如果我添加另一个 TCP 连接、则溢出错误会再次频繁发生。

    Chuck Davenport --> SCI3是标准 SCI,不具有缓冲模式。 它只在 SCI/LIN 实例化上可用。 如果器件有 DMA、您可能会考虑使用 DMA。 这样、DMA 就可以将接收到的数据传输到可以独立于接收操作的缓冲区位置。 然后、您可以根据需要/在时间允许时对缓冲区进行操作、而无需担心 TCP 操作中断。

    卡盘 Davenport

    这里的真正解决方案是尽可能少地在中断中花费时间、并仅使用中断将数据转储到接收到的数据结构中。 用于 TCP 数据或 SCI 数据。 即、进入 ISR、将数据复制到 RAM 缓冲区以供后续处理、重新启用中断并退出。 然后、所有处理都可以在应用层中进行。 这仍然不会阻止中断延迟、但希望它允许您在收到另一条消息之前捕获数据。 实际上、您只能通过启用 TCP 中断内部中断来避免这种情况、这样它就可以允许来自 SCI 的嵌套中断、从而可以捕获数据并复制到 RAM。 TCP 传输完成后、您可以将 SCI 数据移动到其所属位置并调整缓冲区。 (理想情况下、您将有一个基于 RAM 的环形缓冲器(FIFO)用于 SCI 接收数据、其中中断仅将数据放置在环形缓冲器中、而 SCI 数据在非中断级别进行处理。
    我不知道 LwIP 端口(来自德州仪器(TI)教程)在 TX 中断中的具体作用。 我会假设它会尽量减少时间、这也是我所做的。 我尝试使用嵌套 IRQ 的想法、以便串行接口能够中断 TCP 接口。 但电路板会崩溃。 我还尝试将 SCI 设置为与 FIQ 配合使用、但结果相同。 我想端口的 TCP 中断没有被设计成被中断。
    使用 SCI3与 DMA 会怎么样? 这是否有助于将所有传入数据发送到 DMA 缓冲区、同时避免从 TCP 进行阻止?
    CD-->我之前也有过同样的想法。 我建议尝试一下。 HalCoGen 的示例中有一个 SCI DMA 示例、效果良好。 您必须手动启动第一次通信、我认为这样才能启动工作。
    此致、
    Julio

    [/报价]

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

    非常感谢您的帮助。 我还找到了 sci DMA 示例、但无法使其正常工作。 它在环回模式下打印失败、或在环回为零时卡在 while 环路中。

    我创建了一个新项目、在 Halcogen 中启用了 sci3和 sci4、未更改配置(禁用了所有 sci 中断、两者中的帧参数相同)、并生成了代码。

    我是否缺少一些配置步骤?

    另一件事是:如果 DMA 被用来接收数据、则需要执行一个虚拟 DMA 传输来更新 CTCOUNT、从而允许再次触发 DMA 接收请求。 因此、我想、我将需要它。

    如果我的虚拟发送和接收缓冲器在我的应用中被定义(uint8 dummy_array[2]、其中 idx 0将是 TX Addr、idx 1是 Rx Addr)、那么应该在'dmaReqAssign (dma_chx、dma_req_line)'中使用的 dummy_req_line 应该是什么?

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

    原来的问题已得到解答。 我要将问题设置为答案、并打开一个包含 DMA 问题的新线程。

    如果您或同事能帮我解决问题、那就太棒了。 这是指向另一个线程的链接: e2e.ti.com/.../579707

    非常感谢。
    Julio