Как использовать задержки при использовании отладчика с STM32? - PullRequest
0 голосов
/ 01 марта 2019

Я использую отладчик ST Link на микроконтроллере STM32F407.У меня есть проблемы, связанные с неправильной загрузкой данных между различными циклическими буферами, используемыми для извлечения байтов из USART.Я хотел посмотреть, как поток, который извлекает кадры из массива serial [4000], ведет себя с добавленной задержкой.

Ниже код хорошо работает с отладчиком, и я могу перейти к каждой строке и проверить значения переменных.

//This callback is automatically called by the HAL when the DMA transfer is completed
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {           

    // read 50 bytes of raw data to the raw_serial buffer   
    HAL_UART_Receive_DMA (huart, raw_serial, 50);

    //osDelay(10);
    //HAL_Delay(10);

    // add raw_serial to the serial[4000]
    AppendSerial(raw_serial,size);  
}

Использование одной из этих задержек:

  • osDelay(10);
  • HAL_Delay(10);

Заставляет выполнение программы зависатьобратного отсчета и не дает мне когда-либо достичь контрольной точки, расположенной после статов ожидания.

Читая этот пост , мне кажется, что osDelay более практичен при использовании FreeRTOS.

Единственное, о чем я могу думать, это то, что ST Link не хватает совместимости или драйверов или невозможности включить задержки из-за функций обратного вызова, запускаемых по прерываниям.

Спасибо за вашу помощь.

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

Это не имеет ничего общего с ST-Link.

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

Позвольте прерыванию таймера опередить обработчик последовательного прерывания

Убедитесь, что прерывание таймера имеет более высокий приоритет, чем последовательное прерывание.По умолчанию HAL устанавливает прерывание таймера на минимально возможный приоритет (довольно глупая идея IMO) в stm32f4xx_hal_conf.h

#define  TICK_INT_PRIORITY            0x0FU /*!< tick interrupt priority */

, изменяет его на более низкое значение (более высокий приоритет) и устанавливает приоритет UART.прерывать до более высокого значения (с более низким приоритетом).Теперь HAL_Delay() будет работать даже в обработчике прерываний UART.

Заставить HAL_Delay() работать без прерываний

HAL_Delay() работает, многократно вызывая HAL_GetTick() довремя задержки истекло.HAL_GetTick() должно возвращать время, прошедшее с момента запуска в миллисекундах, в виде 32-разрядного значения без знака.Вы можете предоставить собственную реализацию HAL_GetTick(), которая использует 32-разрядный аппаратный таймер для определения текущего времени.

Существует два 32-разрядных таймера, TIM2 и TIM5, выберите один из них.Установите значение перезагрузки на тактовую частоту APB1, деленную на 1000 минус 1 (83999 с настройками часов по умолчанию), начните отсчет вверх.Теперь HAL_GetTick() может просто вернуть регистр счетчика таймера.

uint32_t HAL_GetTick(void) {
    return TIM2->CNT; // or TIM5->CNT
}

Написать собственную функцию задержки

Например, вы можете использовать счетчик циклов для коротких задержек или пустой цикл for для приблизительных задержек, запуска таймера однократного запуска, ожидания до завершения и т. Д.

0 голосов
/ 01 марта 2019

Вы не можете вызвать функцию задержки из обработчика прерываний.Помните, что целью обработчиков прерываний является выполнение как можно быстрее, чтобы программа могла вернуться к нормальному выполнению, задержка несовместима с этой концепцией.

...