C语言指针传值:I2C_Transfer调用后预期值未更新问题
问题分析:I2C_Transfer调用后立即读取数据未更新的异常
我实现了一个read_reg函数,通过指针参数data接收I2C_Transfer库函数返回的寄存器值,调用后立即打印解引用后的*data:
static bool read_reg(uint8_t reg, uint8_t *data) { bool success = I2C_Transfer(appData.drvI2CHandle, APP_OV2640_SENSOR_I2C_ADDR, (void *)®, sizeof(reg), (void *)data, sizeof(uint8_t)); printf("after I2C_Transfer(%02x), *data = 0x%02x\r\n", reg, *data); return success; }
调用代码如下:
uint8_t vid = 0x55; // 预初始化用于调试 printf("before read_reg(), vid = 0x%02x\r\n", vid); read_reg(0x0a, &vid); printf("after read_reg(), vid = 0x%02x\r\n", vid);
运行输出:
before read_reg(), vid = 0x55 // 符合预期 after I2C_Transfer(0a), *data = 0x55 // 预期应为0x26 after read_reg(), vid = 0x26 // 符合预期
其中vid=0x26是寄存器的正确值,但read_reg内调用I2C_Transfer后立即打印的*data却还是初始值0x55,函数返回后vid才更新为正确值。
排查过程与结论
- 编写I2C_Transfer桩函数模拟测试,结果符合预期(调用后立即读取能得到正确值);
- 查看I2C_Transfer的实际实现
DRV_I2C_WriteReadTransfer,文档标注该函数为同步阻塞函数; - 最终确认是厂商库bug:该函数并未真正阻塞到所有数据接收完成,而是在最后一个数据字节接收前就提前返回,剩余的数据更新操作是后续由中断服务程序完成的。
现象解释
当read_reg中调用I2C_Transfer后立即打印*data时,中断还未触发,目标内存(即vid的地址)还未被更新,因此打印的是初始值0x55;当read_reg函数返回后,中断已经完成数据写入操作,此时读取vid就能得到正确的0x26。
内容的提问来源于stack exchange,提问作者fearless_fool
相关产品推荐
相关产品推荐

