Suspending a thread also blocks I2C

Hello,

I have a thread that is reading sensor data over I2C. When I suspend it I cant access I2C from another thread that's reading another I2C device. 

I tried isolating the I2C read function with mutex so only one device can access it at a time and when thread goes to sleep to release the mutex but it did not help.

Any ideas why?

Regards, 

Parents
  • Hello,

    Can you please share some snippets showing the issue? Or perhaps an application that I can build and run on a DK to replicate the issue?

    Are you finished reading the I2C before going to sleep? Or were you interrupted by another thread?

    Best regards,

    Edvin

  • code is part of huge project. 

    I have two I2C devices connected. 

    One is Accelerometar

      const struct i2c_dt_spec spec = {
        .bus  = dev_I2C,
        .addr = 0x6A
      };
    other is RTC
    const struct i2c_dt_spec spec_rtc = {
       .bus  = dev_I2C,
       .addr = 0x68
    };
    Accelerometar is beeing read in its thread by calling 
    static inline int readSensorData(int16_t* acceleration, int16_t* angular_rate) {
      // unsigned int key;
    
      // k_mutex_lock(&i2c_access_mutex, K_FOREVER);
      // key = irq_lock();
    
      int err = lsm6dso_acceleration_raw_get(gdev, acceleration);
      if (err) {
        printf("Error reading acceleration: %d\n", err);
        return err;
      }
    
      err = lsm6dso_angular_rate_raw_get(gdev, angular_rate);
      if (err) {
        printf("Error reading gyroscope: %d\n", err);
        return err;
      }
    
      // irq_unlock(key);
      // k_mutex_unlock(&i2c_access_mutex);
      return 0;
    }
    

    without success. When I suspent that thread and try to read RTC the entire device hangs without any errors. 
  • readSensorData  works fine, I can suspend it and resume it and it works, that part is not an issue. But when I suspend the thread thats reading it. 

    readSensorData is read from thread get_Gyro within while(1). I need that data as fast as LSM can provide. 

    if I suspend that thread I cant access I2C from main thread that (with issued command) reads RTC. If I unsuspend getGyro thread I can read the RTC. 

     

  • What exactly do you mean by suspending the thread? How do you do it? Can you please share some snippets?

    Best regards,

    Edvin

  • void suspendThreads(struct k_thread* notifThread, struct k_thread* gyroThread, struct k_thread* adcThread) {
      k_thread_suspend(notifThread);
      k_thread_suspend(gyroThread);
      adc_thread_pause = true;
      // Wait a short period to ensure the ADC thread has paused corectly
      k_sleep(K_MSEC(200));
      k_thread_suspend(adcThread);
      k_timer_stop(&notification_timer);
    }

  • I understand very little of this. None of the names from this list matches anything that you posted in the earlier snippets. Perhaps you can upload the entire application, and let me know what file and line number things stop working?

    Best regards,

    Edvin

  • Solved it by using semaphore to pause the thread instead of suspending. 

        // Check if the thread should be paused
        if (k_sem_count_get(&gyro_thread_sem) == 1) {
          // Wait on the semaphore if a pause is requested
          k_sem_take(&gyro_thread_sem, K_FOREVER);
        }

Reply Children
No Data
Related