【问题标题】:STM32- RTOS -Task Notify From ISRSTM32- RTOS - ISR 的任务通知
【发布时间】:2022-09-22 21:54:26
【问题描述】:

我想通知我的任务从 ISR 运行。我红了 RTOS 文档,但我做不到。如果您告诉我我应该做什么并在可能的情况下举个例子,我将不胜感激。我使用了cmsis-V2。 在 ISR 内部,我确信 ISR 可以正常工作,我写道:

  void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* USER CODE BEGIN Callback 0 */

  /* USER CODE END Callback 0 */
  if (htim->Instance == TIM15) {
    HAL_IncTick();
  }
  /* USER CODE BEGIN Callback 1 */
  if (htim == &htim16)
    {
        BaseType_t xHigherPriorityTaskWoken;
        xHigherPriorityTaskWoken = pdFALSE;
        vTaskNotifyGiveFromISR(ADXL_HandlerHandle , &xHigherPriorityTaskWoken);
        portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
      }

  /* USER CODE END Callback 1 */
}

我还使用免费 RTOS 的 systick 计时器和计时器 15 作为系统计时器。问题可能与这部分有关吗?我不知道,因为 task_notify_give 函数只是加起来,而不是像信号量这样的阻塞机制。

在 thask 内部,在 for 循环内部,第一行是:

ulNotifiedValue = ulTaskNotifyTake( pdFALSE, portMAX_DELAY);
      if( ulNotifiedValue > 0 ){
//my codes ....
}

在我定义的 for 循环之前:

uint32_t ulNotifiedValue;

但任务没有执行。哪怕只有一次。 我使用 Nucleo H755ZIQ。

在定义全局变量之前,任务定义如下:

/* Definitions for ADXL_Handler */
osThreadId_t ADXL_HandlerHandle;
const osThreadAttr_t ADXL_Handler_attributes = {
  .name = \"ADXL_Handler\",
  .priority = (osPriority_t) osPriorityNormal,
  .stack_size = 1024 * 4
};

然后在初始化调度程序的主函数内部如下:

 osKernelInitialize();
 ADXL_HandlerHandle = osThreadNew(ADXL_Handler_TaskFun, NULL, &ADXL_Handler_attributes);
osKernelStart();

然后将启动计时器:

 HAL_TIM_Base_Start_IT(&htim16);
 

在CMSIS中没有任务通知之类的东西,我看了一眼。我在 ISR 例程中使用的函数来自 FreeRTOS。会不会有矛盾?我应该只使用免费 RTOS 任务创建函数而不是 CMSIS 函数吗?

提前致谢。

  • 通知相关的代码似乎没问题。我认为问题是别的。任务是否正确创建和启动(有足够的堆栈)?您是否确保在创建任务并且 ADXL_HandlerHandle 有效之前不调用 ISR?
  • 关于我怀疑的任务句柄,我编辑了我的问题并添加了 CUBE IDE 如何定义任务。启用任务后启用计时器。在使用任务通知之前,我编译了程序并且任务运行正确,所以我认为堆栈大小不是问题。我可以上传整个代码,但可能不是一个好的决定,因为它有点长。根据用于创建任务的免费 RTOS 文档,使用了 xTaskCreated(),并将任务句柄作为输入参数提供给该函数。这可能是问题吗?
  • 您通常可以在代码中混合和匹配 CMSIS API 和本机 FreeRTOS API。通知相关的代码似乎是正确的,堆栈大小应该绰绰有余。是否有任何任务/调度程序运行正确,您是否验证在 ISR 中调用了 vTaskNotifyGiveFromISR ?

标签: arm stm32 freertos isr mcu


【解决方案1】:

我不确定这是否适用于 freeRTOS,但在 embos 中,您需要在从中断与操作系统交互时调用 OSIntEnter() 和 OSIntExit()。所以这意味着,你必须这样做:

OSIntEnter();
vTaskNotifyGiveFromISR(ADXL_HandlerHandle , &xHigherPriorityTaskWoken);
OSIntExit();

与操作系统交互时,中断的优先级也可能受到限制。在 embos 中,如果要从中断中调用 OS 函数,则中断的优先级必须至少为 8。

【讨论】:

    猜你喜欢
    • 2021-09-19
    • 2017-08-23
    • 1970-01-01
    • 2020-04-17
    • 1970-01-01
    • 1970-01-01
    • 2011-02-27
    • 2021-09-23
    • 2022-01-17
    相关资源
    最近更新 更多