Link here

Using Mailboxes in Multitasking C Programs

How to use mailboxes to manage inter-task messaging and synchronize data production and data reception in multitasking programs



Mailboxes provide a means of passing messages between tasks for data exchange or task synchronization. For example, assume that a data gathering task that produces data needs to convey the data to a calculation task that consumes the data. This data gathering task can convey the data by placing it in a mailbox and using the SEND command; the calculation task uses RECEIVE to retrieve the data. If the calculation task consumes data faster than the gatherer produces it, the tasks need to be synchronized so that only new data is operated on by the calculation task. Using mailboxes achieves synchronization by forcing the calculation task to wait for new data before it operates. The data producer puts the data in a mailbox and SENDs it. The data consumer task calls RECEIVE to check whether there is new data in the mailbox; if not, RECEIVE calls Pause() to allow other tasks to execute while the consuming task is waiting for the new data.


Defining a mailbox

To create and initialize a mailbox called data_mail, execute

MAILBOX data_mail = 0;

MAILBOX is a typedef defined in the mtasker.h include file. It declares and allocates memory in common RAM for a 32 bit variable. It is important to explicitly initialize the resource variable to contain zero as part of the application program’s initialization after each startup. That is, the initialization must be done in a function that is called by main. Failure to perform the runtime initialization could leave "garbage" in the mailbox that precludes any task from writing valid data into the mailbox.

After initializing the mailbox, only the following routines should be used to modify the contents of a mailbox:

  • SEND

The last three of these functions are for transmission of floating point messages. All of these operators accept as one of their parameters the address of the mailbox. Note that the & operator must be used before the name of the mailbox in the parameter list for these functions. These operators are carefully designed to disable interrupts for short periods of time to assure that task switches do not cause the contents of a mailbox to be written over before reception by the other task.


Sending and receiving mail

To write the quantity 0x123456 to the mailbox, a task executes

SEND( 0x123456, &data_mail );

Note that the & operator must be used before the name of the mailbox so that the address (not the contents) of the mailbox are passed to the SEND function. If the contents of the data_mail mailbox are non-zero when this command is executed, the task Pauses until the mailbox is cleared (that is, until it is read by the action program of the receiving task).

To receive the message, the destination task executes an assignment statement such as

received_data = RECEIVE( &data_mail );

where received_data is declared as a long variable to match the contents of the mailbox. If the contents of data_mail are zero when this assignment statement is executed, the destination task enters a Pause() loop until the mail arrives. Thus mail can be used to ensure that a producer of data and a consumer of data become synchronized. The contents of the mail may be a 32-bit address which points to a block of data, thus giving a mechanism for sharing significant amounts of data.

The TRY_TO_SEND and TRY_TO_FSEND routines may be used to attempt to send mail. If unsuccessful because the mailbox is already full (nonzero), they do not Pause() to pass control to other tasks. Rather, they return a zero flag to the calling task to indicate that it can do something else instead of pausing while waiting for the mailbox to become empty.

Mailboxes and resource variables enable the programmer to specify the manner in which different tasks interact and share resources and information, leading to well controlled task interactions.

See also:

This page is about: Using Mailboxes to Send and Receive Messages between Tasks or Processes, Synchronize Data Production and Data Use in Multitasking C Programs – How to send and receive synchronized data between tasks or processes without data loss in real time multitasking C application programs.