Не отрабатывает hal_uart_rxcpltcallback
Всем здаровеньки. Такая проблема появилась. Использую FreeRtos на stm32f4 возникла такая задача - необходимо по прерыванию обрабатывать пакет данных приходящих по USART. Переопределил weak функцию hal_uart_rxcpltcallback.
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
uint8_t str[] = "Hello world UART\r\n\0";
HAL_UART_Transmit(huart, str, sizeof(str), 30);
}
При отправлении сообщения - ничего не происходит (использую FTDI). После отправки большого количества данных, прерывание все таки вызывается, но в структуре UART_HandleTypeDef значение RxXferSize = 0.
После решил переопределить функцию HAL_UART_ErrorCallback
void HAL_UART_ErrorCallback (UART_HandleTypeDef * huart){
//breakpoint
}
В итоге оказалось, что после вызова предыдущей функции сразу вызывается и эта функция. В ней значение RxXferSize = 39 и поднимается флаг переполнения. Если извлечь данные из буфера, то там действительно есть те данные, которые отправлялись, но очевидно часть данных потерялась из-за переполнения.
Проблема в том, что прерывание должно отрабатывать как только приходит пакет (там есть программные флаги). Явно функция работает не правильно, как это можно исправить? В чем может быть проблема?
Во FreeRtOS уровень прерывания стоит 5, что является максимальным. К слову, при отправке данных, прерывание на отправку вызывается сразу, вектор прерывания один, следовательно уровни у них едины.
Ответы (1 шт):
После проведенных тестов понял вот что, это в целом решило мой вопрос.
- То, что прерывание вызывалось, когда отпускалась линия ничто иное как шум на линии, который воспринимался как один символ, что в итоге дало ошибочное суждение.
- Прерывание hal_uart_rxcpltcallback вызывается только при условии вызова функций работающих с прерыванием, то есть HAL_UART_Receive_IT или HAL_UART_Receive_DMA. Никаким иным образом оно вызываться не должно.
- Для приема неизвестно длины пакета можно использовать несколько методов, но опишу один, самый простой (про сложные через IDLE строк можно посмотреть на ютубе). При использовании DMA можно реализовать прерывание по одному символу, при использовании IT такого результата не будет, так как будут теряться символы.
Если используете CUBEMXIDE при генерации кода, то убедитесь, что инициализация UART идет после инициализации DMA (иначе ничего работать не будет), этот баг известен, но найти с первого раза информацию о нем мне не удалось, так что оставлю ее здесь. Что касается того, что hal_uart_rxcpltcallback вызывалось после переполнения буффера, то мне не удалось найти точного подтверждения причины этому, после нескольких компиляций с разными входами этот баг пропал сам, так же как и появился. Так или иначе, триггер этой функции лежит в функциях приема.