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.

[参考译文] TMDSEMU110-U:XDS110 USB UART以高波特率闪存

Guru**** 2535360 points
Other Parts Discussed in Thread: UNIFLASH

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1087696/tmdsemu110-u-xds110-usb-uart-is-bursty-at-high-baud-rates

部件号:TMDSEMU110-U
主题中讨论的其他部分:UNIFLAASH

我之前在蓝牙论坛上报告过此问题,因为我一直在与CC2652合作,但实际上我没有找到解决方案。 我的问题与XDS110调试器有关,与CC2652无关。 在此处查看我上一篇文章: https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/100.923万/launchxl-cc26x2r1-xds110-uart-is-bursty-and-very-high-latency-under-certain-conditions

我一直在使用带有内置XDS110调试器的Launchpad板在延迟敏感型应用程序中进行开发,因此需要为USB UART连接单独的FTDI电缆以获得可接受的延迟是不方便的。 在23.04万及更高的波特率下,XDS110似乎在发送到USB主机之前通过UART收集数据块,在某些情况下,USB主机可能需要等待数百毫秒才能发送UART数据。 在中等数据吞吐量级别(未使UART饱和,但仍相当定期地发送数据)中,这种模糊性/延迟问题最为明显。 我在之前链接的E2E帖子中给出的示例代码非常适合演示此类情况,每15毫秒发送大约16字节的数据。 我所做的延时测试Python脚本(在链接的帖子中)清楚地显示了模糊性,我仍然可以在Windows,Mac和0.19 上的最新XDS110固件(XDS110固件)(3.0 .)上重现此问题。

作为临时黑客攻击,为了避免使用FTDI电缆,我已将应用程序中的波特率降低到23.0399万,因为这是XDS110 USB UART不会发生突发的最高波特率。 但是,在某些情况下,我的应用程序可以在这个波特率下使UART吞吐量饱和,因此我以前使用的是更快的波特率。

在这种情况下,您能否向XDS110开发人员提交票据,以改善USB UART桥接器的延迟? 此延迟问题还会影响SmartRF Sniffer 2软件,该软件在3M波特的开发板上使用XDS110 USB UART。

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

    你好,Sultan,

    很遗憾听到最后一条E2E线程未能满足您的期望。  我已联系调试器开发团队,他们正在进一步调查此问题。  请让他们有时间熟悉所描述的行为并找出根本原因。

    此致,
    Ryan

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

    谢谢,非常感谢。

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

    发展小组的答复如下:

    有一个循环从UART读取,直到没有其他数据存在,并且在将数据写入USB之前。 一种可能性是该环路中可能有足够的代码,在高波特率下TIVA内核无法保持运行 ,因此无法通过USB传输数据。  但是还有其他的可能性,如果没有更专门的调试工作,我们真的不会知道。 由于此用例有可行的解决方法,因此未将进一步调查和确定此行为的优先级放在更高的优先级。

    此致,
    Ryan

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

    好的。 如果团队有一天能对此进行进一步调查,那将是很好的,尽管我理解这不是一个高度优先事项。 23.04万波特率仅为每秒28千字节,这对于120 MHz Cortex M4来说应该非常容易处理。 此问题在23.04万波特时突然出现(即设置23.0399万波特可避免此问题)对我也很可疑。 在此期间,我将继续使用FTDI适配器,我可能会考虑为具有更好性能的XDS110 MCU (TM4C129)编写我自己的最小(仅USB-UART)固件。

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

    通过进一步调查和检查XDS110固件,我发现对于23.04万及更高的波特率,它使用DMA通过UART接收数据,而不是CPU从UART中断上的FIFO提取数据。 基于DMA的UART实现一定存在导致延迟的错误。 我正在进一步调查,如果/当我发现延迟问题的根本原因时,我将更新此线程。 我希望我能找到一个XDS110固件二进制修补程序来解决这个问题,然后我会分享我解决这个问题的方法,以便您将它传递给XDS110固件开发团队。

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

    在进一步的调查中,我发现在DMA UART模式(用于23.04万波特及更高)中,XDS110固件设置的DMA传输大小等于波特率除以2000,最大可达1016字节。 例如,在23.04万波特时,DMA传输大小为23.04万 / 2000=115字节。

    问题在于,它似乎是在等待此DMA缓冲区被填充后才将数据发送到主机,而不是在准备就绪后立即将数据发送到主机。 例如,在我之前给出的示例代码中,我每15毫秒发送16个字节,因此需要7或8次迭代(105或120毫秒)来填充DMA缓冲区。 如果您将我的调查结果转交给开发团队,我将不胜感激。

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

    作为临时解决方法,我修改了XDS110固件,使其仅对波特率>= 0x20万 (209.7152万)波特使用UART DMA,而不是>=23.04万波特。

    对于XDS110固件版本3.0 .0.19 (随Uniflash 7.1 .0附带),我在十六进制编辑器中修改了firmware.3.0 .0.19 .bin文件(位于deskdb/content/TICalliAgent/OSX/CS_base/common/uscif/xds110)。 我将固件中偏移0x908 (2312)后的两个字节从61 3F更改为00 1F。 然后,我使用xdsdfu刷新了新的修改固件。 TM4C129x微控制器在120 MHz下运行的速度足以在FIFO模式下处理2M波特。

    为了参考,此更改所影响的函数类似于以下内容(猜测/组成函数和变量名称):

    void uart_interrupt_setup(int cdc_index)
    {
      USBCDC_Config *cdc_conf = &cdc_configs[cdc_index];
    
      UARTIntClear(cdc_conf->uart_base, UARTIntStatus(cdc_conf->uart_base, 0));
      UARTIntEnable(cdc_conf->uart_base, 0x7E0);
      if ( cdc_conf->baudRate >= 230400 )
      {
        cdc_conf->uart_dma_enabled = 1;
        uart_dma_setup(cdc_index);
      }
      else
      {
        cdc_conf->uart_dma_enabled = 0;
        cdc_conf->field_40 = 0;
        IntRegister(cdc_conf->uart_interrupt_number, cdc_conf->uart_fifo_interrupt_handler);
        UARTIntEnable(cdc_conf->uart_base, 16);
        IntEnable(cdc_conf->uart_interrupt_number);
        UARTFIFOEnable(cdc_conf->uart_base);
        UARTEnable(cdc_conf->uart_base);
      }
    }

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

    作为另一个跟进,在2M波特率下使用FIFO模式最有效,并修复了我的延迟问题,但它有时会丢失数据(我猜是因为XDS110固件中的其他ISR优先运行且运行缓慢)。 但是,波特率高达0x9万 (58.9824万)波特率的FIFO模式似乎是可靠的,不会丢失数据。 要将修补程序限制为可靠的波特率,请将我提到的两个字节替换为十六进制10 2F,而不是00 1F。

    为了正确处理较高的波特率,需要对基于DMA的操作进行修复,以触发收到的数据在UART接收超时中断(或定期)后通过USB发送。

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

    感谢您分享您的调查结果,我会将此信息传递给 调试器开发团队。

    此致,
    Ryan

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

    还有一个后续操作:即使在DMA模式下,偶尔(定期)丢失高波特率的UART数据也似乎发生了。 它似乎与我对FIFO模式使用的更改无关,因为CPU的功能确实非常强大,足以在2M波特的情况下保持UART中断,每20 us发生一次(大约每秒20万 字节,每个中断4字节UART FIFO)。

    当我发送的每个UART传输的字节数不是4的倍数时,就会出现偶尔的数据丢失问题(不相关,不要混淆)。 我上次给出的复制测试代码(每15毫秒发送16个字节)不会触发数据丢失,也不会一次发送20或24个字节, 但是,在较高波特率(800k波特率和更高)下,发送时每15毫秒显示17字节,会间歇性地导致丢失几个字节。 对于数据丢失的原因,我的猜测是奇数字节并不总是触发FIFO中断(XDS110固件将级别设置为4),并且会定期刷新FIFO,而不会将数据从FIFO中取出。

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

    此外,如果在16毫秒以上的时间内未通过UART接收任何内容,则似乎还有一些计时器处理会将UART DMA接收缓冲区刷新到USB。 但是,我的应用程序(和测试程序)往往会触发最坏的情况,即它们发送相距不到16毫秒的小块数据。 这些小块需要很长时间才能填满整个DMA传输缓冲区,但是它们的出现频率足以持续延迟此定期UART DMA缓冲区刷新到USB,无论它在固件中发生在何处。

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

    我弄明白了为什么在DMA模式下传输会延迟,因为每15毫秒或更短时间内会有一些小的UART数据进入。 XDS110固件中的计时器0中断处理程序每5毫秒触发一次。 在此处理程序中,如果自上次检查以来发生了3个或更多计时器中断周期,它将从UART读取UDMA传输中剩余的字节数,并将其与上次执行检查时读取的值进行比较。 如果(并且仅当) UDMA从UART传输的剩余字节数与上次(5*3=15毫秒前)保持不变,则会将DMA缓冲区中的任何数据刷新到USB。

    我的应用程序(和测试程序)都频繁地发送小块数据(相距15毫秒或更短),因此,计时器中断处理程序检查在过去15毫秒内没有传输任何新数据时,总是失败。 因此,在我的用例中,它最终会等待DMA缓冲区完全填满,然后再将数据发送到USB主机。

    我建议的解决方案有两个方面:

    1.修改DMA模式UART的计时器0中断逻辑,以将DMA缓冲区内容刷新到USB,即使数据经常被当作小块进行快速传输。 当前的逻辑是等待DMA缓冲区填满,当新数据在过去15毫秒内进入时,只有当持续的高吞吐量数据流进入,并迅速填满DMA缓冲区时,才有意义。

    2.将切换到基于DMA的UART操作的最小波特率从23.04万波特提高到0x20万 (209.7152万)波特率。 即使DMA模式计时器中断逻辑得到了改进,基于FIFO的模式也是更好的,因为它提供的延迟比DMA模式低得多,因为它不必等待定期计时器中断来刷新缓冲区。 CPU速度快,所以经常出现的UART中断应该是正常的。

    对于不是4的倍数的数据大小,在高波特率下的数据丢失问题是一个单独的问题,我们可以在另一个时间处理,并且似乎与选择DMA或FIFO基于中断的操作无关(因为这两者都发生)。