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.

[参考译文] TMS320F28388S:优化 SCI-A 通信(多达 70 字节)以减少 CPU 开销

Guru**** 2794765 points

Other Parts Discussed in Thread: TMS320F28388S, C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1596744/tms320f28388s-optimizing-sci-a-communication-up-to-70-bytes-to-reduce-cpu-overhead

器件型号: TMS320F28388S
主题: C2000WARE 中讨论的其他器件

您好:

我正在使用 TMS320F28388S 微控制器模块上的 SCI-A 模块开发一个通信层。 我们处理一个数据帧可达的自定义串行协议  70 字节 。 由于高中断频率和上下文切换、我们看到了显著的 CPU 开销。

当前实施和问题:

  • RX 设置: SCI-A RX FIFO 配置为以 A 的频率触发中断 单字电平 (Rx FIFO = 1)。

  • RX 逻辑: RX ISR 使用SCI_readCharNonBlocking()并对其进行处理来读取单个字符。

  • TX 逻辑: TX ISR 轮询 TX FIFO 状态、并使用一次写入一个字节SCI_writeCharNonBlocking()

  • 问题: 对于 70 字节帧、恒定中断服务会显著影响系统的实时控制环路。

所需目标:使用 DMA 消除 CPU 开销

我想将整个 70 字节传输过程卸载到 DMA 控制器。

我的假设和验证请求:

  1. Rx DMA 触发条件约束: 根据我器件的 TRM、我假设是 SCI-A RX FIFO 级别 不可用作直接硬件外设触发源 DMA 模块相同。 这意味着标准的 DMA 块传输(仅在一个完整帧后触发一次)不可行。 此假设是否适用于我的器件、或者是否有无文档记载的方法将 SCI RX 状态(例如电平阈值或空闲线)配置为 DMA 触发器?

  2. TX DMA 解决方案: 我认为 SCI TX 空状态是一种可行的 DMA 触发器。 将 DMA 从 RAM 发送 70 字节到 SCI TX 寄存器并使用 TX FIFO 作为触发器、建议的最低开销方法是什么?

  3. 替代 RX 解决方案(如果 DMA 不可行): 鉴于这些限制、RX 侧是否有任何低开销方法?

    • 增加 RX FIFO 中断级别(例如,增加到 RX FIFO = 16)是否可以显著减少开销?

    • 是否有推荐的外设到外设触发机制来模拟 SCI RX 的 DMA 触发?

如果能就尽可能提高高频、多字节 SCI 通信的传输效率提供任何指导、将不胜感激。

谢谢您、
Ninad Lomte

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

    嗨、Ninad、

    遗憾的是、正如您提到的、SCI 模块具有 DMA 访问权限。 它不能用于触发 DMA、DMA 也不能访问其寄存器。

    然而、对于 F2838x 器件、有一个不同的支持 UART 的模块 — 仅称为 UART、可从 CM 内核访问、该模块确实具有 DMA 访问权限。 以下 SDK 路径中有一个 UART/DMA 示例、我建议使用作为起点:[C2000ware install]/driverlib/f2838x/examples/cm/uart/uart_ex2_loopback_udma. 您可以使用 IPC 在 C28x 和 CM 内核之间进行通信、请在此处参阅示例: [C2000ware INSTALL]/driverlib/f2838x/examples/c28x_cm/ipc/ip_ex1_basic_XX.

    另一个修复方法确实是增加 FIFO 级别。 F2838x 接收的数据量是否始终固定为 70 字节? 如果是、您可以将 FIFO 级别设置为 10/16、并每个 ISR 读取 10 个字节、从而将 ISR 数量减少 10 倍。 或者、您可以将 RX FIFO 级别设置为 16/16、在每个 ISR 中读取 16 个字节、然后在主循环中读取剩余的 6 个字节。  

    此致、

    Delaney

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

    尊敬的 Delaney:

    感谢您的答复! 我一定会研究从 CM 内核使用 UART 模块和使用 DMA 访问的可行性。
    为了回答您有关帧大小的问题、帧大小不是固定的 70 字节。 我们目前正在开发一种自定义协议、其中帧大小会发生变化、帧的最大长度可高达 70 字节。


    1.根据协议,我们在帧的开始和结束时使用了分隔符。
    2.我们为 SCI RX ISR 使用了 RX1 FIFO 中断级别、因此我们在 ISR 中运行一个状态机、该状态机一次读取单个字符、并在 没有复杂逻辑的情况下将分隔符与主有效载荷分开。
    3.现在根据您的建议,也许使用的 FIFO 水平 10/16,这将有助于我们减少 CPU 开销,但我们将需要将数据存储到一个临时缓冲区,我的状态机将不得不逐一处理这些 10/16 字节,以正确识别序列边界。


    鉴于必须维护这种逐字节定界符状态机、对于具有内部分隔符的协议、从 RX1 迁移到 RX16/RX10 时、建议采取什么做法?

    1. 是否只需增加 FIFO 深度 (RX16) 并将我们的整个逐字节状态机逻辑移动到 ISR 内的循环即可推荐的方法? (然后,我们将依靠主线代码中的 CRC 校验来处理任何剩余的模糊性)。

    2. 或者、是否有一种更简单的、受库支持的方法来在固定级别 FIFO 上处理这种流状态分析、而不会使 ISR 明显变得复杂化?

    再次感谢您的原始回复、以及您关于切换到不同 RX FIFO 级别的建议、我们将非常感谢您的解析安全性!

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

    嗨、Ninad、

    我会推荐:

    1.使用 #pragma INTERRUPT (SCI_xxxxxx、HPI) 减少 ISR 延迟;
    2.将 ISR 移至 RAM
    3.如果不在 SCI 中断中使用 VCU、设置-isr_save_vcu_regs=off 以进一步降低 ISR 延迟(在文件级)
    4.最大限度地优化 ISR(借助分析生成的汇编代码)

    您有什么波特率?

    此致、
    Andy

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

    嗨、Ninand、

    为了提高 RX FIFO 级别、是的、需要使用较大的缓冲区来存储多个字节。 对于时间关键型代码、RX ISR 通常只是将该数据移到缓冲区、然后在主循环中完成数据的后处理。 这还需要一个 state 变量来确保 ISR 操作和主循环操作是同步的(我们不想在主循环处理之前覆盖 ISR 中的缓冲区,反之亦然)。 如果您的逐字节状态机逻辑当前位于后台循环中、建议将其保留在后台循环中。 您只需修改逻辑、以便一次从缓冲区读取一个、而不是单个全局变量。  

    此致、

    Delaney

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

    尊敬的 Andy:

    感谢您的答复。 我会考虑你的建议并加以研究。 我们当前的波特率为 57600。


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

    尊敬的 Delaney:

    感谢您的答复。 在我们的代码中、ISR 正在处理状态机和逐字节处理任务、仅当使用标志变量将整个响应解析到缓冲区中以同步 ISR 和主循环时、才会实现主循环。 我认为更改主代码逻辑可能很复杂、但我会考虑您的建议!  

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

    您好、

    请注意,由于假日季,回复可能会有一些延迟。  

    此致、
    Aishwarya

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

    嗨、Ninad、

    听起来不错、如果您对我的建议有任何其他问题、请告诉我。  

    对于 RX FIFO 级别、如果字节总数不是固定为 70、那么是否有一种方法可以根据自定义协议了解接收到前几个字节后的帧长度? 例如、如果协议中的每个帧都以一个起始字节开始、然后是一个命令字节、我们根据接收到的命令来知道完整的帧长度。 在这种情况下、FIFO 级别可以初始化为 2/16、并且可以在接收到每个命令字节后根据命令字节的内容进行调整。

    此致、

    Delaney