Reputation: 15648
I have following C problem:
I have a hardware module that controls the SPI bus (as a master), let's call it SPI_control, it's got private (static
) read & write and "public" Init()
and WriteRead()
functions (for those who don't know, SPI is full duplex i.e. a Write always reads data on the bus). Now I need to make this accessible to higher levekl modules that incorporate certain protocols. Let's cal the upper modules TDM and AC. They run in two separate threads and one might not be interrupted by the other (when it's in the nmiddle of a transaction, it first needs to complete).
So one possibility I thought of, is to incorporate a SPI_ENG inbween the modules and the SPI_control which controls data flow and know what can be interrupted and what can't - it would then forward data accordingly to spi_control. But hwo can the independent tasks AC & **TDM talk to spi_control, can I have them to write to and read from some kind ok Semaphore queue? How is should this be done?
Upvotes: 1
Views: 238
Reputation: 958
Its not exactly clear what you are trying to do, but a general solution is that your two processes (AC and TDM) can write data in their own separate output queues. A third process can act as a scheduler and read alternatively from these queue and write on to the HW (SPI_control). This may be what you are looking for since the queues will also act as elasticity buffers to handle bursty transactions. This ways you will not have to worry about AC getting preempted TDM, there should be no need for Mutex's to synchronize the accesses to SPI_Control.
Queues in kernel are implemented using kernel semaphores. A Queue is an array of memory guarded by an kernel semaphore.
What I would do is create a control msg queue for the Scheduler tasks. So now system will have 3 queue. 2 data output queues for AC, TDM process and one Control queue for Scheduler task. During system startup scheduler task will start before AC and TDM and pend on its control queue. The AC and TDM process should send "data available" msg to scheduler task over the control queue whenever their queue goes non empty (msgQNumMsgs()). On receiving this msg, the scheduler task should start reading from the specific queue until it is empty and again pend on the control queue. The last time I worked on vxworks(2004), it had a flat memory model, in which all the global variables were accessible to all tasks. Is it this the case? If yes then you can use global variable to pass queue Id's between tasks.
Upvotes: 2
Reputation: 30146
I would simply use a Mutex on each SPI operation:
SPI_Read()
{
MutexGet(&spiMutex);
...
MutexPut(&spiMutex);
}
SPI_Write()
{
MutexGet(&spiMutex);
...
MutexPut(&spiMutex);
}
Make sure that you initialize the Mutex with priority-inheritance enabled, so that it can perform priority-inversion whenever needed.
Upvotes: 1