首页 > 解决方案 > 为了方便,我们可以编辑回调函数 HAL_UART_TxCpltCallback 吗?

问题描述

我是 FreeRTOS 和 STM32 的新手。我想知道 HAL_UART_Transmit_IT 的回调函数 HAL_UART_TxCpltCallback 究竟是如何工作的?为了方便起见,我们可以编辑那个回调函数吗?

提前致谢

标签: callbackstm32freertosusart

解决方案


您调用HAL_UART_Transmit_IT以“中断”(非阻塞)模式传输数据。此调用会立即返回,很可能早在您的数据被完全传输之前。

事件顺序如下:

  • HAL_UART_Transmit_IT存储您提供的数据缓冲区的指针和长度。它不执行复制,因此您传递的缓冲区需要保持有效,直到回调被调用。例如,它不能是您将在回调发生之前执行delete []/ freeon 的缓冲区,也不能是您将在回调调用之前返回的函数中的本地缓冲区。

  • 然后它为这个UART启用TXE中断,每次DR(或TDR,取决于使用的STM)为空并且可以写入新数据时都会发生中断

  • 此时中断立即发生。在 IRQ 处理程序 ( HAL_UART_IRQHandler) 中,将一个新字节放入DR( TDR) 寄存器中,然后将其传输 - 这发生在UART_Transmit_IT.

  • 一旦这个字节被传输,TXE中断就会再次被触发,这个过程会重复,直到到达你提供的缓冲区的末尾。

  • 如果发生任何错误HAL_UART_ErrorCallback,将从 IRQ 处理程序调用

  • 如果没有发生错误并且已经到达缓冲区末尾,HAL_UART_TxCpltCallback则调用(从HAL_UART_IRQHandler-> UART_EndTransmit_IT)。

关于你的第二个问题,你是否可以“为了方便”编辑这个回调——我想说你可以做任何你想做的事情,但你必须忍受修改代码的后果,这本质上是一个库:

  1. 将 HAL 升级到新版本将是一场噩梦。您必须手动重新应用您对该代码所做的所有更改并再次测试它们。在某种程度上,这可以通过某种形式的版本控制(git / svn)甚至补丁文件来自动化,但是如果您修改的代码被 ST 更改,这些补丁可能不再适用,您将不得不这样做这一切都是手工的。这可能需要重新发现实现的变化并从头开始完成所有工作。

  2. 没有人能够帮助您,因为您的库代码不再与其他人拥有的代码匹配。如果您通过修改库代码引入了新的错误,那么没有人能够重现它们。即使您提供了您的修改,老实说,我怀疑这里的许多人会费心应用您的更改并在实践中对其进行测试。

如果我要表达我的个人观点,那就是:如果您认为 HAL 代码中存在错误,请在本地修复它们并将它们报告给 ST。一旦它们在未来的更新中得到修复,请使用更新的官方版本完全覆盖您的 HAL 修改。如果您认为 HAL 代码缺乏满足您需求的功能或灵活性,您有两种选择:

  1. 建议您对 ST 进行更改。您必须记住,HAL 旨在满足“通用”需求。

  2. 只是不要对这个特定的外围设备使用 HAL。这种“混合”的方法正是我个人所做的。在某些情况下,HAL 为给定外围设备提供的功能“足够好”可以满足我的需求(在我的情况下,一个示例是 SPI,我完全依赖 HAL),而在其他一些情况下 - 例如 UART - 我仅将 HAL 用于初始化,同时自己处理传输。即使您决定不使用 HAL 函数,它仍然可以提供一些价值——例如,您可以将它们的 IRQ 处理程序复制到您的代码中并改为调用您的函数。这样,您至少可以跳过开发中的某些部分。


推荐阅读