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.

TI RTOS - Using i2c in multiple tasks



Hello,

I am new in RTOS, so the best is to ask first than code second. I have two I2C devices, call them A and B and being used in their tasks, Task_A and Task_B.

What I have:

When I call i2c_open() function in Task A to initialize the comm. for device A, I got an error when I trying to call the i2c_open() for device B in Task B. I suppose, when I initialized the peripheral I don't need to do it again.

Problems/Questions:

  • Should I share the result of i2c_open for both tasks and then create two independent i2cParams and Transaction of both tasks?
  • Or should I create a third task called: i2C_Comm and use mailboxes to send and receive data. Messagebox element should contain the i2c address and the data/reply.

I have attached a simple drawing for better understanding ;)

Thank you for your suggestions and reply

  • Hi Daniel, you can't open i2c more one time, before close the same i2c.
    You can use Semaphores to control who can access the i2c, thus, only one task can access the i2c a time.

    Tiago
  • Hey,
    Thank you for your reply. I suppose the lower figure is the right choice.

    PS.: I miss an example that demonstrates the shared I2C bus usage. But this is my personal opinion.

    All the best,
  • Are you talking about different I2C peripherals (e.g. I2C0 and I2C3) or different endpoints addresses on the same I2C peripheral.

    Different Endpoints on the same peripheral

    For this, there can only be 1 open per I2C and then share the handle. Note: the I2C module protects a single transfer. If you need to have multiple transfers to the same endpoint be atomic, then you have to manage that with a semaphore as noted by a previous post.

    Different peripherals

    Do you want to open I2C A in task A and I2C B in task B? This is supported as expected. Here is the pseudo-code:

    TaskA
    {
        I2C_Params i2cParams;
        I2C_Handle i2cHandle;

        I2C_Params_init(&i2cParams);
        //fill in params as needed
       i2cHandle = I2C_open(indexA, &i2cParams);
       ...
    }

    TaskB
    {
        I2C_Params i2cParams;
        I2C_Handle i2cHandle;

        I2C_Params_init(&i2cParams);
        //fill in params as needed
       i2cHandle = I2C_open(indexB, &i2cParams);
       ...
    }

    Todd

  • Hello Todd,

    This is what I have been waiting for. Complete answer.
    I have different endpoints (i2c addresses) on the same peripheral. I thought (now I know wrong) that I have to manage them as you show in Different peripheral, but I always got an error when I called the i2c_open() 2nd time.
    Now, I created a task called I2C_Communication where I initialized the I2C. I am using MailBoxes and (Queues+Semaphores) to send data to and receive from i2C network. (Its a kind of producer - consumer design instead of shared resources.)

    I hope, using synchronization tools doesn't decrease the application performance very much.

    Thank you for your reply,

    UPDATE: I think your example should be inserted into the RTOS User Guide

  • Hi Daniel,

    I'm glad you got the answer you were looking for.

    Daniel Vamos said:
    I am using MailBoxes and (Queues+Semaphores) to send data to and receive

    Please note that Mailbox is really just two queues (full queue and free queue) ,  two semaphores (one to manage the full queue and one to manage the free queue) and N msgs of size S (where N and S are specified when you create the Mailbox instance). Mailbox is copied based, so if the messages are large, it's better to just pass the pointer to the buffer/struct and the size of buffer/struct. This will help your performance.

    Todd