STM32 TIM回调升旗

STM32 TIM callback to raise flag

我读过很多次,将花在定时器中断上的时间减到最少通常是一个好习惯,并且只提出一个标志的建议出现了好几次。

我正在使用计时器来 运行 一些代码(将传感器数据转换为可用数据)。在我的应用程序中,以相当高的速度 (8KHz) 读取和操作这些数据很重要。

这是我解决问题的方法:

然后 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) 会“太长”(1 毫秒对 125 微秒)。有没有一种方法可以应用更短的延迟,而不会减慢我的 8KHz 轮询?

当然,运行CAL() 所需的时间将比 125 us 周期少得多。

对我来说,完全消除延迟是有意义的,但我感觉它会严重崩溃。

我该怎么办?

干杯

当您使用 RTOS 时,标志不是非常好的线程同步方式。

在这种情况下使用信号量、互斥量或直接任务通知。

slightly higher priority than the secondary thread

您显示的代码没有任何区别不同优先级的 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 );
}