FreeRTOS:为何同一任务函数绑定两个任务仅最后创建的生效?
问题根源:错误的任务参数传递逻辑
你遇到的问题和「共用任务函数」无关——FreeRTOS完全支持多个任务复用同一个任务函数,每个任务会拥有独立的栈空间和参数副本。真正的问题出在你传递任务参数的方式上:
你创建任务时直接将true/false字面量强制转换为void*,然后在任务函数里把这个指针转成bool*去解引用,这是严重的错误:
(void *)true本质是把整数1转换成指针,指向的是内存地址0x1(32位系统),这个地址属于非法内存区域,不属于你的程序可控范围。- 解引用这个非法指针会触发未定义行为,你看到「只有递减任务生效」只是未定义行为的一种随机表现,实际运行中还可能出现崩溃、数值乱跳等问题。
正确的参数传递方式
方式1:传递变量地址(推荐)
把布尔参数存储在全局或静态变量中,传递变量的地址给任务:
// 共享变量 int x = 0; // 存储任务参数的静态变量 static bool incFlag = true; static bool decFlag = false; void myTask_increment_decrement(void *pvParameters) { bool *pFlag = (bool *)pvParameters; while(1) { if(*pFlag) { x += 1; } else { x -= 1; } } } // 创建任务 BaseType_t status1 = xTaskCreate( myTask_increment_decrement, "myTaskIncrement", configMINIMAL_STACK_SIZE, &incFlag, 2, &g_taskHandle1); BaseType_t status2 = xTaskCreate( myTask_increment_decrement, "myTaskDecrement", configMINIMAL_STACK_SIZE, &decFlag, 2, &g_taskHandle2);
方式2:直接传递整数参数
如果只是简单的布尔值,可以直接把true/false作为整数传递,任务函数里直接转换为bool使用,无需解引用:
// 共享变量 int x = 0; void myTask_increment_decrement(void *pvParameters) { bool isIncrement = (bool)pvParameters; while(1) { if(isIncrement) { x += 1; } else { x -= 1; } } } // 创建任务 BaseType_t status1 = xTaskCreate( myTask_increment_decrement, "myTaskIncrement", configMINIMAL_STACK_SIZE, (void *)true, 2, &g_taskHandle1); BaseType_t status2 = xTaskCreate( myTask_increment_decrement, "myTaskDecrement", configMINIMAL_STACK_SIZE, (void *)false, 2, &g_taskHandle2);
额外提醒:共享变量的线程安全
你当前的代码中,多个任务直接操作共享变量x会存在竞态条件(比如增减操作不是原子性的),实际项目中需要用互斥锁或原子操作保护:
// 示例:用互斥锁保护共享变量 SemaphoreHandle_t xMutex; void myTask_increment_decrement(void *pvParameters) { bool isIncrement = (bool)pvParameters; while(1) { if(xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) { if(isIncrement) { x += 1; } else { x -= 1; } xSemaphoreGive(xMutex); } } } // 在启动任务前创建互斥锁 xMutex = xSemaphoreCreateMutex();
内容的提问来源于stack exchange,提问作者Elliott Goldstein
相关产品推荐
相关产品推荐

