Могут ли байты быть потеряны при использовании HAL_UART_Receive_IT () и HAL_UART_RxCpltCallback ()? - PullRequest
0 голосов
/ 13 января 2020

У меня есть некоторый (в основном сгенерированный 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-устройства с более высоким приоритетом могут задержать вызов HAL_UART_RxCpltCallback(), и поэтому один или более символов могут быть потеряны.

1 Ответ

1 голос
/ 13 января 2020

Быстрый ответ:

HAL_UART_Transmit является функцией блокировки, поэтому до ее завершения HAL_UART_Receive_IT не вызывается, и uart наверняка переполнится go. Если вы беспокоитесь о том, что любое другое прерывание может предрешить ваше выполнение, используйте dma или отключите проблемные прерывания, когда вы вводите команду. Вы также можете повысить приоритет прерывания UART, но ....

Подсказки:

.... вам не следует вызывать HAL_UART_Transmit и HAL_UART_Receive_IT в рамках HAL_UART_RxCpltCallback, как здесь вы находитесь в Режим ISR. Это вызывает некоторые побочные проблемы в определенных версиях инфраструктуры HAL. Лучше установить флаг и проверить его из основного кода.

Также вам действительно следует избегать использования volatile, лучше, если вы используете барьер компилятора, такой как g cc __asm volatile("" ::: "memory")

...