STM32 TIM回调引发标志
Posted
技术标签:
【中文标题】STM32 TIM回调引发标志【英文标题】:STM32 TIM callback to raise flag 【发布时间】:2020-11-14 17:16:02 【问题描述】:我读过很多次,通常最好的做法是尽量减少在定时器中断上花费的时间,并且多次提出只提高标志的建议。
我正在使用计时器来运行一些代码(将传感器数据转换为可用数据)。在我的应用程序中,以相当高的速度 (8KHz) 读取和操作这些数据非常重要。
这是我解决问题的方法:
我正在使用 STM32 H743
我正在使用具有两个线程的 RTOS,优先级略有不同
在我的情况下,我使用了 2 个计时器(TIM2 和 TIM3)
TIM2 设置为在 1KHz 触发回调,并在我的主线程中启动(优先级略高于辅助线程)
TIM3 设置为在 8KHz 触发回调,并在辅助线程中启动
HAL_TIM_PeriodElapsedCallback 用于两个计时器,如下所示:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
/* USER CODE BEGIN Callback 0 */
/* USER CODE END Callback 0 */
if (htim->Instance == TIM6)
HAL_IncTick();
/* USER CODE BEGIN Callback 1 */
else if (htim->Instance == TIM2)
TIM3_flag = 1;
else if (htim->Instance == TIM3)
TIM3_flag = 1;
/* USER CODE END Callback 1 */
然后 2 个线程中的每一个都对标志进行简单测试,这是辅助线程的样子:
void StartSecondaryThread(void *argument)
/* USER CODE BEGIN StartSecondaryThread */
HAL_TIM_Base_Start_IT(&htim3);
/* Infinite loop */
for(;;)
if (TIM3_flag == 1)
runCALC();
//MORE USER CODE HERE
TIM3_flag = 0;
/* USER CODE END StartSecondaryThread */
根据 CubeMX 自动生成的代码,mainThread 和 secondaryThread 无限 for(;;) 循环都有一个 osDelay(1)。
我应该保留这些天吗?在升旗的 if 语句之外?
我有些担心,如果我不这样做,它会导致 MCU 崩溃,因为在没有升起标志的情况下,外界无事可做。而且我担心保持 osDelay(1) 会“太长”(1ms vs 125 us)。有没有办法应用更短的延迟而不会减慢我的 8KHz 轮询?
当然,runCAL() 的内容将比 125 us 周期花费的时间要少得多。
将延迟全部消除对我来说是有意义的,但我感觉它会严重崩溃。
我该怎么办?
干杯
【问题讨论】:
【参考方案1】:使用 RTOS 时,标志并不是线程同步的好方法。
在这种情况下,请使用信号量、互斥锁或直接任务通知。
比辅助线程的优先级略高
它在您显示的代码中没有任何区别不同优先级的 RTOS 任务不会被调度程序抢占,并且只有当您自己传递控制权时才会发生上下文切换。唯一真正会一直运行的任务是最后启动的任务,因为您的任务不会将控制权传递给 RTOS,而 ISR 也不会。您的代码实际上不是正确的 RTOS 代码。
您可以在一项任务中使用它。
void StartSecondaryThread(void *argument)
/* USER CODE BEGIN StartSecondaryThread */
HAL_TIM_Base_Start_IT(&htim3);
HAL_TIM_Base_Start_IT(&htim2);
/* Infinite loop */
for(;;)
switch(ulTaskNotifyTake(pdTRUE, portMAX_DELAY))
case 3:
runCALC();
//MORE USER CODE HERE for timer 3
break;
case 2:
//MORE USER CODE HERE for timer 2
break;
default:
//MORE USER CODE HERE for other timers
break;
/* USER CODE END StartSecondaryThread */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
BaseType_t xHigherPriorityTaskWoken = pdFalse;
switch((uint32_t)htim->Instance)
case (uint32_t)TIM6:
HAL_IncTick();
break;
case (uint32_t)TIM2:
xTaskNotifyFromISR( xThreadHndl, 2, eSetValueWithOverwrite, &xHigherPriorityTaskWoken );
break;
case (uint32_t)TIM3:
xTaskNotifyFromISR( xThreadHndl, 3, eSetValueWithOverwrite, &xHigherPriorityTaskWoken );
break;
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
【讨论】:
默认情况下(configUSE_TIME_SLICING 定义为 1),FreeRTOS 调度程序在具有最高优先级的任务之间切换。如果您将系统设计为完全具有同等优先级的任务,这可能会很有用,但当然最好使用适当的同步原语。以上是关于STM32 TIM回调引发标志的主要内容,如果未能解决你的问题,请参考以下文章