Keil Logo

Using a Mailbox

The RTX kernel message objects are simply pointers to a block of memory where the relevant information is stored. There is no restriction regarding the message size or content. The RTX kernel handles only the pointer to this message.

Sending 8-bit, 16-bit, and 32-bit values

Because the RTX kernel passes only the pointer from the sending task to the receiving task, we can use the pointer itself to carry simple information like passing a character from a serial receive interrupt routine. An example can be found in the serial.c interrupt driven serial interface module for the Traffic example. You must cast the char to a pointer like in the following example:

  os_mbx_send (send_mbx, (void *)c, 0xffff);

Sending fixed size messages

To send fixed size messages, you must allocate a block of memory from the dynamic memory pool, store the information in it, and pass its pointer to a mailbox. The receiving task receives the pointer and restores the original information from the memory block, and then releases the allocated memory block.

Fixed Memory block memory allocation functions

RTX has very powerful fixed memory block memory allocation routines. They are thread safe and fully reentrant. They can be used with the RTX kernel with no restriction. It is better to use the fixed memory block allocation routines for sending fixed size messages. The memory pool needs to be properly initialized to the size of message objects:

  • 32-bit values: initialize to 4-byte block size.
      _init_box (mpool, sizeof(mpool), 4);
  • any size messages: initialize to the size of message object.
      _init_box (mpool, sizeof(mpool), sizeof(struct message));

For 8-bit and 16-bit messages, it is better to use a parameter casting and convert a message value directly to a pointer.

The following example shows you how to send fixed size messages to a mailbox (see the mailbox example for more information). The message size is 8 bytes (two unsigned ints).

#include <rtl.h>

os_mbx_declare (MsgBox, 16);                /* Declare an RTX mailbox */
U32 mpool[16*(2*sizeof(U32))/4 + 3];        /* Reserve a memory for 16 messages */

__task void rec_task (void);

__task void send_task (void) {
  /* This task will send a message. */
  U32 *mptr;

  os_tsk_create (rec_task, 0);
  os_mbx_init (MsgBox, sizeof(MsgBox));
  mptr = _alloc_box (mpool);                /* Allocate a memory for the message */
  mptr[0] = 0x3215fedc;                     /* Set the message content. */
  mptr[1] = 0x00000015;
  os_mbx_send (MsgBox, mptr, 0xffff);       /* Send a message to a 'MsgBox' */
  os_tsk_delete_self ();

__task void rec_task (void) {
  /* This task will receive a message. */
  U32 *rptr, rec_val[2];

  os_mbx_wait (MsgBox, &rptr, 0xffff);      /* Wait for the message to arrive. */
  rec_val[0] = rptr[0];                     /* Store the content to 'rec_val' */
  rec_val[1] = rptr[1];
  _free_box (mpool, rptr);                  /* Release the memory block */
  os_tsk_delete_self ();

void main (void) {
  _init_box (mpool, sizeof(mpool), sizeof(U32));

Sending variable size messages

To send a message object of variable size, you must use the memory allocation functions for the variable size memory blocks. The RVCT library provides these functions in stdlib.h


  • The fixed block memory allocation functions are fully reentrant. The variable length memory allocation functions are not reentrant. Therefore the system timer interrupts need to be disabled during the execution of the malloc() or free() function. Function tsk_lock() disables timer interrupts and function tsk_unlock() enables timer interrupts.
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.