Page 1 of 1

I2C multitrading

Posted: Thu Feb 03, 2022 7:54 pm
by Tuxford
Hi,
I use i2c software driver (fallback) in my project. But when i2c is used from different thread I am receiving chSysHalt
Stack:

Code: Select all

Thread #16 536912464 (Name: spindle, State: CURRENT) (Suspended : Signal : SIGTRAP:Trace/breakpoint trap)   
   chSysHalt() at chsys.c:199 0x801658e   
   chMtxLockS() at chmtx.c:216 0x80189ac   
   chMtxLock() at chmtx.c:124 0x80188d0   
   osalMutexLock() at osal.h:994 0x801153c   
   i2cAcquireBus() at hal_i2c.c:265 0x80117cc   
   TLV493D_A1B6_read_regs() at TLV_A1B6_driver.c:40 0x801e59c   
   TLV493D_A1B6_read_frame() at TLV_A1B6.c:232 0x801ea36   
   hall3d_read() at hall3d.c:47 0x801dea4   
   _spindle_handle_trigger_value() at spindle.c:51 0x8027c0e   
   spindle_thd() at spindle.c:81 0x8027cbe   
   <...more frames...>   


Problem is because different threads.

Code: Select all

chDbgAssert(mp->owner == ctp, "not owner");


How to workaround this problem without additional threads?

Re: I2C multitrading

Posted: Thu Feb 03, 2022 9:42 pm
by Giovanni
Hi,

You need to make sure that the thread doing i2cAcquireBus() is the same thread doing i2cReleaseBus(). You cannot do acquire from one thread and release from another. Each thread needs to acquire, do operations and finally release.

Giovanni

Re: I2C multitrading

Posted: Fri Feb 04, 2022 7:40 am
by Tuxford
I understand it. This is property of mutex.
But in my case problem occurs on acquiring, not releasing.

Code: Select all

void chMtxLockS(mutex_t *mp) {
//....
      /* It is assumed that the thread performing the unlock operation assigns
         the mutex to this thread.*/
->      chDbgAssert(mp->owner == ctp, "not owner");

It looks a first thread acquired the bus is only allowed to use it.

Re: I2C multitrading

Posted: Fri Feb 04, 2022 9:02 am
by Giovanni
Hi,

This is not the normal behavior, please check for possible stack overflows corrupting things.

Giovanni

Re: I2C multitrading

Posted: Fri Feb 04, 2022 12:38 pm
by Tuxford
Problem was in acquiring and releasing of i2c bus.
I added retry count if i2c operation fails. It looks:

Code: Select all

    const I2CConfig* cfg = i2cp->config;
    while((rs != 0) && (retries < 5)) {
        rs = i2cMasterReceiveTimeout(i2cp, addr, rxbuf, rxbytes, timeout);

        if (rs != 0) {
            i2cStop(i2cp);
            i2cObjectInit(i2cp);
            i2cStart(i2cp, cfg);
            retries++;
        }
        else
            break;
    }

Acquiring and releasing is in caller of this function. When it i2cObjectInit is called bus mutex is reinitialized and next call of i2cAcquireBus/i2cAcquireBus fails because owner is already different.

I implemented own lock stead of library's one.
It seems it works.