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

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 *)&reg, 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:42:51