MBOX

Overview

An MBOX device is a peripheral capable of passing signals (and data depending on the peripheral) between CPUs and clusters in the system. Each MBOX instance is providing one or more channels, each one targeting one other CPU cluster (multiple channels can target the same cluster).

API Reference

group mbox_interface

MBOX Interface.

                     CPU #1        |
+----------+                       |        +----------+
|          +---TX9----+   +--------+--RX8---+          |
|  dev A   |          |   |        |        |  CPU #2  |
|          <---RX8--+ |   | +------+--TX9--->          |
+----------+        | |   | |      |        +----------+
                 +--+-v---v-+--+   |
                 |             |   |
                 |   MBOX dev  |   |
                 |             |   |
                 +--+-^---^--+-+   |
+----------+        | |   |  |     |        +----------+
|          <---RX2--+ |   |  +-----+--TX3--->          |
|  dev B   |          |   |        |        |  CPU #3  |
|          +---TX3----+   +--------+--RX2---+          |
+----------+                       |        +----------+
                                   |

An MBOX device is a peripheral capable of passing signals (and data depending on the peripheral) between CPUs and clusters in the system. Each MBOX instance is providing one or more channels, each one targeting one other CPU cluster (multiple channels can target the same cluster).

For example in the plot the device ‘dev A’ is using the TX channel 9 to signal (or send data to) the CPU #2 and it’s expecting data or signals on the RX channel 8. Thus it can send the message through the channel 9, and it can register a callback on the channel 8 of the MBOX device.

This API supports two modes: signalling mode and data transfer mode.

In signalling mode:

In data transfer mode:

  • mbox_mtu_get() must return a (value != 0)

  • mbox_send() must have (msg != NULL)

  • the callback must be called with (data != NULL)

  • The msg content must be the same between sender and receiver

Defines

MBOX_DT_CHANNEL_GET(node_id, name)

Structure initializer for mbox_channel from devicetree.

This helper macro expands to a static initializer for a mbox_channel by reading the relevant device controller and channel number from the devicetree.

Example devicetree fragment:

mbox1: mbox-controller@... { ... };

n: node {
        mboxes = <&mbox1 8>,
                 <&mbox1 9>;
        mbox-names = "tx", "rx";
};
Example usage:
const struct mbox_channel channel = MBOX_DT_CHANNEL_GET(DT_NODELABEL(n), tx);

Parameters
  • node_id – Devicetree node identifier for the MBOX device

  • name – lowercase-and-underscores name of the mboxes element

MBOX_DT_CTLR_BY_NAME(node_id, name)

Get the node identifier for the MBOX controller from a mboxes property by name.

Example devicetree fragment:

mbox1: mbox-controller@... { ... };

n: node {
        mboxes = <&mbox1 8>,
                 <&mbox1 9>;
        mbox-names = "tx", "rx";
};
Example usage:
MBOX_DT_CTLR_BY_NAME(DT_NODELABEL(n), tx) // DT_NODELABEL(mbox1)
MBOX_DT_CTLR_BY_NAME(DT_NODELABEL(n), rx) // DT_NODELABEL(mbox1)

Parameters
  • node_id – node identifier for a node with a mboxes property

  • name – lowercase-and-underscores name of a mboxes element as defined by the node’s mbox-names property

Returns

the node identifier for the MBOX controller in the named element

MBOX_DT_CHANNEL_ID_BY_NAME(node_id, name)

Get a MBOX channel value by name.

Example devicetree fragment:

mbox1: mbox@... {
        #mbox-cells = <1>;
};

n: node {
    mboxes = <&mbox1 1>,
             <&mbox1 6>;
    mbox-names = "tx", "rx";
};
Bindings fragment for the mbox compatible:
mbox-cells:
  - channel
Example usage:
MBOX_DT_CHANNEL_ID_BY_NAME(DT_NODELABEL(n), tx) // 1
MBOX_DT_CHANNEL_ID_BY_NAME(DT_NODELABEL(n), rx) // 6

Parameters
  • node_id – node identifier for a node with a mboxes property

  • name – lowercase-and-underscores name of a mboxes element as defined by the node’s mbox-names property

Returns

the channel value in the specifier at the named element or 0 if no channels are supported

Typedefs

typedef void (*mbox_callback_t)(const struct device *dev, uint32_t channel, void *user_data, struct mbox_msg *data)

Callback API for incoming MBOX messages.

These callbacks execute in interrupt context. Therefore, use only interrupt-safe APIS. Registration of callbacks is done via mbox_register_callback()

The data parameter must be NULL in signalling mode.

Param dev

Driver instance

Param channel

Channel ID

Param user_data

Pointer to some private data provided at registration time

Param data

Message struct

typedef int (*mbox_send_t)(const struct device *dev, uint32_t channel, const struct mbox_msg *msg)

Callback API to send MBOX messages.

See mbox_send() for function description

Param dev

Driver instance

Param channel

Channel ID

Param msg

Message struct

Return

See return values for mbox_send()

typedef int (*mbox_mtu_get_t)(const struct device *dev)

Callback API to get maximum data size.

See mbox_mtu_get() for argument definitions.

typedef int (*mbox_register_callback_t)(const struct device *dev, uint32_t channel, mbox_callback_t cb, void *user_data)

Callback API upon registration.

See mbox_register_callback() for function description

Param dev

Driver instance

Param channel

Channel ID

Param cb

Callback function to execute on incoming message interrupts.

Param user_data

Application-specific data pointer which will be passed to the callback function when executed.

Return

See return values for mbox_register_callback()

typedef int (*mbox_set_enabled_t)(const struct device *dev, uint32_t channel, bool enable)

Callback API upon enablement of interrupts.

See mbox_set_enabled() for function description

Param dev

Driver instance

Param channel

Channel ID

Param enable

Set to 0 to disable and to nonzero to enable.

Return

See return values for mbox_set_enabled()

typedef uint32_t (*mbox_max_channels_get_t)(const struct device *dev)

Callback API to get maximum number of channels.

See mbox_max_channels_get() for argument definitions.

Functions

static inline void mbox_init_channel(struct mbox_channel *channel, const struct device *dev, uint32_t ch_id)

Initialize a channel struct.

Initialize an mbox_channel passed by the user with a provided MBOX device and channel ID. This function is needed when the information about the device and the channel ID is not in the DT. In the DT case MBOX_DT_CHANNEL_GET() must be used instead.

Parameters
  • channel – Pointer to the channel struct

  • dev – Driver instance

  • ch_id – Channel ID

int mbox_send(const struct mbox_channel *channel, const struct mbox_msg *msg)

Try to send a message over the MBOX device.

Send a message over an mbox_channel. The msg parameter must be NULL when the driver is used for signalling.

If the msg parameter is not NULL, this data is expected to be delivered on the receiving side using the data parameter of the receiving callback.

Parameters
  • channel – Channel instance pointer

  • msg – Pointer to the message struct

Return values
  • -EBUSY – If the remote hasn’t yet read the last data sent.

  • -EMSGSIZE – If the supplied data size is unsupported by the driver.

  • -EINVAL – If there was a bad parameter, such as: too-large channel descriptor or the device isn’t an outbound MBOX channel.

  • 0 – On success, negative value on error.

static inline int mbox_register_callback(const struct mbox_channel *channel, mbox_callback_t cb, void *user_data)

Register a callback function on a channel for incoming messages.

This function doesn’t assume anything concerning the status of the interrupts. Use mbox_set_enabled() to enable or to disable the interrupts if needed.

Parameters
  • channel – Channel instance pointer.

  • cb – Callback function to execute on incoming message interrupts.

  • user_data – Application-specific data pointer which will be passed to the callback function when executed.

Return values

0 – On success, negative value on error.

int mbox_mtu_get(const struct device *dev)

Return the maximum number of bytes possible in an outbound message.

Returns the actual number of bytes that it is possible to send through an outgoing channel.

This number can be 0 when the driver only supports signalling or when on the receiving side the content and size of the message must be retrieved in an indirect way (i.e. probing some other peripheral, reading memory regions, etc…).

If this function returns 0, the msg parameter in mbox_send() is expected to be NULL.

Parameters
  • dev – Driver instance pointer.

Returns

Maximum possible size of a message in bytes, 0 for signalling, negative value on error.

int mbox_set_enabled(const struct mbox_channel *channel, bool enable)

Enable (disable) interrupts and callbacks for inbound channels.

Enable interrupt for the channel when the parameter ‘enable’ is set to true. Disable it otherwise.

Immediately after calling this function with ‘enable’ set to true, the channel is considered enabled and ready to receive signal and messages (even already pending), so the user must take care of installing a proper callback (if needed) using mbox_register_callback() on the channel before enabling it. For this reason it is recommended that all the channels are disabled at probe time.

Enabling a channel for which there is no installed callback is considered undefined behavior (in general the driver must take care of gracefully handling spurious interrupts with no installed callback).

Parameters
  • channel – Channel instance pointer.

  • enable – Set to 0 to disable and to nonzero to enable.

Return values
  • 0 – On success.

  • -EINVAL – If it isn’t an inbound channel.

uint32_t mbox_max_channels_get(const struct device *dev)

Return the maximum number of channels.

Return the maximum number of channels supported by the hardware.

Parameters
  • dev – Driver instance pointer.

Returns

Maximum possible number of supported channels on success, negative value on error.

struct mbox_msg
#include <mbox.h>

Message struct (to hold data and its size).

Public Members

const void *data

Pointer to the data sent in the message.

size_t size

Size of the data.

struct mbox_channel
#include <mbox.h>

Provides a type to hold an MBOX channel.

Struct type to hold an MBOX device pointer and the channel ID.

Public Members

const struct device *dev

MBOX device pointer.

uint32_t id

Channel ID.

struct mbox_driver_api
#include <mbox.h>