Я уже использовал STM32CubeMx / HAL в нескольких проектах и обнаружил, что генерируемая им программа обработки UART имеет определенные недостатки на стороне приема.
При передаче вы обычно хотите отправить блок данных или строку текста. В этом случае вы заранее знаете, сколько времени занимает передача данных, и поэтому использование DMA является очевидным решением. Вы получаете прерывание после завершения передачи и можете использовать функцию обратного вызова UART TX complete, чтобы указать вашему основному коду, что передача завершена, и вы можете отправить другой блок данных.
Когда дело доходит до получения данных, все функции, предоставляемые ST, предполагают, что вы знаете, сколько символов будет выдано отправляющим устройством, прежде чем оно начнет отправлять. Обычно это не известно. Функция прерывания помещает полученные данные в буфер и указывает только на то, что данные доступны, когда получено заранее определенное количество символов. Если вы попытаетесь использовать DMA или функцию прерывания для получения данных путем настройки последовательных односимвольных передач, то время установки для каждого из них будет означать, что вы потеряете символы с любой скоростью, кроме самой низкой скорости передачи данных (скорость передачи данных, которую вы будете потеря данных будет зависеть от тактовой частоты вашего процессора) и будет чрезмерно загружать процессор, не оставляя циклов команд для какой-либо другой обработки
Чтобы обойти это, я написал свою собственную функцию обработчика прерываний, которая хранит данные в небольшом локальном циклическом буфере и устанавливает счетчик, который читается основным кодом (семафор подсчета RTOS), чтобы указать, что полученные данные готовы. Затем основной код может собирать данные из этого буфера в свободное время, при этом не имеет значения, имеется ли некоторая задержка в сборе данных, при условии, что локальный буфер не переполняется до того, как данные собраны.