在ESP32双核下,Arduino loopTask运行在Core1,自定义FreeRTOS任务可能运行在Core0或Core1。共享I2C总线时,若两任务同时调用Wire库的beginTransmission/endTransmission,会因内部状态机(如txBufferIndex)被并发修改导致数据错乱或总线锁死。复现方法:在loopTask和自定义任务中均以高频率读写同一I2C设备(如OLED),不加保护运行数秒即可观察到NACK或数据异常。修复需组合互斥锁与临界区:首先创建互斥量(xSemaphoreCreateMutex),在每次I2C事务前xSemaphoreTake、后xSemaphoreGive,确保总线访问串行化;其次,对Wire库内部共享变量(如txBuffer)的修改需用portENTER_CRITICAL/portEXIT_CRITICAL包裹,防止任务切换导致中间状态被破坏。注意临界区应尽量短,仅保护缓冲区操作,而互斥锁覆盖整个事务。示例代码:在任务中先取互斥量,再进入临界区填充缓冲区,退出临界区后调用endTransmission,最后释放互斥量。这样既避免死锁又保证原子性。