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.

RTOS/LAUNCHXL-CC1310: Deadlock when two Tasks share I2C? (with suspected bug cause and potential solutions)

Part Number: LAUNCHXL-CC1310

Tool/software: TI-RTOS

Hi,


I'm having an issue where my tasks are deadlocking inside i2c_close.

I currently have TI-RTOS v2.21.00.06.

I have two tasks that alternately try to talk to devices on the same I2C bus. In each task, I try to open and Task_sleep if open fails before retrying. Once the task is finished talking, it calls i2c_close on the handle it received from i2c_open.

What appears to be happening is that, when the second task calls i2c_open, handle->object->hPin is overwritten with the  NULL result of PIN_open [*1] since the pin is in use. This causes the first task to deadlock in i2c_close since the pin handle is now NULL, and PIN_close apparently deadlocks when passed a null handle since it doesn't check for NULL [*2].

*1: I2CCC26XX.c:1030:
    object->hPin = PIN_open(&object->pinState, i2cPinTable);
    if (!object->hPin) {
        return I2C_STATUS_ERROR;
    }

*2: PINCC26XX.c:448:
    // No need for sequencing accesses to PIN_close()
    // For each pin in port bitmask
    while (handle->bmPort) {
        // Find lowest index pin
        i = PIN_ctz(handle->bmPort);
        // Deallocate pin
        PIN_remove(handle, i);
    }


It seems to me that using a temporary variable at I2CCC26XX.c:1030 instead of writing directly into the (potentially already open) i2c object would solve this.

Alternatively, check if the pin handle is non-null and return error if so, without overwriting a valid handle with the NULL result of a failed PIN_open.

Furthermore, PIN_close should check for null pointer and respond appropriately.

I haven't tried any of these solutions since CCS apparently won't let me edit the files in question. They were marked read only, and changing their permissions to read-write and applying appropriate edits seems to have no effect except for making the debugger confused. I tried altering my build config as per but this also had no apparent effect. How can I make CCS try my altered files?

In the meantime I can use a semaphore to work around this bug..

    // No need for sequencing accesses to PIN_close()
    // For each pin in port bitmask
    while (handle->bmPort) {
        // Find lowest index pin
        i = PIN_ctz(handle->bmPort);
        // Deallocate pin
        PIN_remove(handle, i);
    }

  • Hi Kevin,
    I'm not sure how this deadlock can be happening, since the task that closes the I2C (calling PIN_remove) sets object->isOpen to false only after the object is de-initialized. Any other call to I2C_open() would return NULL as long as object->isOpen is true.
    To test your changes to driver code in CCS, copy the file (e.g. I2CCC26XX.c) to your project. Then you will link in the code from the copied file and don't have to rebuild the driver library.
    Best regards,
    Janet