Creating a mutex pulls I2C clock line down

Hi!

I am running into the issue if I create a mutex before I try to read EEPROM that is connected to the I2C bus, the action pulls the clock line down and leaves the code hanging. I am using xSemaphoreCreate() function provided by FreeRTOS, but have also tried xSemaphoreCreateBinary() and xSemaphoreCreateCounting(). The static versions of the semaphores did not work either. I am using the I2C library provided by FreeScale Semiconductor. Attached is a picture showing the mutex was successfully created, then an attempt to read EEPROM on the I2C bus was made and pulls the clockline low.

Was wondering if anyone could provide some insight to this, thanks!

Sophy

Better use xSemaphoreCreateMutex if you want mutex protection.
FreeRTOS doesn’t and can’t affect your I2C driver directly.
There must be another problem in your application resp. in the I2C driver.
Did you try to step through the code to see what’s going on ?
Did you verify that the Freescale driver (still) works at all ?
I’d add the mutex protection and multitasking access as 2nd step testing proper mutex protection.

Hi Hartmut, thank you for your reply! Yes I am using xSemaphoreCreateMutex for mutex protection (sorry for the typo in the original post). This is creating a brand new mutex (not taken/given anywhere in the code). This issue occurs before the FreeRTOS scheduler has started, and this is the code that performs the EEPROM read:

I2C_MasterTransferCreateHandle(I2C_0_PERIPHERAL, &i2cHandle, EEPROMMasterCallback, (void*)&i2c_status);
I2C_MasterTransferNonBlocking(I2C_0_PERIPHERAL, &i2cHandle, &i2cTransfer);

    while(i2c_status == -1){
      if(count++ > I2C_TIMEOUT_COUNT){
        /* read has timed out */
        printf("EEPROM Read Timed Out! Aborting.\r\n");
        return false;
      }
    }

I have tried stepping through the code and the problem happens because i2c_status stays -1 during the transfer and the read times out. I have noticed that the first byte gets transferred and acknowleged (since the return code of the non blocking transfer is successful), but the clock line gets pulled low indefinitely afterwards. I have confirmed that this same transfer succeeds if the mutex is created after the EEPROM read or the scheduler has started. Is there the possibly some configuration needs to be done in the FreeRTOS config file beforehand?

It’s an important information that the scheduler isn’t started yet when this problem happens. See e.g. this post Using Mutex before scheduler starts - #2 by rtel describing that interrupts might get disabled when calling FreeRTOS API before it’s running.
So if the I2C driver makes use of interrupts (I think it does) and the interrupt priority is in the range (logically) covered by configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY it won’t work.
It’s not a configuration issue. The problem is a side effect using FreeRTOS before it’s started.
You could implement an alternative ‘early boot’ version of the EEPROM read function without using the mutex or can you move the call into a (main) task running after the scheduler has started.
I’m using the second approach to do some task preparations right before entering the task (forever) loop.

1 Like