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.

[参考译文] MSP432P4111:使用 TI 驱动程序和 FreeRTOS 从 UART 进行连续读取

Guru**** 2988540 points

Other Parts Discussed in Thread: CC3135

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/851339/msp432p4111-continuous-reading-from-uart-using-ti-drivers-and-freertos

器件型号:MSP432P4111

您好!

设置:

版本:

- simplelink_msp432p4_sdk_3_30_00_13

- simplelink_sdk_wifi 插件_2_40_00_22

- FreeRTOSv10.2.1

- CCS  9.0.1.00004  

我有一个项目、它包含使用多处理器 UART 进行相互通信的多个板。

所有这些电路板上都有 MSP432P4111。

FreeRTOS 用作不带 POSIX 层的操作系统。

外设通过 driverlib API 使用。

有1个主板通过 UART 依次向所有其他板发送各种查询。

每个电路板都通过 UART 逐一响应。

在主板(也在其他主板上)上、DMA 通道用于逐个接收字节并将其存储在 StreamBuffer_t (来自 FreeRTOS)中

每当 DMA 完成对1个字节的读取时、就会触发中断。

在此中断处理程序中、使用 StreamBuffer_t 的"xStreamBufferSendFromISR"方法发送接收到的字节、然后使用相同的设置重新启用 DMA (从 UARTRX 接收1个字节)

此设置工作正常、没有问题。

问题:

但是、我必须为其添加无线连接。

我选择了 CC3135 BOOSTXL 板。

通过查看 MSP432的示例、可以看到它们使用 SPI TI 驱动程序与 CC 板进行通信。

我已决定将我的 driverlib 实现迁移到 TI 驱动程序、以使整个应用在 TI 器件之间至少具有一点跨平台性、此外、我还计划使用各种策略尽可能提高应用的功效。

我的问题是:

据我所知、无法通过 driverlib 以我使用的方式设置 UART:

TI 驱动程序实现完全缺少多处理器 API

我已经解决了这一问题、方法是使用 CS 引脚分别在所需电路板上启用和打开 UART、然后在所有数据交换完成后将其关闭。

2.由于能够使用 DMA、无法找到从 UART 连续读取的方法、因为:

我最近来的是为 UART 设置一个读取回调、并准备接收1个字节、并且计划在每次接收和处理一个字节时执行此操作、但文档警告我不能从其自身的回调函数调用 UART_Read():

*@警告在
*#UART_MODE_CALLACK 中时、不要从自己的回调函数调用%UART_READ()。 

此时、我看不出如何实现与 UART + DMA 相同的功能(接收一个字节、处理它、准备另一个字节<-中断处理程序中的所有这些)

现在、我有机会将 driverlib 实现方式保留原样、不要在 TI 驱动程序设置中触及 EUSCI 外设、但从长远来看、我不想使用权变措施、而且从经验中我也知道、 通过 driverlib 使用外设并使用 TI 驱动程序的省电功能(我计划使用该功能)会导致问题。

因此、我需要的是使用 TI 驱动程序实现与使用 driverlib 相同的 UART 功能

请提供任何帮助。

注:

我需要从 UART 逐字节读取、因为不同的请求和响应具有不同的长度。

逐字节读取确保了我始终将所有板的所有内容接收到同一个缓冲区中、该缓冲区将在以后处理、而不会阻止调用、也不会进行任何超时处理。

谢谢、

Akos

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

    您好!

    我已将您的问题转发给团队。 他们将在几天前返回。

    感谢您的耐心。

    此致

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

    您好、Akos、

    如果我理解正确、您只需了解如何使用 TI 驱动程序逐字节读取 UART。 请确认。 如果是、可以通过在 TI 驱动程序的 UART_READ API 上指定大小1来实现这一点。

    Jesu

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

    您好、Jesu、

    答案是肯定的、但您需要了解一点背景、才能完全理解我的问题。

    我有一个使用 FreeRTOS 的应用程序。

    此应用的周期时间为1ms。

    此应用程序必须连续接收来自其他器件的数据、而不知道要接收的数据量。 然后、每个周期都会检查标头、页脚的数据(在自定义环形缓冲区中)并进行处理。

    不使用 TI 驱动程序:

    我已设置 UART DMA、将1个字节接收到特定位置(自定义环形缓冲器)、

    此外 、还设置了 DMA 完成中断、在该中断中、我刚刚使用相同的源地址和手动递增的目标地址重新启用了 DMA。

    我只需启动一次读取过程、从这一点开始、我只需处理接收 到的数据(如果有)并从任务上下文放入环形缓冲区。

    使用 TI 驱动程序:

    我计划在 UART 处于回调模式时使用 UART_READ()实现相同的功能。

    我想在应用程序开始时、然后在每次回调中调用 UART_read (ownHandle、&ringBuffer[currentWritePosition]、1U)。

    这将是完美的解决方案、因为它的工作方式与我之前的非 TI 驱动程序实现方式相同、但我在 UART.h 中找到了这条评论(simplelink_msp432p4_sdk_3_30_00_13)

    *@警告在
    *#UART_MODE_CALLACK 中时、不要从自己的回调函数调用%UART_READ()。 

    因此,既然我知道,我无法从自己的回调中使用 UART_read(),我需要从周期时间为1ms 的循环任务中调用 UART_read(),这会导致巨大的数据丢失,而在接收字节后不调用 UART_read()。

    这种解决方案最适合我的真正问题是 、我不知道另一个器件正在发送多少数据(如果有)、但是、当收到完整消息时、我必须尽快做出响应。

    那么、这就是我要实现的目标。

    我希望这清除了我的问题的背景。

    感谢你的帮助。

    Akos

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

    您好、Akos、

    为什么不增加缓冲区大小? 这种方法效率更高、因为读取之间的处理时间会更长、并且使用大小合适的缓冲区、不会丢失任何数据。 对1个字节使用 DMA 会首先使使用 DMA 的目的失败。 我同意、为了便于携带、最好将驾驶员留在自己的位置。  

    Jesu

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

    您好、Jesu、

    缓冲区大小增加的问题在于、我不知道在给定的时间范围内将接收多少数据、它可以是0字节到500字节以上的任何数据(这是器件的工作方式、遗憾的是我无法更改其行为):

    例如,在一个周期内,我将用 UART_READ()等待的所需数据量设置为理论最大值~1000字节(我增加了这个数字,只是为了示例)。

    在 UART 回调中,我设置了一个标志,该数据将被接收,以便我可以从主周期再次调用 UART_READ()。

    此方法有2个问题:

    1、当我无法处理任何数据时、将会有周期、因为器件仅发送100个字节、但已接收到该字节、但尚未调用回调、因此对于应用层、数据不可用。 但是、我已经需要处理收到的数据并对其做出响应。

    2.如果在主周期结束后立即接收到1000个字节,则在回调调用期间以及主周期开始之间应接收的所有数据都将丢失,因为我只能从任务环境中再次调用 UART_READ(),而不能从回调本身调用。

    我确实知道、使用 DMA 逐字节读取是有一定程度的违背了它的目的、但它解决了我遇到的问题、我本来可以在没有 DMA 的情况下、只使用 UART 中断来执行同样的操作。 但我似乎无法使用 TI-Drivers 解决它。

    我解决问题的方式是、我使用了协议标头中的数据、该数据描述了要作为有效载荷接收的数据量。

    这现在起作用了、但我必须使我自己的 HAL 层(在我的例子中、处理对 TI-Drivers 的调用的层)协议知道、我真的希望避免这种情况。 所有数据处理、解析和分布之前都是在功能层上处理的、而 HAL 层只是简单地接收数据并将其推入环形缓冲区、而无需了解任何相关信息(这里我的意思是要接收的数据量)。

    该解决方案基本上是一种解决方法、不是解决问题的真正解决方案、但它起作用。 现在、我可以继续发展、但我的问题仍然是:

    TI 驱动程序是否有可能在不与应用层进行任何外部交互的情况下通过 UART 逐字节连续接收数据(这意味着无需从任务上下文调用 UART_READ)?

    或者(只是一个想法)、是否有可能访问 TI-Drivers 内部缓冲器? 假设我将 UART_Read()设置为等待1000个字节,是否可以检查是否收到任何数据,并在调用回调之前获取该数据?

    因此、正如我之前所说的、我已经做了一个权变措施、这种工作(需要在这里和那里进行一些改进、 但可行)、所以如果我的问题没有解决方案、这不是问题、此时我只想知道是否可以或不可以像我所描述的那样使用用于 UART 的 TI 驱动程序。

    再次感谢您、

    Akos

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

    您好、Akos、

    TI 驱动程序无法满足您的要求。 我不确定是否不知道您将收到多少数据是采用这种使用 UART 的非标准方法的好理由。 您应该在数据中建立某种模式、其中包含一些消息终止字符以指示完整消息的结束。  

    正如您发现的、您可以随意修改驱动程序以获得所需的行为、但我相信这不仅仅是一个设计问题、而是 TI 驱动程序缺少功能。

    Jesu

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

    您好、Jesu、

    我得出同样的结论。 使用的协议用页眉页脚包装有效负载、其中页眉具有有效负载的大小、因此我将继续使用始终等待精确数据量的方法。 我不会编辑驱动程序、因为我打算迁移到 TI-Drivers 的其中一个计划是通过具有 simplelink 支持的 MCU 实现兼容性。

    无论如何、感谢您花时间为我提供帮助。

    此致、

    Akos