source: rtems-docs/ada_user/message_manager.rst @ 1a1be7f

4.115
Last change on this file since 1a1be7f was 4783b0d, checked in by Amar Takhar <amar@…>, on 01/17/16 at 16:37:28

Split document into seperate files by section.

  • Property mode set to 100644
File size: 23.9 KB
Line 
1Message Manager
2###############
3
4.. index:: messages
5.. index:: message queues
6
7Introduction
8============
9
10The message manager provides communication and
11synchronization capabilities using RTEMS message queues.  The
12directives provided by the message manager are:
13
14- ``rtems.message_queue_create`` - Create a queue
15
16- ``rtems.message_queue_ident`` - Get ID of a queue
17
18- ``rtems.message_queue_delete`` - Delete a queue
19
20- ``rtems.message_queue_send`` - Put message at rear of a queue
21
22- ``rtems.message_queue_urgent`` - Put message at front of a queue
23
24- ``rtems.message_queue_broadcast`` - Broadcast N messages to a queue
25
26- ``rtems.message_queue_receive`` - Receive message from a queue
27
28- ``rtems.message_queue_get_number_pending`` - Get number of messages pending on a queue
29
30- ``rtems.message_queue_flush`` - Flush all messages on a queue
31
32Background
33==========
34
35Messages
36--------
37
38A message is a variable length buffer where
39information can be stored to support communication.  The length
40of the message and the information stored in that message are
41user-defined and can be actual data, pointer(s), or empty.
42
43Message Queues
44--------------
45
46A message queue permits the passing of messages among
47tasks and ISRs.  Message queues can contain a variable number of
48messages.  Normally messages are sent to and received from the
49queue in FIFO order using the ``rtems.message_queue_send``
50directive.  However, the ``rtems.message_queue_urgent``
51directive can be used to place
52messages at the head of a queue in LIFO order.
53
54Synchronization can be accomplished when a task can
55wait for a message to arrive at a queue.  Also, a task may poll
56a queue for the arrival of a message.
57
58The maximum length message which can be sent is set
59on a per message queue basis.  The message content must be copied in general
60to/from an internal buffer of the message queue or directly to a peer in
61certain cases.  This copy operation is performed with interrupts disabled.  So
62it is advisable to keep the messages as short as possible.
63
64Building a Message Queue Attribute Set
65--------------------------------------
66.. index:: message queue attributes
67
68In general, an attribute set is built by a bitwise OR
69of the desired attribute components.  The set of valid message
70queue attributes is provided in the following table:
71
72- ``RTEMS.FIFO`` - tasks wait by FIFO (default)
73
74- ``RTEMS.PRIORITY`` - tasks wait by priority
75
76- ``RTEMS.LOCAL`` - local message queue (default)
77
78- ``RTEMS.GLOBAL`` - global message queue
79
80An attribute listed as a default is not required to
81appear in the attribute list, although it is a good programming
82practice to specify default attributes.  If all defaults are
83desired, the attribute ``RTEMS.DEFAULT_ATTRIBUTES``
84should be specified on this call.
85
86This example demonstrates the attribute_set parameter
87needed to create a local message queue with the task priority
88waiting queue discipline.  The attribute_set parameter to the``rtems.message_queue_create`` directive could be either``RTEMS.PRIORITY`` or``RTEMS.LOCAL or RTEMS.PRIORITY``.
89The attribute_set parameter can be set to ``RTEMS.PRIORITY``
90because ``RTEMS.LOCAL`` is the default for all created
91message queues.  If a similar message queue were to be known globally, then the
92attribute_set parameter would be``RTEMS.GLOBAL or RTEMS.PRIORITY``.
93
94Building a MESSAGE_QUEUE_RECEIVE Option Set
95-------------------------------------------
96
97In general, an option is built by a bitwise OR of the
98desired option components.  The set of valid options for the``rtems.message_queue_receive`` directive are
99listed in the following table:
100
101- ``RTEMS.WAIT`` - task will wait for a message (default)
102
103- ``RTEMS.NO_WAIT`` - task should not wait
104
105An option listed as a default is not required to
106appear in the option OR list, although it is a good programming
107practice to specify default options.  If all defaults are
108desired, the option ``RTEMS.DEFAULT_OPTIONS`` should
109be specified on this call.
110
111This example demonstrates the option parameter needed
112to poll for a message to arrive.  The option parameter passed to
113the ``rtems.message_queue_receive`` directive should
114be ``RTEMS.NO_WAIT``.
115
116Operations
117==========
118
119Creating a Message Queue
120------------------------
121
122The ``rtems.message_queue_create`` directive creates a message
123queue with the user-defined name.  The user specifies the
124maximum message size and maximum number of messages which can be
125placed in the message queue at one time.  The user may select
126FIFO or task priority as the method for placing waiting tasks in
127the task wait queue.  RTEMS allocates a Queue Control Block
128(QCB) from the QCB free list to maintain the newly created queue
129as well as memory for the message buffer pool associated with
130this message queue.  RTEMS also generates a message queue ID
131which is returned to the calling task.
132
133For GLOBAL message queues, the maximum message size
134is effectively limited to the longest message which the MPCI is
135capable of transmitting.
136
137Obtaining Message Queue IDs
138---------------------------
139
140When a message queue is created, RTEMS generates a
141unique message queue ID.  The message queue ID may be obtained
142by either of two methods.  First, as the result of an invocation
143of the ``rtems.message_queue_create`` directive, the
144queue ID is stored in a user provided location.  Second, the queue
145ID may be obtained later using the ``rtems.message_queue_ident``
146directive.  The queue ID is used by other message manager
147directives to access this message queue.
148
149Receiving a Message
150-------------------
151
152The ``rtems.message_queue_receive`` directive attempts to
153retrieve a message from the specified message queue.  If at
154least one message is in the queue, then the message is removed
155from the queue, copied to the caller’s message buffer, and
156returned immediately along with the length of the message.  When
157messages are unavailable, one of the following situations
158applies:
159
160- By default, the calling task will wait forever for the
161  message to arrive.
162
163- Specifying the ``RTEMS.NO_WAIT`` option forces an immediate return
164  with an error status code.
165
166- Specifying a timeout limits the period the task will
167  wait before returning with an error status.
168
169If the task waits for a message, then it is placed in
170the message queue’s task wait queue in either FIFO or task
171priority order.  All tasks waiting on a message queue are
172returned an error code when the message queue is deleted.
173
174Sending a Message
175-----------------
176
177Messages can be sent to a queue with the``rtems.message_queue_send`` and``rtems.message_queue_urgent`` directives.  These
178directives work identically when tasks are waiting to receive a
179message.  A task is removed from the task waiting queue,
180unblocked,  and the message is copied to a waiting task’s
181message buffer.
182
183When no tasks are waiting at the queue,``rtems.message_queue_send`` places the
184message at the rear of the message queue, while``rtems.message_queue_urgent`` places the message at the
185front of the queue.  The message is copied to a message buffer
186from this message queue’s buffer pool and then placed in the
187message queue.  Neither directive can successfully send a
188message to a message queue which has a full queue of pending
189messages.
190
191Broadcasting a Message
192----------------------
193
194The ``rtems.message_queue_broadcast`` directive sends the same
195message to every task waiting on the specified message queue as
196an atomic operation.  The message is copied to each waiting
197task’s message buffer and each task is unblocked.  The number of
198tasks which were unblocked is returned to the caller.
199
200Deleting a Message Queue
201------------------------
202
203The ``rtems.message_queue_delete`` directive removes a message
204queue from the system and frees its control block as well as the
205memory associated with this message queue’s message buffer pool.
206A message queue can be deleted by any local task that knows the
207message queue’s ID.  As a result of this directive, all tasks
208blocked waiting to receive a message from the message queue will
209be readied and returned a status code which indicates that the
210message queue was deleted.  Any subsequent references to the
211message queue’s name and ID are invalid.  Any messages waiting
212at the message queue are also deleted and deallocated.
213
214Directives
215==========
216
217This section details the message manager’s
218directives.  A subsection is dedicated to each of this manager’s
219directives and describes the calling sequence, related
220constants, usage, and status codes.
221
222MESSAGE_QUEUE_CREATE - Create a queue
223-------------------------------------
224.. index:: create a message queue
225
226**CALLING SEQUENCE:**
227
228.. code:: c
229
230    procedure Message_Queue_Create (
231    Name             : in     RTEMS.Name;
232    Count            : in     RTEMS.Unsigned32;
233    Max_Message_Size : in     RTEMS.Unsigned32;
234    Attribute_Set    : in     RTEMS.Attribute;
235    ID               :    out RTEMS.ID;
236    Result           :    out RTEMS.Status_Codes
237    );
238
239**DIRECTIVE STATUS CODES:**
240
241``RTEMS.SUCCESSFUL`` - queue created successfully
242``RTEMS.INVALID_NAME`` - invalid queue name
243``RTEMS.INVALID_ADDRESS`` - ``id`` is NULL
244``RTEMS.INVALID_NUMBER`` - invalid message count
245``RTEMS.INVALID_SIZE`` - invalid message size
246``RTEMS.TOO_MANY`` - too many queues created
247``RTEMS.UNSATISFIED`` - unable to allocate message buffers
248``RTEMS.MP_NOT_CONFIGURED`` - multiprocessing not configured
249``RTEMS.TOO_MANY`` - too many global objects
250
251**DESCRIPTION:**
252
253This directive creates a message queue which resides
254on the local node with the user-defined name specified in name.
255For control and maintenance of the queue, RTEMS allocates and
256initializes a QCB.  Memory is allocated from the RTEMS Workspace
257for the specified count of messages, each of max_message_size
258bytes in length.  The RTEMS-assigned queue id, returned in id,
259is used to access the message queue.
260
261Specifying ``RTEMS.PRIORITY`` in attribute_set causes tasks
262waiting for a message to be serviced according to task priority.
263When ``RTEMS.FIFO`` is specified, waiting tasks are serviced
264in First In-First Out order.
265
266**NOTES:**
267
268This directive will not cause the calling task to be
269preempted.
270
271The following message queue attribute constants are
272defined by RTEMS:
273
274- ``RTEMS.FIFO`` - tasks wait by FIFO (default)
275
276- ``RTEMS.PRIORITY`` - tasks wait by priority
277
278- ``RTEMS.LOCAL`` - local message queue (default)
279
280- ``RTEMS.GLOBAL`` - global message queue
281
282Message queues should not be made global unless
283remote tasks must interact with the created message queue.  This
284is to avoid the system overhead incurred by the creation of a
285global message queue.  When a global message queue is created,
286the message queue’s name and id must be transmitted to every
287node in the system for insertion in the local copy of the global
288object table.
289
290For GLOBAL message queues, the maximum message size
291is effectively limited to the longest message which the MPCI is
292capable of transmitting.
293
294The total number of global objects, including message
295queues, is limited by the maximum_global_objects field in the
296configuration table.
297
298MESSAGE_QUEUE_IDENT - Get ID of a queue
299---------------------------------------
300.. index:: get ID of a message queue
301
302**CALLING SEQUENCE:**
303
304.. code:: c
305
306    procedure Message_Queue_Ident (
307    Name   : in     RTEMS.Name;
308    Node   : in     RTEMS.Unsigned32;
309    ID     :    out RTEMS.ID;
310    Result :    out RTEMS.Status_Codes
311    );
312
313**DIRECTIVE STATUS CODES:**
314
315``RTEMS.SUCCESSFUL`` - queue identified successfully
316``RTEMS.INVALID_ADDRESS`` - ``id`` is NULL
317``RTEMS.INVALID_NAME`` - queue name not found
318``RTEMS.INVALID_NODE`` - invalid node id
319
320**DESCRIPTION:**
321
322This directive obtains the queue id associated with
323the queue name specified in name.  If the queue name is not
324unique, then the queue id will match one of the queues with that
325name.  However, this queue id is not guaranteed to correspond to
326the desired queue.  The queue id is used with other message
327related directives to access the message queue.
328
329**NOTES:**
330
331This directive will not cause the running task to be
332preempted.
333
334If node is ``RTEMS.SEARCH_ALL_NODES``, all nodes are searched
335with the local node being searched first.  All other nodes are
336searched with the lowest numbered node searched first.
337
338If node is a valid node number which does not
339represent the local node, then only the message queues exported
340by the designated node are searched.
341
342This directive does not generate activity on remote
343nodes.  It accesses only the local copy of the global object
344table.
345
346MESSAGE_QUEUE_DELETE - Delete a queue
347-------------------------------------
348.. index:: delete a message queue
349
350**CALLING SEQUENCE:**
351
352.. code:: c
353
354    procedure Message_Queue_Delete (
355    ID     : in     RTEMS.ID;
356    Result :    out RTEMS.Status_Codes
357    );
358
359**DIRECTIVE STATUS CODES:**
360
361``RTEMS.SUCCESSFUL`` - queue deleted successfully
362``RTEMS.INVALID_ID`` - invalid queue id
363``RTEMS.ILLEGAL_ON_REMOTE_OBJECT`` - cannot delete remote queue
364
365**DESCRIPTION:**
366
367This directive deletes the message queue specified by
368id.  As a result of this directive, all tasks blocked waiting to
369receive a message from this queue will be readied and returned a
370status code which indicates that the message queue was deleted.
371If no tasks are waiting, but the queue contains messages, then
372RTEMS returns these message buffers back to the system message
373buffer pool.  The QCB for this queue as well as the memory for
374the message buffers is reclaimed by RTEMS.
375
376**NOTES:**
377
378The calling task will be preempted if its preemption
379mode is enabled and one or more local tasks with a higher
380priority than the calling task are waiting on the deleted queue.
381The calling task will NOT be preempted if the tasks that are
382waiting are remote tasks.
383
384The calling task does not have to be the task that
385created the queue, although the task and queue must reside on
386the same node.
387
388When the queue is deleted, any messages in the queue
389are returned to the free message buffer pool.  Any information
390stored in those messages is lost.
391
392When a global message queue is deleted, the message
393queue id must be transmitted to every node in the system for
394deletion from the local copy of the global object table.
395
396Proxies, used to represent remote tasks, are
397reclaimed when the message queue is deleted.
398
399MESSAGE_QUEUE_SEND - Put message at rear of a queue
400---------------------------------------------------
401.. index:: send message to a queue
402
403**CALLING SEQUENCE:**
404
405.. code:: c
406
407    procedure Message_Queue_Send (
408    ID     : in     RTEMS.ID;
409    Buffer : in     RTEMS.Address;
410    Size   : in     RTEMS.Unsigned32;
411    Result :    out RTEMS.Status_Codes
412    );
413
414**DIRECTIVE STATUS CODES:**
415
416``RTEMS.SUCCESSFUL`` - message sent successfully
417``RTEMS.INVALID_ID`` - invalid queue id
418``RTEMS.INVALID_SIZE`` - invalid message size
419``RTEMS.INVALID_ADDRESS`` - ``buffer`` is NULL
420``RTEMS.UNSATISFIED`` - out of message buffers
421``RTEMS.TOO_MANY`` - queue’s limit has been reached
422
423**DESCRIPTION:**
424
425This directive sends the message buffer of size bytes
426in length to the queue specified by id.  If a task is waiting at
427the queue, then the message is copied to the waiting task’s
428buffer and the task is unblocked. If no tasks are waiting at the
429queue, then the message is copied to a message buffer which is
430obtained from this message queue’s message buffer pool.  The
431message buffer is then placed at the rear of the queue.
432
433**NOTES:**
434
435The calling task will be preempted if it has
436preemption enabled and a higher priority task is unblocked as
437the result of this directive.
438
439Sending a message to a global message queue which
440does not reside on the local node will generate a request to the
441remote node to post the message on the specified message queue.
442
443If the task to be unblocked resides on a different
444node from the message queue, then the message is forwarded to
445the appropriate node, the waiting task is unblocked, and the
446proxy used to represent the task is reclaimed.
447
448MESSAGE_QUEUE_URGENT - Put message at front of a queue
449------------------------------------------------------
450.. index:: put message at front of queue
451
452**CALLING SEQUENCE:**
453
454.. code:: c
455
456    procedure Message_Queue_Urgent (
457    ID     : in     RTEMS.ID;
458    Buffer : in     RTEMS.Address;
459    Size   : in     RTEMS.Unsigned32;
460    Result :    out RTEMS.Status_Codes
461    );
462
463**DIRECTIVE STATUS CODES:**
464
465``RTEMS.SUCCESSFUL`` - message sent successfully
466``RTEMS.INVALID_ID`` - invalid queue id
467``RTEMS.INVALID_SIZE`` - invalid message size
468``RTEMS.INVALID_ADDRESS`` - ``buffer`` is NULL
469``RTEMS.UNSATISFIED`` - out of message buffers
470``RTEMS.TOO_MANY`` - queue’s limit has been reached
471
472**DESCRIPTION:**
473
474This directive sends the message buffer of size bytes
475in length to the queue specified by id.  If a task is waiting on
476the queue, then the message is copied to the task’s buffer and
477the task is unblocked.  If no tasks are waiting on the queue,
478then the message is copied to a message buffer which is obtained
479from this message queue’s message buffer pool.  The message
480buffer is then placed at the front of the queue.
481
482**NOTES:**
483
484The calling task will be preempted if it has
485preemption enabled and a higher priority task is unblocked as
486the result of this directive.
487
488Sending a message to a global message queue which
489does not reside on the local node will generate a request
490telling the remote node to post the message on the specified
491message queue.
492
493If the task to be unblocked resides on a different
494node from the message queue, then the message is forwarded to
495the appropriate node, the waiting task is unblocked, and the
496proxy used to represent the task is reclaimed.
497
498MESSAGE_QUEUE_BROADCAST - Broadcast N messages to a queue
499---------------------------------------------------------
500.. index:: broadcast message to a queue
501
502**CALLING SEQUENCE:**
503
504.. code:: c
505
506    procedure Message_Queue_Broadcast (
507    ID     : in     RTEMS.ID;
508    Buffer : in     RTEMS.Address;
509    Size   : in     RTEMS.Unsigned32;
510    Count  :    out RTEMS.Unsigned32;
511    Result :    out RTEMS.Status_Codes
512    );
513
514**DIRECTIVE STATUS CODES:**
515
516``RTEMS.SUCCESSFUL`` - message broadcasted successfully
517``RTEMS.INVALID_ID`` - invalid queue id
518``RTEMS.INVALID_ADDRESS`` - ``buffer`` is NULL
519``RTEMS.INVALID_ADDRESS`` - ``count`` is NULL
520``RTEMS.INVALID_SIZE`` - invalid message size
521
522**DESCRIPTION:**
523
524This directive causes all tasks that are waiting at
525the queue specified by id to be unblocked and sent the message
526contained in buffer.  Before a task is unblocked, the message
527buffer of size byes in length is copied to that task’s message
528buffer.  The number of tasks that were unblocked is returned in
529count.
530
531**NOTES:**
532
533The calling task will be preempted if it has
534preemption enabled and a higher priority task is unblocked as
535the result of this directive.
536
537The execution time of this directive is directly
538related to the number of tasks waiting on the message queue,
539although it is more efficient than the equivalent number of
540invocations of ``rtems.message_queue_send``.
541
542Broadcasting a message to a global message queue
543which does not reside on the local node will generate a request
544telling the remote node to broadcast the message to the
545specified message queue.
546
547When a task is unblocked which resides on a different
548node from the message queue, a copy of the message is forwarded
549to the appropriate node,  the waiting task is unblocked, and the
550proxy used to represent the task is reclaimed.
551
552MESSAGE_QUEUE_RECEIVE - Receive message from a queue
553----------------------------------------------------
554.. index:: receive message from a queue
555
556**CALLING SEQUENCE:**
557
558.. code:: c
559
560    procedure Message_Queue_Receive (
561    ID         : in     RTEMS.ID;
562    Buffer     : in     RTEMS.Address;
563    Option_Set : in     RTEMS.Option;
564    Timeout    : in     RTEMS.Interval;
565    Size       :    out RTEMS.Unsigned32;
566    Result     :    out RTEMS.Status_Codes
567    );
568
569**DIRECTIVE STATUS CODES:**
570
571``RTEMS.SUCCESSFUL`` - message received successfully
572``RTEMS.INVALID_ID`` - invalid queue id
573``RTEMS.INVALID_ADDRESS`` - ``buffer`` is NULL
574``RTEMS.INVALID_ADDRESS`` - ``size`` is NULL
575``RTEMS.UNSATISFIED`` - queue is empty
576``RTEMS.TIMEOUT`` - timed out waiting for message
577``RTEMS.OBJECT_WAS_DELETED`` - queue deleted while waiting
578
579**DESCRIPTION:**
580
581This directive receives a message from the message
582queue specified in id.  The ``RTEMS.WAIT`` and ``RTEMS.NO_WAIT`` options of the
583options parameter allow the calling task to specify whether to
584wait for a message to become available or return immediately.
585For either option, if there is at least one message in the
586queue, then it is copied to buffer, size is set to return the
587length of the message in bytes, and this directive returns
588immediately with a successful return code.  The buffer has to be big enough to
589receive a message of the maximum length with respect to this message queue.
590
591If the calling task chooses to return immediately and
592the queue is empty, then a status code indicating this condition
593is returned.  If the calling task chooses to wait at the message
594queue and the queue is empty, then the calling task is placed on
595the message wait queue and blocked.  If the queue was created
596with the ``RTEMS.PRIORITY`` option specified, then
597the calling task is inserted into the wait queue according to
598its priority.  But, if the queue was created with the``RTEMS.FIFO`` option specified, then the
599calling task is placed at the rear of the wait queue.
600
601A task choosing to wait at the queue can optionally
602specify a timeout value in the timeout parameter.  The timeout
603parameter specifies the maximum interval to wait before the
604calling task desires to be unblocked.  If it is set to``RTEMS.NO_TIMEOUT``, then the calling task will wait forever.
605
606**NOTES:**
607
608The following message receive option constants are
609defined by RTEMS:
610
611- ``RTEMS.WAIT`` - task will wait for a message (default)
612
613- ``RTEMS.NO_WAIT`` - task should not wait
614
615Receiving a message from a global message queue which
616does not reside on the local node will generate a request to the
617remote node to obtain a message from the specified message
618queue.  If no message is available and ``RTEMS.WAIT`` was specified, then
619the task must be blocked until a message is posted.  A proxy is
620allocated on the remote node to represent the task until the
621message is posted.
622
623A clock tick is required to support the timeout functionality of
624this directive.
625
626MESSAGE_QUEUE_GET_NUMBER_PENDING - Get number of messages pending on a queue
627----------------------------------------------------------------------------
628.. index:: get number of pending messages
629
630**CALLING SEQUENCE:**
631
632.. code:: c
633
634    procedure Message_Queue_Get_Number_Pending (
635    ID     : in     RTEMS.ID;
636    Count  :    out RTEMS.Unsigned32;
637    Result :    out RTEMS.Status_Codes
638    );
639
640**DIRECTIVE STATUS CODES:**
641
642``RTEMS.SUCCESSFUL`` - number of messages pending returned successfully
643``RTEMS.INVALID_ADDRESS`` - ``count`` is NULL
644``RTEMS.INVALID_ID`` - invalid queue id
645
646**DESCRIPTION:**
647
648This directive returns the number of messages pending on this
649message queue in count.  If no messages are present
650on the queue, count is set to zero.
651
652**NOTES:**
653
654Getting the number of pending messages on a global message queue which
655does not reside on the local node will generate a request to the
656remote node to actually obtain the pending message count for
657the specified message queue.
658
659MESSAGE_QUEUE_FLUSH - Flush all messages on a queue
660---------------------------------------------------
661.. index:: flush messages on a queue
662
663**CALLING SEQUENCE:**
664
665.. code:: c
666
667    procedure Message_Queue_Flush (
668    ID     : in     RTEMS.ID;
669    Count  :    out RTEMS.Unsigned32;
670    Result :    out RTEMS.Status_Codes
671    );
672
673**DIRECTIVE STATUS CODES:**
674
675``RTEMS.SUCCESSFUL`` - message queue flushed successfully
676``RTEMS.INVALID_ADDRESS`` - ``count`` is NULL
677``RTEMS.INVALID_ID`` - invalid queue id
678
679**DESCRIPTION:**
680
681This directive removes all pending messages from the
682specified queue id.  The number of messages removed is returned
683in count.  If no messages are present on the queue, count is set
684to zero.
685
686**NOTES:**
687
688Flushing all messages on a global message queue which
689does not reside on the local node will generate a request to the
690remote node to actually flush the specified message queue.
691
692.. COMMENT: COPYRIGHT (c) 1988-2002.
693
694.. COMMENT: On-Line Applications Research Corporation (OAR).
695
696.. COMMENT: All rights reserved.
697
Note: See TracBrowser for help on using the repository browser.