Writing code for an embedded platform on Zephyr RTOS.
To paint the picture of the situation I am trying to resolve: I have data coming in over UART, and I have a handler for the incoming data. I want to:
Notify all threads that new data has come in
Have a mechanism where all the threads have an opportunity to access this data. For simplicity the data is stored in a global struct.
I am trying to figure out a solution where threads can "subscribe" or "register" to a particular event or signal and then once they are aware that new data comes in, they can go ahead and call some function to access it, in which a mutex will be used to lock the data being accessed to one thread at a time and perhaps does a memcpy()
to copy the data from the global struct into one the thread wishes to use.
I tried multiple solutions but seem to stuck in the fact that a maximum of one thread only ever receives a chance to access the data each time the event handler is triggered.
For example, I used k_poll
and signal raising to signal when new data came in. I had multiple threads initialize an event which used the shared signal. One thread (perhaps with a higher priority) will always get access first and then reset the signal, resulting in the other threads missing the data.
I also tried using a counting semaphore. However, a thread with the highest priority always gets the data and the other threads are unable to read it.
I thought about making a linked list of polling signals, and then just iterating through it when new data came in and raising each signal individually. This way each thread can depend on a unique signal and have the ability to access the data. But I was worried that perhaps data can be overwritten before a thread has a chance to read the data.
My question is what is an implementation that will work for this?
You can use zbus to create a channel and notify multiple subscribers on that channel whenever there is new data by publishing the a message on the channel.
Just make sure to not publish under an ISR, if you need to do it under an ISR make sure to differ the publishing to something like a workqueue.