You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32 FreeRTOS调用vTaskDelete删除任务导致程序挂起问题求助

问题根因

你在当前正在运行的任务上下文内,执行vTaskDelete删除自身,删除操作执行后当前任务会立刻终止执行,vTaskDelete后续的所有逻辑(包括创建新任务、更新状态变量、更新任务句柄等代码)完全不会运行,导致旧任务被删除后没有新任务被调度,程序直接冻结。

修复方案

调整State_change_handle的执行顺序,先创建新任务、更新状态和任务句柄,最后再删除旧任务,保证即使删除的是当前运行的任务,新任务也已经创建完成可以被调度。
修改后的代码示例:

void Controller::State_change_handle(e_thermostat_state state)
{
    this->new_state = state;
    if(this->old_state == this->new_state ){ 
        printf("same task \n");
        return;
    }
    // 提前保存旧任务句柄
    TaskHandle_t old_task = this->main_task_handle;

    // 先创建新任务、更新状态和新任务句柄
    switch(this->new_state) 
    {   
        case TASK1:
            printf("NEW STATE = MODE1 \n");
            this->old_state = TASK1;
            xTaskCreate(task1,"MODE1",10000,this,1,&this->main_task_handle);
            break;
        case TASK2:
            printf("NEW STATE = MODE2\n");
            this->old_state = TASK2;
            xTaskCreate(task2,"MODE2",10000,this,1,&this->main_task_handle);
            break;
        default:
            printf("state not recognised \n");
            return;
    }

    // 最后删除旧任务
    if (old_task != NULL){
        printf("delete the previous task \n");
        vTaskDelete(old_task);
    }
}

关于类指针调用写法的问题

你在静态任务函数中通过Controller* controller = (Controller*)parameters;获取类实例指针的写法是完全合规的,这是FreeRTOS任务和C++类结合的标准实现方式:

  • 静态成员函数没有隐含的this指针,所以通过xTaskCreate的第四个参数传入类实例的this指针
  • 任务函数启动后将参数强转为类指针,即可正常访问类的公有/私有成员,该写法没有问题。

内容的提问来源于stack exchange,提问作者TheBestPlayer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 03:48:03