我们可以为方便起见编辑回调函数 HAL_UART_TxCpltCallback 吗?

Can we edit callback function HAL_UART_TxCpltCallback for our convenience?

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

提前致谢

您调用 HAL_UART_Transmit_IT 以 "interrupt"(非阻塞)模式传输您的数据。此调用会立即调用 returns,很可能在您的数据被完全传输之前。

事件顺序如下:

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

  • 然后为该 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)。

关于你的第二个问题,你是否可以编辑这个回调 "for convenience" - 我会说你可以做任何你想做的事,但你必须忍受修改代码的后果,本质上是一个库:

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

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

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

  1. 建议您对 ST 进行更改。您必须记住,HAL 旨在满足 "general purpose" 需求。

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