80 likes | 227 Vues
This resource delves into the principles of message passing within embedded systems, as taught in the EECE 354 course at Vanderbilt University in Fall 2010. It emphasizes the advantages of using message queues for inter-task communication over global variables. Key concepts include creating standalone queues, FIFO/LIFO message handling, and managing task synchronization through semaphores to avoid overflow situations. The document also illustrates practical applications, such as error reporting via clients (ISRs) to a single error handler (server), and provides API examples for queue operations.
E N D
Message Passing Akos Ledeczi EECE 354, Fall 2010 Vanderbilt University
Message Queues • Inter-task communication • Usually better practice than using global variables • Message queues are used to manage messages • Standalones queues • Each task has a built-in queue • Messages are passed by reference, that is, no copy is ever made!!! Must remain in scope!!! • Default is FIFO, but optionally LIFO can be used for important messaged to bypass waiting messages in the queue • Multiple tasks can Pend() on a queue. Post() can optionally broadcast to all waiting tasks
Bilateral Rendezvous • Using tasks queues in this case • Just like semaphores, but can pass data as well
Flow Control • Message producer may produce faster than consumer can consume • To prevent overflowing the message queue, a semaphore helps manage the resource • Using a task semaphore and a task queue in this case
Clients and servers • Different tasks/ISRs (clients) report different error conditions • Single error handler (“server”) processes the reports
Example • Measure RPM using a hole in the disk • A free running counter is used to measure the time between two hole detections • ISR shouldn’t be used to compute average, maximum, etc. • Task may be low priority in the system, so a message queue is used to store measurements until they can be processed
Usage OS_Q MyQ; MyMsgDataMyMsg; OSQCreate(&MyQ, “My Queue”, 10, /* max queue size */ &err); … OSQPost(&MyQ, (void *)&MyMsg, /* actual data to send */ /* DANGER: using a global */ sizeof(MyMsg), OS_OPT_POST_FIFO, &err); … OSQPend(&MyQ, 1000, /* timeout */ OS_OPT_PEND_BLOCKING, &size, &ts, &err); if (err == OS_ERR_TIMEOUT) { … API: OSQCreate() OSQPend() OSQPost() OSQFlush() OSQPendAbort() OSQDel()