This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TDA4VM: i2c

Part Number: TDA4VM

HI TI:

我们在使用tda4vm 7.3sdk上面,当我同时运行vx_app_single_cam和另一个摄像头相关的进程,会出现i2c操作timeout的情况,因为两个进程有可能会同时去操作i2c,从而导致i2c操作异常,请问有解决方法吗

已知我们必须让两个进程这样来运行,不能调整其运行顺序

  • 请问有解决方法吗

    1. 使用锁(Lock):在代码中使用锁机制,确保同一时间只有一个进程能够访问I2C总线。当一个进程在访问I2C时,其他进程必须等待锁的释放。

    from multiprocessing import Lock
    
    # 在代码中定义锁
    i2c_lock = Lock()
    
    # 在需要访问I2C的地方使用锁
    with i2c_lock:
    # 执行I2C操作的代码

    2. 用 IPC:用进程间通信机制,例如消息队列或共享内存,在进程之间共享I2C访问的状态信息。通过在共享数据上加锁,确保只有一个进程能够修改共享的I2C状态。

    3. 分配独立的I2C总线:为每个进程分配独立的I2C总线。可以避免进程之间的冲突。

    4. 调整I2C设备地址:每个进程中使用不同的I2C设备地址,从而避免冲突。

    5. 选择支持多主机模式的I2C总线设备,或者使用I2C多路复用器来隔离不同进程的I2C访问。

  • HI Lu

    非常高兴收到回复,请问有mcu2_0上的i2c锁的参考吗

  • 您好,抱歉我目前没有找到参考,我通过个人理解为您写了一段示例代码框架,用互斥锁来保护多任务下的I2C访问,请参考。

    // 假设I2C设备地址
    #define I2C_DEVICE_ADDRESS 0x50
    
    // 定义全局互斥锁
    SemaphoreHandle_t i2cMutex;
    
    // 模拟I2C读取函数
    void simulated_i2c_read() {
    // 模拟I2C读取操作
    // ...
    }
    
    // 模拟I2C写入函数
    void simulated_i2c_write() {
    // 模拟I2C写入操作
    // ...
    }
    
    // 1:读取I2C数据
    void task_read_i2c(void *pvParameters) {
    while (1) {
    // 尝试获取I2C互斥锁
    if (xSemaphoreTake(i2cMutex, portMAX_DELAY)) {
    // 执行I2C读取操作
    simulated_i2c_read();
    
    // 释放I2C互斥锁
    xSemaphoreGive(i2cMutex);
    }
    
    // 任务延时
    vTaskDelay(pdMS_TO_TICKS(1000));
    }
    }
    
    // 2:写入I2C数据
    void task_write_i2c(void *pvParameters) {
    while (1) {
    // 尝试获取I2C互斥锁
    if (xSemaphoreTake(i2cMutex, portMAX_DELAY)) {
    // 执行I2C写入操作
    simulated_i2c_write();
    
    // 释放I2C互斥锁
    xSemaphoreGive(i2cMutex);
    }
    
    // 任务延时
    vTaskDelay(pdMS_TO_TICKS(500));
    }
    }
    
    int main(void) {
    // 初始化I2C互斥锁
    i2cMutex = xSemaphoreCreateMutex();
    
    // 创建任务
    xTaskCreate(task_read_i2c, "ReadI2C", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
    xTaskCreate(task_write_i2c, "WriteI2C", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
    
    // 启动调度器
    vTaskStartScheduler();
    
    
    while (1) {
    }
    
    return 0;
    }

    如有问题欢迎您的指正,谢谢

  • 你好,我的代码如下

    SemaphoreP_Params params;
    static SemaphoreP_Handle gI2cSem;
    i2c_init()
    {
    SemaphoreP_Params_init(&params);
    params.mode = SemaphoreP_Mode_BINARY;
    gI2cSem = SemaphoreP_create(1U, &params);
    }
    i2c_write()
    {
    SemaphoreP_pend(gI2cSem,SemaphoreP_WAIT_FOREVER);
    status = Board_i2c16BitRegWr(sensorI2cHandle, i2cAddr, regAddr, &regVal, 1, sensorI2cByteOrder, SENSOR_I2C_TIMEOUT);
    if(0 != status)
    {
    printf("Error : I2C Timeout while writing: i2chandle[%d]\n", i2cInstId);
    }
    SemaphoreP_post(gI2cSem);
    }

    错误打印如下:

    [MCU2_0]   1604.296556 s: Error : I2C Timeout while writing: i2chandle[1]
    [MCU2_0]   1604.296673 s: Error : I2C Timeout while writing: i2chandle[1]
    [MCU2_0]   1604.296787 s: Error : I2C Timeout while writing: i2chandle[1]
    [MCU2_0]   1604.296901 s: Error : I2C Timeout while writing: i2chandle[1]

  • 看起来是I2C总线上有问题。你可以排查一下:硬件连接、I2C配置、I2C设备状态、中断

    再者:I2C API返回值的错误处理。我看你检查了`status`是否为0,但你还要需要查看一下具体的错误代码

    最后:在调试时,你可以尝试先简化你的代码,只保留最基本I2C访问,确保在最简单的情况下没有超时问题。然后逐步添加其他功能