多任务并发调用创建FreeRTOS对象的硬件初始化函数是否存在安全风险?
你的顾虑绝对合理,这确实是个需要解决的竞态条件问题
为什么会出问题?
你代码里的if (NULL == i2c_control_mutex[i2c_control])检查和后续的互斥量创建操作不是原子性的。当多个任务同时调用I2C_Control_Init时,很可能出现多个任务都通过了NULL检查,接着各自尝试创建互斥量的情况:
- 第一个任务刚创建完互斥量并赋值给数组元素,第二个任务已经通过了之前的NULL判断,会再次创建一个新的互斥量覆盖掉之前的指针,导致第一个互斥量的内存泄漏。
- 更糟的是,后续任务拿到的互斥量不是同一个,完全起不到互斥保护硬件的作用。
怎么解决这个问题?
这里有几个靠谱的方案,按推荐度排序:
方案1:启动任务提前初始化所有共享资源
既然启动任务负责创建所有子任务,那不如把所有共享硬件的初始化(比如I2C互斥量的创建)都放在子任务创建之前完成。这样所有子任务启动时,需要的FreeRTOS对象已经准备就绪,从根源上消除竞态。
示例代码:
void Startup_Task(void *pvParameters) { // 先搞定所有共享资源的初始化 I2C_Control_Init(); // 再逐个创建子任务 xTaskCreate(TaskA, "TaskA", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL); xTaskCreate(TaskB, "TaskB", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL); // 启动任务完成使命,删除自己就行 vTaskDelete(NULL); }
这种方案最简单可靠,没有任何额外的同步开销,是最优解。
方案2:给初始化函数加全局初始化互斥锁
如果因为某些原因(比如资源只被特定任务用到,不想提前初始化)必须让子任务自己触发初始化,那可以给整个I2C_Control_Init函数加一个全局的初始化互斥量,确保同一时间只有一个任务能进入初始化逻辑。
示例代码:
// 全局初始化互斥量,必须在子任务启动前创建 SemaphoreHandle_t xI2CInitMutex = NULL; void Startup_Task(void *pvParameters) { // 先创建初始化互斥量 xI2CInitMutex = xSemaphoreCreateMutex(); configASSERT(xI2CInitMutex); // 确保创建成功 // 再创建子任务 xTaskCreate(TaskA, "TaskA", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL); xTaskCreate(TaskB, "TaskB", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL); vTaskDelete(NULL); } void I2C_Control_Init(void) { // 先获取初始化互斥量,阻塞等待直到拿到 if (xSemaphoreTake(xI2CInitMutex, portMAX_DELAY) == pdPASS) { for(int i2c_control = 0; i2c_control < I2C_CONTROL_NUM; i2c_control++) { if (NULL == i2c_control_mutex[i2c_control]) { i2c_control_mutex[i2c_control] = xSemaphoreCreateMutex(); configASSERT(i2c_control_mutex[i2c_control]); } } // 释放互斥量,让其他任务可以进入 xSemaphoreGive(xI2CInitMutex); } return; }
注意:这个初始化互斥量必须在子任务启动前就创建好,不然还是会有竞态风险。
方案3:使用FreeRTOS静态初始化(可选)
如果你的FreeRTOS版本支持静态内存分配,可以用xSemaphoreCreateMutexStatic来预分配互斥量的内存,这样初始化时就不需要动态创建,直接初始化静态对象即可,也能避免竞态。不过这种方案需要提前规划内存,灵活性稍差。
总结
你的担忧完全成立,这种“检查-创建”的间隙确实会导致严重的竞态问题。最推荐方案1,把共享资源初始化放在子任务创建之前;如果有特殊限制,再用方案2的全局互斥保护。
内容的提问来源于stack exchange,提问作者Bobby
相关产品推荐
相关产品推荐

