Named Message Queue Interfaces

NuttX supports POSIX named message queues for inter-task communication. Any task may send or receive messages on named message queues. Interrupt handlers may send messages via named message queues.

mqd_t mq_open(const char *mqName, int oflags, ...)

Establishes a connection between a named message queue and the calling task. After a successful call of mq_open(), the task can reference the message queue using the address returned by the call. The message queue remains usable until it is closed by a successful call to mq_close().

Parameters
  • mqName – Name of the queue to open

  • oflags

    Open flags. These may be any combination of:

    • O_RDONLY. Open for read access.

    • O_WRONLY. Open for write access.

    • O_RDWR. Open for both read & write access.

    • O_CREAT. Create message queue if it does not already exist.

    • O_EXCL. Name must not exist when opened.

    • O_NONBLOCK. Don’t wait for data.

  • ...

    Optional parameters. When the O_CREAT flag is specified, POSIX requires that a third and fourth parameter be supplied:

    • mode. The mode parameter is of type mode_t. In the POSIX specification, this mode value provides file permission bits for the message queue. This parameter is required but not used in the present implementation.

    • attr. A pointer to an mq_attr that is provided to initialize. the message queue. If attr is NULL, then the messages queue is created with implementation-defined default message queue attributes. If attr is non-NULL, then the message queue mq_maxmsg attribute is set to the corresponding value when the queue is created. The mq_maxmsg attribute determines the maximum number of messages that can be queued before addition attempts to send messages on the message queue fail or cause the sender to block; the mq_msgsize attribute determines the maximum size of a message that can be sent or received. Other elements of attr are ignored (i.e, set to default message queue attributes).

Returns

A message queue descriptor or -1 (ERROR)

POSIX Compatibility: Comparable to the POSIX interface of the same name. Differences from the full POSIX implementation include:

  • The mq_msgsize attributes determines the maximum size of a message that may be sent or received. In the present implementation, this maximum message size is limited at 22 bytes.

int mq_close(mqd_t mqdes)

Used to indicate that the calling task is finished with the specified message queued mqdes. The mq_close() deallocates any system resources allocated by the system for use by this task for its message queue.

If the calling task has attached a notification request to the message queue via this mqdes (see mq_notify()), this attachment will be removed and the message queue is available for another task to attach for notification.

Parameters
  • mqdes – Message queue descriptor.

Returns

0 (OK) if the message queue is closed successfully, otherwise, -1 (ERROR).

Assumptions/Limitations:

  • The behavior of a task that is blocked on either a mq_send() or mq_receive() is undefined when mq_close() is called.

  • The result of using this message queue descriptor after successful return from mq_close() is undefined.

POSIX Compatibility: Comparable to the POSIX interface of the same name.

Removes the message queue named by “mqName.” If one or more tasks have the message queue open when mq_unlink() is called, removal of the message queue is postponed until all references to the message queue have been closed.

Parameters
  • mqName – Name of the message queue

POSIX Compatibility: Comparable to the POSIX interface of the same name.

int mq_send(mqd_t mqdes, const void *msg, size_t msglen, int prio)

Adds the specified message, msg, to the message queue, mqdes. The msglen parameter specifies the length of the message in bytes pointed to by msg. This length must not exceed the maximum message length from the mq_getattr().

If the message queue is not full, mq_send() will place the msg in the message queue at the position indicated by the prio argument. Messages with higher priority will be inserted before lower priority messages The value of prio must not exceed MQ_PRIO_MAX.

If the specified message queue is full and O_NONBLOCK is not set in the message queue, then mq_send() will block until space becomes available to the queue the message.

If the message queue is full and NON_BLOCK is set, the message is not queued and ERROR is returned.

NOTE: mq_send() may be called from an interrupt handler. However, it behaves differently when called from the interrupt level:

  • It does not check the size of the queue. It will always post the message, even if there is already too many messages in queue. This is because the interrupt handler does not have the option of waiting for the message queue to become non-full.

  • It doesn’t allocate new memory (because you cannot allocate memory from an interrupt handler). Instead, there are are pool of pre-allocated message structures that may be used just for sending messages from interrupt handlers. The number of such pre-allocated messages is a configuration parameter.

Parameters
  • mqdes – Message queue descriptor.

  • msg – Message to send.

  • msglen – The length of the message in bytes.

  • prio – The priority of the message.

Returns

On success, mq_send() returns 0 (OK); on error, -1 (ERROR) is returned, with `errno <#ErrnoAccess>`__ set to indicate the error:

  • EAGAIN. The queue was empty, and the O_NONBLOCK flag was set for the message queue description referred to by mqdes.

  • EINVAL. Either msg or mqdes is NULL or the value of prio is invalid.

  • EPERM. Message queue opened not opened for writing.

  • EMSGSIZE. msglen was greater than the maxmsgsize attribute of the message queue.

  • EINTR. The call was interrupted by a signal handler.

POSIX Compatibility: Comparable to the POSIX interface of the same name.

int mq_timedsend(mqd_t mqdes, const char *msg, size_t msglen, int prio, const struct timespec *abstime);

Adds the specified message, msg, to the message queue, mqdes. The msglen parameter specifies the length of the message in bytes pointed to by msg. This length must not exceed the maximum message length from the mq_getattr().

If the message queue is not full, mq_timedsend() will place the msg in the message queue at the position indicated by the prio argument. Messages with higher priority will be inserted before lower priority messages The value of prio must not exceed MQ_PRIO_MAX.

If the specified message queue is full and O_NONBLOCK is not set in the message queue, then mq_send() will block until space becomes available to the queue the message or until a timeout occurs.

mq_timedsend() behaves just like mq_send(), except that if the queue is full and the O_NONBLOCK flag is not enabled for the message queue description, then abstime points to a structure which specifies a ceiling on the time for which the call will block. This ceiling is an absolute timeout in seconds and nanoseconds since the Epoch (midnight on the morning of 1 January 1970).

If the message queue is full, and the timeout has already expired by the time of the call, mq_timedsend() returns immediately.

Parameters
  • mqdes – Message queue descriptor.

  • msg – Message to send.

  • msglen – The length of the message in bytes.

  • prio – The priority of the message.

Returns

On success, mq_send() returns 0 (OK); on error, -1 (ERROR) is returned, with `errno <#ErrnoAccess>`__ set to indicate the error:

  • EAGAIN. The queue was empty, and the O_NONBLOCK flag was set for the message queue description referred to by mqdes.

  • EINVAL. Either msg or mqdes is NULL or the value of prio is invalid.

  • EPERM. Message queue opened not opened for writing.

  • EMSGSIZE. msglen was greater than the maxmsgsize attribute of the message queue.

  • EINTR. The call was interrupted by a signal handler.

POSIX Compatibility: Comparable to the POSIX interface of the same name.

ssize_t mq_receive(mqd_t mqdes, void *msg, size_t msglen, int *prio)

Receives the oldest of the highest priority messages from the message queue specified by mqdes. If the size of the buffer in bytes, msgLen, is less than the mq_msgsize attribute of the message queue, mq_receive() will return an error. Otherwise, the selected message is removed from the queue and copied to msg.

If the message queue is empty and O_NONBLOCK was not set, mq_receive() will block until a message is added to the message queue. If more than one task is waiting to receive a message, only the task with the highest priority that has waited the longest will be unblocked.

If the queue is empty and O_NONBLOCK is set, ERROR will be returned.

Parameters
  • mqdes – Message Queue Descriptor.

  • msg – Buffer to receive the message.

  • msglen – Size of the buffer in bytes.

  • prio – If not NULL, the location to store message priority.

Returns

One success, the length of the selected message in bytes is returned. On failure, -1 (ERROR) is returned and the `errno <#ErrnoAccess>`__ is set appropriately:

  • EAGAIN The queue was empty and the O_NONBLOCK flag was set for the message queue description referred to by mqdes.

  • EPERM Message queue opened not opened for reading.

  • EMSGSIZE msglen was less than the maxmsgsize attribute of the message queue.

  • EINTR The call was interrupted by a signal handler.

  • EINVAL Invalid msg or mqdes

POSIX Compatibility: Comparable to the POSIX interface of the same name.

ssize_t mq_timedreceive(mqd_t mqdes, void *msg, size_t msglen, int *prio, const struct timespec *abstime);

Receives the oldest of the highest priority messages from the message queue specified by mqdes. If the size of the buffer in bytes, msgLen, is less than the mq_msgsize attribute of the message queue, mq_timedreceive() will return an error. Otherwise, the selected message is removed from the queue and copied to msg.

If the message queue is empty and O_NONBLOCK was not set, mq_timedreceive() will block until a message is added to the message queue (or until a timeout occurs). If more than one task is waiting to receive a message, only the task with the highest priority that has waited the longest will be unblocked.

mq_timedreceive() behaves just like mq_receive(), except that if the queue is empty and the O_NONBLOCK flag is not enabled for the message queue description, then abstime points to a structure which specifies a ceiling on the time for which the call will block. This ceiling is an absolute timeout in seconds and nanoseconds since the Epoch (midnight on the morning of 1 January 1970).

If no message is available, and the timeout has already expired by the time of the call, mq_timedreceive() returns immediately.

Parameters
  • mqdes – Message Queue Descriptor.

  • msg – Buffer to receive the message.

  • msglen – Size of the buffer in bytes.

  • prio – If not NULL, the location to store message priority.

  • abstime – The absolute time to wait until a timeout is declared.

Returns

One success, the length of the selected message in bytes is returned. On failure, -1 (ERROR) is returned and the `errno <#ErrnoAccess>`__ is set appropriately:

  • EAGAIN: The queue was empty and the O_NONBLOCK flag was set for the message queue description referred to by mqdes.

  • EPERM: Message queue opened not opened for reading.

  • EMSGSIZE: msglen was less than the maxmsgsize attribute of the message queue.

  • EINTR: The call was interrupted by a signal handler.

  • EINVAL: Invalid msg or mqdes or abstime

  • ETIMEDOUT: The call timed out before a message could be transferred.

POSIX Compatibility: Comparable to the POSIX interface of the same name.

int mq_notify(mqd_t mqdes, FAR const struct sigevent *notification)

If the notification input parameter is not NULL, this function connects the task with the message queue such that the specified signal will be sent to the task whenever the message changes from empty to non-empty. One notification can be attached to a message queue.

If notification; is NULL, the attached notification is detached (if it was held by the calling task) and the queue is available to attach another notification.

When the notification is sent to the registered task, its registration will be removed. The message queue will then be available for registration.

Parameters
  • mqdes – Message queue descriptor

  • notification

    Real-time signal structure containing:

    • sigev_notify. Should be SIGEV_SIGNAL (but actually ignored)

    • sigev_signo. The signo to use for the notification

    • sigev_value. Value associated with the signal

Returns

On success mq_notify() returns 0; on error, -1 is returned, with errno set to indicate the error:

  • EBADF. The descriptor specified in mqdes is invalid.

  • EBUSY. Another process has already registered to receive notification for this message queue.

  • EINVAL. sevp->sigev_notify is not one of the permitted values; or sevp->sigev_notify is SIGEV_SIGNAL and sevp->sigev_signo is not a valid signal number.

  • ENOMEM. Insufficient memory.

POSIX Compatibility: Comparable to the POSIX interface of the same name. Differences from the full POSIX implementation include:

  • The notification signal will be sent to the registered task even if another task is waiting for the message queue to become non-empty. This is inconsistent with the POSIX specification which states, “If a process has registered for notification of message arrival at a message queue and some process is blocked in mq_receive waiting to receive a message when a message arrives at the queue, the arriving message will satisfy the appropriate mq_receive() … The resulting behavior is as if the message queue remains empty, and no notification will be sent.”

int mq_setattr(mqd_t mqdes, const struct mq_attr *mqStat, struct mq_attr *oldMqStat);

Sets the attributes associated with the specified message queue “mqdes.” Only the “O_NONBLOCK” bit of the “mq_flags” can be changed.

If oldMqStat is non-null, mq_setattr() will store the previous message queue attributes at that location (just as would have been returned by mq_getattr()).

Parameters
  • mqdes – Message queue descriptor

  • mqStat – New attributes

  • oldMqState – Old attributes

Returns

0 (OK) if attributes are set successfully, otherwise -1 (ERROR).

POSIX Compatibility: Comparable to the POSIX interface of the same name.

int mq_getattr(mqd_t mqdes, struct mq_attr *mqStat)

Gets status information and attributes associated with the specified message queue.

Parameters
  • mqdes – Message queue descriptor

  • mqStat

    Buffer in which to return attributes. The returned attributes include:

    • mq_maxmsg. Max number of messages in queue.

    • mq_msgsize. Max message size.

    • mq_flags. Queue flags.

    • mq_curmsgs. Number of messages currently in queue.

Returns

0 (OK) if attributes provided, -1 (ERROR) otherwise.

POSIX Compatibility: Comparable to the POSIX interface of the same name.