使用 HAL_UART_Receive_IT() 和 HAL_UART_RxCpltCallback() 时会丢失字节吗?
Can bytes be lost when using HAL_UART_Receive_IT() and HAL_UART_RxCpltCallback()?
我有一些(主要是 CubeMX 生成的)代码:
volatile uint8_t buf[4];
int main(void)
{
...
HAL_UART_Receive_IT(&huart3, buf, sizeof(buf));
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART3) {
HAL_UART_Transmit(&huart3, buf, sizeof(buf), 0xFFFF);
HAL_UART_Receive_IT(&huart3, buf, sizeof(buf));
}
}
这成功地回显了 USART3 上接收到的所有内容。 (这段代码只是一个学习串口的一次性例子。)
我担心 HAL_UART_RxCpltCallback()
被调用和 HAL_UART_Receive_IT()
设置下一次接收之间的时间。
STM32F103有没有什么特性可以保证在这个区间内不丢失数据?我没有在 USART 上找到超过两个字节的接收缓冲区的任何证据。
我特别担心某些优先级较高的 USB 设备 activity 可能会延迟 HAL_UART_RxCpltCallback()
的调用,因此可能会丢失一个或多个字符。
Quick answer:
HAL_UART_Transmit 是一个阻塞函数,因此,在它完成之前 HAL_UART_Receive_IT 不会被调用并且 uart 肯定会溢出。如果您担心任何其他中断会抢占您的执行,请在发出命令时使用 dma 或禁用麻烦的中断。您也可以提高 UART 中断优先级但是....
Hints:
...您不应在 HAL_UART_RxCpltCallback 内调用 HAL_UART_Transmit 和 HAL_UART_Receive_IT,因为您处于 ISR 模式。这会导致某些版本的 HAL 框架出现一些附带问题。最好设置一个标志并从主代码中检查它。
另外你真的应该避免使用 volatile,如果你使用像 gcc 这样的编译器障碍会更好__asm volatile("" ::: "memory")
我有一些(主要是 CubeMX 生成的)代码:
volatile uint8_t buf[4];
int main(void)
{
...
HAL_UART_Receive_IT(&huart3, buf, sizeof(buf));
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART3) {
HAL_UART_Transmit(&huart3, buf, sizeof(buf), 0xFFFF);
HAL_UART_Receive_IT(&huart3, buf, sizeof(buf));
}
}
这成功地回显了 USART3 上接收到的所有内容。 (这段代码只是一个学习串口的一次性例子。)
我担心 HAL_UART_RxCpltCallback()
被调用和 HAL_UART_Receive_IT()
设置下一次接收之间的时间。
STM32F103有没有什么特性可以保证在这个区间内不丢失数据?我没有在 USART 上找到超过两个字节的接收缓冲区的任何证据。
我特别担心某些优先级较高的 USB 设备 activity 可能会延迟 HAL_UART_RxCpltCallback()
的调用,因此可能会丢失一个或多个字符。
Quick answer:
HAL_UART_Transmit 是一个阻塞函数,因此,在它完成之前 HAL_UART_Receive_IT 不会被调用并且 uart 肯定会溢出。如果您担心任何其他中断会抢占您的执行,请在发出命令时使用 dma 或禁用麻烦的中断。您也可以提高 UART 中断优先级但是....
Hints:
...您不应在 HAL_UART_RxCpltCallback 内调用 HAL_UART_Transmit 和 HAL_UART_Receive_IT,因为您处于 ISR 模式。这会导致某些版本的 HAL 框架出现一些附带问题。最好设置一个标志并从主代码中检查它。
另外你真的应该避免使用 volatile,如果你使用像 gcc 这样的编译器障碍会更好__asm volatile("" ::: "memory")