使用 DMA 的 UART - BLE Stack 1.4.0的 Tx 吞吐量问题
背景
我们的系统上有一个运行 BLE Stack 1.4.0的嵌入式 CC2540、其主机处理器可通过 UART 或 USB 与 CC2540通信、具体取决于主机处理器的硬件是支持 UART 还是 USB。 此端口称为管理端口。 管理端口始终以115、200波特运行。
无论是采用 UART 配置还是 USB 配置、CC2540都能积极扫描环境中是否有其他 BLE 器件以及它接收到的每个 BLE 广播或扫描响应、 以一种大约50字节左右的众所周知的格式对其进行封装、并通过115200波特串行链路将其发送给主机处理器。
每20秒、两个不同的管理数据包(称为第一个管理数据包和第二个管理数据包)将通过相同的115、200波特链路背对背发送到主机处理器。
问题说明
据观察、在采用 UART 配置的 BLE 器件上、我们漏掉了大量这些管理数据包。 但是、在 USB 配置中、我们会接收每个管理数据包。 下表对此进行了说明:
第一个管理包
|
配置 |
第一个管理数据包的预期数量 |
首次管理数据包的实际数量 |
%age 丢失第一管理包 |
|
USB |
3011. |
2060. |
31.5% |
|
UART |
3012. |
3012. |
0% |
第二个管理包
|
配置 |
第二管理数据包的预期数量 |
第二管理数据包的实际数量 |
%age 丢失第一管理包 |
|
USB |
3011. |
618- |
79.48% |
|
UART |
3012. |
3012. |
0% |
在浏览 HAL UART 代码和 Tx 驱动程序时,特别是在_hal_UART_dma.c 中,看到 Tx 例程 HalUARTWriteDMA()使用 ISR 而不是 DMA,这令人惊讶,也令人不安。 显然、在该代码的上下文中 DMA 存在"问题"。 以下是代码的几个片段:
hal_UART_dma.c 的第8行:
已知缺陷是当启用流控制时、函数 HalUARTPollTxTrigDMA ()可以提前调用 HAL_DMA_MAN_TRIGGER (HAL_DMA_CH_TX)和 clober、即一个 txBuf[]块传输的最后一个字节和下一个 txBuf[]块传输的第一个字节。 此外、当使用 DMA 进行 Tx 和硬件流控制时、Tx 可能会在重用和/或同步重无线电流量期间永久停止。
hal_UART_dma.c 的第199行
//对于上面 moduel 说明中描述的已知缺陷,最好由 ISR vice 驱动 Tx
// DMA,除非未使用 H/W 流控制,并且 Tx 上的全吞吐量是绝对必要的。
我还检查了在 BLE Stack 1.4.0和 BLE Stack 1.4.1或 BLE Stack 1.4.2之间的 HalUARTWriteDMA()中的更改、但未找到任何内容。
代码中关于不使用 DMA 进行 Tx 声音严重的警告。 我们更喜欢使用 DMA。 但是、上面的一个注释令人不安、"此外、当使用 DMA 进行 Tx 和硬件流控制时、Tx 在重用和/或同时繁重的无线电流量期间可能会永久停机。"
以下是我的问题:
- 我们不在硬件配置中使用流控制、因此上述消息是否适用于我们的设置?
- 当管理端口通过 USB 运行时、以115、200波特运行、我们不会看到任何丢弃的数据包。 当管理端口是 ISR 处理的 UART 端口时、以115、200波特运行、我们可以看到几乎有32%的第一管理端口和80%的第二管理数据包被丢弃。 ISR 处理的 UART 端口的预期吞吐量是多少?
- 我通过更改以下行将端口配置更改为使用 DMA 而不是 ISR:
#define HAL_UART_TX_BY_ISR 0
现在、当管理端口是作为 DMA 处理的 UART 端口时、我们看到管理数据包减少了10%。 为什么这种行为与 USB 端口不等效、因为从理论上讲、DMA 应该能够以115、200波特运行、这与 USB 非常相似?
并将 DMA Tx 缓冲器增加为256、而不是128。 - 请记住、我们不使用流控制、如果我转向使用 DMA、Tx 可能会永久停止?
- 使用 DMA 时、我能否检测到一个挂起的 Tx 并将 UART 复位以恢复正常运行?
- 底线是、如何使 UART 以115、200波特运行?
我非常感谢你在这一问题上的帮助。
此致、
KK