【发布时间】: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