Как использовать задержки при использовании отладчика с STM32?

Я использую отладчик 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 или невозможность включить задержки из функций обратного вызова, запускаемых прерыванием.

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
1 082
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Ответ принят как подходящий

Это не имеет ничего общего с 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, чтобы иметь приблизительные задержки, запустить одноразовый таймер и дождаться завершения и т. д.

Другие вопросы по теме