Search code examples
cembeddedtaskrtosfreertos

Preffered: Suspend all tasks OR mutex when accessing shared resource ? [freeRTOS]


Assume we have a c-code that has a function that takes char[s] as an argument, and stores it in a ring buffer. The ring buffer in turn is read from an interrupt handler in that c-code. One char/interrupt is transmitted over uart.

We have several tasks. On many occassions they want to write over the uart. Due to the ring buffer being a shared resource we have to pay attention not to let the tasks write to it simultaneously.

1. By natural, my mind says use mutex/semaphores. However .. This will be very very messy to have the conditions at many places.

2. Another idea tells me to suspend all tasks within that area. But ... that's not really efficient for the system. And suspending tasks at that level doesn't feel fine either. I'd rather only play with tasks within tasks.

3. Another idea just flew into my head. Create another task that handles specifially the uart? But that is like throwing away alot of memory just for creating a reserved stack for this task :P

Which of the three suggestions would you recommend?


Solution

  • I use one thread that handles all I/O, (OK, except SD-card). This IOthread waits on a semaphore. Any interrupt-handler that requires attention, (eg. it has queued up stuff in its own, private ring buffer), signals the semaphore. Any other thread that requires I/O action queues up requests to a single thread-safe 'IOrequest' queue and signals the semaphore.

    When the IO thread runs, it polls the IOrequest queue and all the I/O queues/buffers/whatever associated with the devices and their interrupt-handlers. One of them will need something doing, (because a unit has been posted to the semaphore), and the thread does it. Not finding anything to do is an error.

    Using one thread for I/O management simplifies the interactions with the queues to/from the interrupt-handlers. The designs of queues etc. is easier if only one thread and one interrupt-handler get to use it. Debugging is much easier since you only need to look at one thread.

    It's worth an extra stack just for the ease of debugging:)