I’m a beginner to FreeRTOS but not to Softwaredevelopment.
I got a ESP32 witch I want to add a keypad and a display, both using I2C-Bus.
What I was thinking about is to create a task for each peripheral (display, keypad) and share my I2C-Class instance between it. Unfortunately I do not get it to work.
What do you recomment to have the best solution? Is it OK to use tasks or is there a better way? Sharing the I2C Instance seams to result in a memory issue.
Appreaciate your tipps and tricks. Thanks a lot.
Make sure your I2C driver uses some form of protection from multiple tasks trying to access it at once. My I2C class uses a mutex to enforce only a single task using a given controller at a time.
Or alternatively do all low level/raw I2C device handling in 1 task having exclusive ownership and access to the bus (no need for mutex protection by design) and communicate to 1 or more higher level task(s) doing the application logic.
Yes, you can dedicate the I2C controller to a single task, and then not need a mutex, but I find that rarely developed into a cleaner design, though this may be due to the types of systems I tend to have. I find that there tends to be a multiplicity of I2C devices that need to be serviced, each one at its own rate. This makes it hard to have a single task have knowledge of all the requests that need to be made, so it becomes a case of each task needing to send a message to the ‘I2C Task’, which does the operations via a queue and sends results back to the task that blocked for it. This replaces the Mutex with the request Queue as the synchronizer, which is less flexible (strict order, no priority management) and adds the overhead of a task to the system. A simple call to function with a mutex is much less complicated.
Note also, since the interface is done via a function, it could easily be changed to have that function do the use a queue to talk to a task instead, if that turned out better for some application.