MTB IPC Library

| MTB IPC Library

API Reference | Data Structures | Macros | Typedefs | Enumerations | Functions
IPC (Inter-Processor Communication)

## General Description

High level interface for communicating between processors on a multi-core device.

The IPC driver allows communication between multiple CPUs or between multiple tasks operating in different domains within a single CPU. It supports binary semaphores and message queues, similar to how they are used for task interactions in an RTOS envrionment.

# Features

- Binary semaphore for resource access control and general signalling
- Message queue for passing data between tasks/cores

# Quick Start

To initialize the driver, call the mtb_ipc_init on the first task/CPU to boot and mtb_ipc_get_handle on other cores. Please see your device documentation to determine which core to start on. This will setup shared memory and the binary semaphore for protecting internal functionality.

For binary semaphores, only one task/CPU may initialize ( mtb_ipc_semaphore_init) a semaphore. Other tasks/CPUs then get the handle ( mtb_ipc_semaphore_get_handle) of the created semaphore. Then take/give the semaphore ( mtb_ipc_semaphore_take/ mtb_ipc_semaphore_give).

For queues, only one task/CPU may initialize ( mtb_ipc_queue_init) a queue. Other tasks/CPUs then get the handle ( mtb_ipc_queue_get_handle) of the created queue. Use the get/put functions to take out or put in items to the queue ( mtb_ipc_queue_put, mtb_ipc_queue_get).

# Valid range for IPC semaphore number

mtb_ipc_semaphore_init function semaphore_num parameter valid range is from 0 to (including) CY_IPC_SEMA_COUNT - 2

# section_impl_ipc_shared_data_objects

For all IPC library constructs, some data must be put in the shared memory regions so that all cores can access. This must satisfy a few requirements:

- Memory should be accessible from all cores (e.g. CY_SECTION_SHAREDMEM macro can be used)
- If used with a core where Data Cache is enabled, memory should be aligned to __SCB_DCACHE_LINE_SIZE The following sections outline the different data types and their requirements.

## Shared data memory allocation

Shared data memory allocation can be done with help of MTB_IPC_SHARED_DATA_ALLOC macro, but using it is not mandatory, so user can allocate memory for the shared memory in any convenient for them way. This struct is necessary to store and keep track of all shared objects during operation.

## Semaphore data memory allocation

semaphore data memory allocation can be done with help of MTB_IPC_SEMAPHORE_DATA_ALLOC macro, but using it is not mandatory, so user can allocate memory for the semaphore data in any convenient for them way as long as such allocation satisfies next parameters:

- Memory should be able to store mtb_ipc_semaphore_data_t type struct
- Each initialized semaphore must have its own semaphore data object. These cannot be shared between semaphores

## Mailbox data memory allocation

Mailbox data memory allocation can be done with help of MTB_IPC_MBOX_DATA_ALLOC macro, but using it is not mandatory, so user can allocate memory for the mailbox data in any way convenient for them as long as such allocation satisfies next parameters:

- Memory should be able to store mtb_ipc_mbox_data_t type struct
- Each initialized mailbox must have its own mailbox data object. These cannot be shared between mailboxes

## Queue pool memory allocation

Queue pool memory allocation can be done with help of MTB_IPC_QUEUE_POOL_ALLOC macro, but using it is not mandatory, so user can allocate memory for the queue pool in any convenient for them way as long as such allocation satisfies next parameters:

- Memory should be able to store NUM_ITEMS x ITEM_SIZE bytes, where NUM_ITEMS - number of max. elements the queue can store, and ITEM_SIZE - size of each queue item in bytes
- Each queue must have its own queue pool

## Queue data memory allocation

Queue data memory allocation can be done with help of MTB_IPC_QUEUE_DATA_ALLOC macro, but using it is not mandatory, so user can allocate memory for the queue data in any convenient for them way as long as such allocation satisfies next parameters:

- Memory should be able to store mtb_ipc_queue_data_t type struct
- Each queue must have its own data object. These cannot be shared between queues.

# Preemtable Semaphore parameter

If preemptable is enabled (true), the user must ensure that there are no deadlocks in the system, which can be caused by an interrupt that occurs after the IPC channel is locked. Unless the user is ready to handle IPC channel locks correctly at the application level, set preemptable to false.

# IPC interrupts implementation

In current IPC library implementation, each core has two of its "own" IPC INTR structures, which services all possible IPC library channels. One IRQ structure is for semaphores, and the other for queues.

# IPC operations in ISR context

Callbacks may execute in an ISR context, so IPC queue put/get operations cannot be performed in callbacks with a timeout != 0 Such operations will result in MTB_IPC_RSLT_ERR_CANT_OPERATE_IN_ISR_W_TIMEOUT. IPC semaphore take/give operations cannot be performed in ISR context with a timeout != 0. Such operations will result in MTB_IPC_RSLT_ERR_CANT_OPERATE_IN_ISR_W_TIMEOUT.

# IPC initialization

On some devices (currently, Traveo, XMC72, and PSE84 devices), startup code does not initialize IPC PDL driver semaphores, so it is done by mtb_ipc_init(). In general, the init function should be called by the first core to boot. Please see your device datasheet for details. This core will do the initialization and set up a pointer using an IPC channel so that all Cores can read and use the same variables. if it has not already been done on that core. The corresponding mtb_ipc_get_handle will be used on other cores to receive this data.

# Calling *_get_handle APIs before _init APIs

Calling mtb_ipc_semaphore_get_handle() before mtb_ipc_semaphore_init() will result in MTB_IPC_RSLT_ERR_NO_SEMA_AVAILABLE. The correct way of using mtb_ipc_semaphore_get_handle() is to call mtb_ipc_semaphore_init() before using mtb_ipc_semaphore_get_handle(), and pass the same semaphore number that was used for the initialization. Semaphores can be initialized on any core and accessed from any core.

Calling mtb_ipc_queue_get_handle() before mtb_ipc_queue_init() will result in MTB_IPC_RSLT_ERR_QUEUE_NOT_FOUND. The correct way of using mtb_ipc_queue_get_handle() is to call mtb_ipc_queue_init() before using mtb_ipc_queue_get_handle(), and pass the same channel and queue number that was used for the queue initialization. Queues can be initialized on any core and accessed from any core.

Calling mtb_ipc_mbox_sender_get_handle() before mtb_ipc_mbox_receiver_init() will result in MTB_IPC_RSLT_ERR_MBOX_NOT_FOUND. The correct way of using mtb_ipc_mbox_sender_get_handle() is to call it after mtb_ipc_mbox_receiver_init() , and pass the same mailbox index that was used for the mailbox initialization. Mailboxes can be initialized on any core and accessed from any core, however initialization must be done on the receiving core for that individual mailbox.

# To protect queue data and also ensure minimal possibility

of deadlocks, any modification of the Queue besides its notifications must be done using the queue's semaphore. To ensure less arbitration in ISR context, notifications are instead protected by the lock on the channel the queue is part of.

# Code Snippets

## Snippet 1: Binary semaphore example

/* General: error handling is not shown. Use CY_ASSERT(CY_RSLT_SUCCESS == result); to check */
#define SEMAPHORE_NUM 0UL
#define IPC_SEMAPHORE_NUM 1UL
/*************************************************************/
/* Task0 (CPU0) */
/*************************************************************/
cy_rslt_t rslt0;
mtb_ipc_t obj;
mtb_ipc_config_t config1;
config1.internal_channel_index = MTB_IPC_CHAN_0;
config1.semaphore_irq = MTB_IPC_IRQ_USER;
config1.queue_irq = MTB_IPC_IRQ_USER + 1UL;
config1.semaphore_num = IPC_SEMAPHORE_NUM;
mtb_ipc_semaphore_t semaphore0;
mtb_ipc_shared_t* shared;
MTB_IPC_SHARED_DATA_ALLOC(shared);
rslt0 = mtb_ipc_init(&obj, shared, &config1);
mtb_ipc_semaphore_data_t* semaphore_data0;
MTB_IPC_SEMAPHORE_DATA_ALLOC(semaphore_data0);
mtb_ipc_semaphore_config_t semaphoreconfig1;
semaphoreconfig1.semaphore_num = SEMAPHORE_NUM;
semaphoreconfig1.preemptable = false;
rslt0 = mtb_ipc_semaphore_init(&obj, &semaphore0, semaphore_data0, &semaphoreconfig1);
for (int i = 0; i < IPC_OPERATIONS_LOOPS; ++i)
{
if (mtb_ipc_semaphore_take(&semaphore0, MTB_IPC_NEVER_TIMEOUT) == CY_RSLT_SUCCESS)
{
rslt0 = mtb_ipc_semaphore_give(&semaphore0);
}
}
/*************************************************************/
/* Task1 (CPU1) */
/*************************************************************/
cy_rslt_t rslt1;
mtb_ipc_t obj1;
mtb_ipc_config_t config2;
config2.internal_channel_index = MTB_IPC_CHAN_0;
config2.semaphore_irq = MTB_IPC_IRQ_USER + 2UL;
config2.queue_irq = MTB_IPC_IRQ_USER + 3UL;
config2.semaphore_num = IPC_SEMAPHORE_NUM;
mtb_ipc_semaphore_t semaphore1;
/* Grab the handle for the initialzied IPC instance*/
mtb_ipc_get_handle(&obj1, &config2, 100);
/* Get the handle for the semaphore created on CPU0 */
rslt1 = mtb_ipc_semaphore_get_handle(&obj1, &semaphore1, SEMAPHORE_NUM, MTB_IPC_NEVER_TIMEOUT);
for (int i = 0; i < IPC_OPERATIONS_LOOPS; ++i)
{
if (mtb_ipc_semaphore_take(&semaphore1, MTB_IPC_NEVER_TIMEOUT) == CY_RSLT_SUCCESS)
{
rslt1 = mtb_ipc_semaphore_give(&semaphore1);
}
}
MTB_IPC_IRQ_USER
#define MTB_IPC_IRQ_USER
Define the first available IRQ for use in MTB IPC.
Definition: mtb_ipc_impl.h:219
MTB_IPC_SHARED_DATA_ALLOC
#define MTB_IPC_SHARED_DATA_ALLOC(shared)
Macro for Shared data region shared memory allocation.
Definition: mtb_ipc_impl.h:291
MTB_IPC_SEMAPHORE_DATA_ALLOC
#define MTB_IPC_SEMAPHORE_DATA_ALLOC(semaphore_data)
Macro for semaphore data shared memory allocation.
Definition: mtb_ipc_impl.h:236
MTB_IPC_CHAN_0
@ MTB_IPC_CHAN_0
User IPC channel 0.
Definition: mtb_ipc_impl.h:151
mtb_ipc_semaphore_data_t
IPC Semaphore Data User should allocate but not modify anything in this struct.
Definition: mtb_ipc_impl.h:462
mtb_ipc_semaphore_t
IPC Semaphore Handle User should allocate but not modify anything in this struct.
Definition: mtb_ipc_impl.h:472
mtb_ipc_shared_t
IPC Shared Memory Object.
Definition: mtb_ipc_impl.h:613
mtb_ipc_t
IPC Instance object This is the per-core obj for tracking shared memory and initialized queues/semaph...
Definition: mtb_ipc_impl.h:656
mtb_ipc_config_t::internal_channel_index
mtb_ipc_channel_t internal_channel_index
IPC channel number (e.g.
Definition: mtb_ipc.h:394
mtb_ipc_config_t::queue_irq
uint32_t queue_irq
User Defined IRQ for use on this core for all queues.
Definition: mtb_ipc.h:400
mtb_ipc_semaphore_config_t::preemptable
bool preemptable
Allows whether the semaphore can be preempted by another task.
Definition: mtb_ipc.h:330
mtb_ipc_semaphore_config_t::semaphore_num
uint32_t semaphore_num
The semaphore number to initialize.
Definition: mtb_ipc.h:333
mtb_ipc_config_t::semaphore_num
uint32_t semaphore_num
User defined semaphore number to use for access to shared region and all MTB IPC operations.
Definition: mtb_ipc.h:403
mtb_ipc_config_t::semaphore_irq
uint32_t semaphore_irq
User Defined IRQ for use on this core for all semaphores.
Definition: mtb_ipc.h:397
MTB_IPC_NEVER_TIMEOUT
#define MTB_IPC_NEVER_TIMEOUT
This define can be used as timeout argument for the IPC HAL driver functions, that take timeout as in...
Definition: mtb_ipc.h:310
mtb_ipc_semaphore_give
cy_rslt_t mtb_ipc_semaphore_give(const mtb_ipc_semaphore_t *semaphore)
Gives/releases a semaphore.
Definition: mtb_ipc.c:2201
mtb_ipc_semaphore_take
cy_rslt_t mtb_ipc_semaphore_take(const mtb_ipc_semaphore_t *semaphore, uint64_t timeout_us)
Takes/acquires a semaphore.
Definition: mtb_ipc.c:1824
mtb_ipc_get_handle
cy_rslt_t mtb_ipc_get_handle(mtb_ipc_t *obj, const mtb_ipc_config_t *config, uint64_t timeout_ms)
Get initialized IPC library Driver Call before any other IPC library functions.
Definition: mtb_ipc.c:1496
mtb_ipc_semaphore_get_handle
cy_rslt_t mtb_ipc_semaphore_get_handle(mtb_ipc_t *obj, mtb_ipc_semaphore_t *semaphore, uint32_t semaphore_num, uint64_t timeout_us)
Finds an already initialized semaphore based on a given number.
Definition: mtb_ipc.c:1766
mtb_ipc_semaphore_init
cy_rslt_t mtb_ipc_semaphore_init(mtb_ipc_t *obj, mtb_ipc_semaphore_t *semaphore, mtb_ipc_semaphore_data_t *sema_obj, const mtb_ipc_semaphore_config_t *config)
Creates a single semaphore based on a given number.
Definition: mtb_ipc.c:1621
mtb_ipc_init
cy_rslt_t mtb_ipc_init(mtb_ipc_t *obj, mtb_ipc_shared_t *shared_data, const mtb_ipc_config_t *config)
Initialize IPC library Driver.
Definition: mtb_ipc.c:1379
mtb_ipc_config_t
IPC object config struct.
Definition: mtb_ipc.h:389
mtb_ipc_semaphore_config_t
User Config Struct to set up a Semaphore Items to be populated by caller before initialization Semaph...
Definition: mtb_ipc.h:322

## Snippet 2: Message queue example

/* General: error handling is not shown. Use CY_ASSERT(CY_RSLT_SUCCESS == result); to check */
// Queue(s) channel(s) must differ from overall IPC channel.
#define Q_CHANNEL_NUM MTB_IPC_CHAN_1
#define QUEUE1_NUM 1UL
#define QUEUE1_ITEMS 8UL
#define QUEUE2_NUM 2UL
#define QUEUE2_ITEMS 1UL
#define QUEUE2_MSG_LEN_MAX 25UL
#define IPC_SEMAPHORE_NUM 1UL
/*************************************************************/
/* Task0 (CPU0) */
/*************************************************************/
#define INVALID_SENSOR_DATA 0UL
#define VALID_SENSOR_DATA 1UL
cy_rslt_t rslt0;
mtb_ipc_queue_t task0_queue1;
mtb_ipc_queue_t task0_queue2;
mtb_ipc_t obj;
mtb_ipc_config_t config1;
config1.internal_channel_index = MTB_IPC_CHAN_0;
config1.semaphore_irq = MTB_IPC_IRQ_USER;
config1.queue_irq = MTB_IPC_IRQ_USER + 1UL;
config1.semaphore_num =IPC_SEMAPHORE_NUM;
mtb_ipc_shared_t* shared;
MTB_IPC_SHARED_DATA_ALLOC(shared);
rslt0 = mtb_ipc_init(&obj, shared, &config1);
uint32_t task0_sensor = VALID_SENSOR_DATA;
char* task0_message = NULL;
/* Allocating in shared memory char array, that will store message from task1 */
CY_SECTION_SHAREDMEM static char task1_message[QUEUE2_MSG_LEN_MAX];
char* task1_message_ptr = task1_message;
/* Defining and allocating (shared) memory pools for queue1 and queue2 */
void* queue1_pool, * queue2_pool;
MTB_IPC_QUEUE_POOL_ALLOC(queue1_pool, QUEUE1_ITEMS, sizeof(task0_sensor));
MTB_IPC_QUEUE_POOL_ALLOC(queue2_pool, QUEUE2_ITEMS, sizeof(task0_message));
/* Defining and allocating (shared) memory for queue handles */
mtb_ipc_queue_data_t* queue1_obj, * queue2_obj;
mtb_ipc_queue_config_t queueconfig1, queueconfig2;
MTB_IPC_QUEUE_DATA_ALLOC(queue1_obj);
MTB_IPC_QUEUE_DATA_ALLOC(queue2_obj);
queueconfig1.channel_num = Q_CHANNEL_NUM;
queueconfig1.queue_num = QUEUE1_NUM;
queueconfig1.queue_pool = queue1_pool;
queueconfig1.max_num_items = QUEUE1_ITEMS;
queueconfig1.item_size = sizeof(task0_sensor);
queueconfig1.semaphore_num = 2UL;
queueconfig2.channel_num = Q_CHANNEL_NUM;
queueconfig2.queue_num = QUEUE2_NUM;
queueconfig2.queue_pool = queue2_pool;
queueconfig2.max_num_items = QUEUE2_ITEMS;
queueconfig2.item_size = sizeof(task0_message);
queueconfig2.semaphore_num = 3UL;
rslt0 = mtb_ipc_queue_init(&obj, &task0_queue1, queue1_obj, &queueconfig1);
rslt0 = mtb_ipc_queue_init(&obj, &task0_queue2, queue2_obj, &queueconfig2);
for (int i = 0; i < IPC_OPERATIONS_LOOPS; ++i)
{
if (task0_sensor != INVALID_SENSOR_DATA)
{
rslt0 = mtb_ipc_queue_put(&task0_queue1, &task0_sensor, MTB_IPC_NEVER_TIMEOUT);
}
while (!mtb_ipc_queue_count(&task0_queue2))
{
Cy_SysLib_Delay(1);
}
if (mtb_ipc_queue_get(&task0_queue2, &task0_message,
MTB_IPC_NEVER_TIMEOUT) == CY_RSLT_SUCCESS)
{
if (task0_message != NULL)
{
task0_message = NULL;
}
}
}
/*************************************************************/
/* Task1 (CPU1) */
/*************************************************************/
cy_rslt_t rslt1;
mtb_ipc_queue_t task1_queue1;
mtb_ipc_queue_t task1_queue2;
mtb_ipc_t obj1;
mtb_ipc_config_t config2;
config2.internal_channel_index = MTB_IPC_CHAN_0;
config2.semaphore_irq = MTB_IPC_IRQ_USER + 2UL;
config2.queue_irq = MTB_IPC_IRQ_USER + 3UL;
config2.semaphore_num = IPC_SEMAPHORE_NUM;
rslt0 = mtb_ipc_get_handle(&obj1, &config2, 100);
uint32_t task1_sensor;
rslt1 = mtb_ipc_queue_get_handle(&obj1, &task1_queue1, Q_CHANNEL_NUM, QUEUE1_NUM);
rslt1 = mtb_ipc_queue_get_handle(&obj1, &task1_queue2, Q_CHANNEL_NUM, QUEUE2_NUM);
for (int i = 0; i < IPC_OPERATIONS_LOOPS; ++i)
{
while (!mtb_ipc_queue_count(&task1_queue1))
{
Cy_SysLib_Delay(1);
}
if (mtb_ipc_queue_get(&task1_queue1, &task1_sensor,
MTB_IPC_NEVER_TIMEOUT) == CY_RSLT_SUCCESS)
{
rslt1 = mtb_ipc_queue_put(&task1_queue2, &task1_message_ptr,
MTB_IPC_NEVER_TIMEOUT);
}
}
MTB_IPC_QUEUE_POOL_ALLOC
#define MTB_IPC_QUEUE_POOL_ALLOC(queue_pool, NUM_ITEMS, ITEMSIZE)
Macro for Queue pool shared memory allocation.
Definition: mtb_ipc_impl.h:265
MTB_IPC_QUEUE_DATA_ALLOC
#define MTB_IPC_QUEUE_DATA_ALLOC(queue_data)
Macro for Queue data shared memory allocation.
Definition: mtb_ipc_impl.h:278
mtb_ipc_queue_data_t
IPC queue data element User should allocate but not modify anything in this struct.
Definition: mtb_ipc_impl.h:524
mtb_ipc_queue_t
IPC Queue handle object User should allocate but not modify anything in this struct.
Definition: mtb_ipc_impl.h:564
mtb_ipc_queue_config_t::semaphore_num
uint32_t semaphore_num
Semaphore number to use with this queue.
Definition: mtb_ipc.h:380
mtb_ipc_queue_config_t::item_size
uint32_t item_size
Size of each packet (item) in the Queue.
Definition: mtb_ipc.h:372
mtb_ipc_queue_config_t::queue_num
uint32_t queue_num
Queue number, which must be unique for each queue in scope of one IPC channel.
Definition: mtb_ipc.h:368
mtb_ipc_queue_config_t::channel_num
mtb_ipc_channel_t channel_num
IPC channel number (e.g.
Definition: mtb_ipc.h:366
mtb_ipc_queue_config_t::queue_pool
void * queue_pool
Pointer to the queue packets in shared memory.
Definition: mtb_ipc.h:378
mtb_ipc_queue_config_t::max_num_items
uint32_t max_num_items
Maximum number of items (packets) allowed in the queue.
Definition: mtb_ipc.h:370
mtb_ipc_queue_get_handle
cy_rslt_t mtb_ipc_queue_get_handle(mtb_ipc_t *obj, mtb_ipc_queue_t *queue, uint32_t channel_num, uint32_t queue_num)
Gets a handle pointer for a given IPC channel and queue number.
mtb_ipc_queue_put
cy_rslt_t mtb_ipc_queue_put(mtb_ipc_queue_t *queue, void *msg, uint64_t timeout_us)
Adds one item to the queue.
Definition: mtb_ipc.c:2742
mtb_ipc_queue_count
uint32_t mtb_ipc_queue_count(const mtb_ipc_queue_t *queue)
Returns how many items are in the queue.
Definition: mtb_ipc.c:2800
mtb_ipc_queue_init
cy_rslt_t mtb_ipc_queue_init(mtb_ipc_t *obj, mtb_ipc_queue_t *queue, mtb_ipc_queue_data_t *queue_obj, const mtb_ipc_queue_config_t *config)
Creates a new queue for a given IPC channel based on the given queue number and other parameters.
Definition: mtb_ipc.c:2350
mtb_ipc_queue_get
cy_rslt_t mtb_ipc_queue_get(mtb_ipc_queue_t *queue, void *msg, uint64_t timeout_us)
Removes one item from the queue.
Definition: mtb_ipc.c:2771
mtb_ipc_queue_config_t
User Config Struct to set up a Queue Items to be populated by caller before initialization Combinatio...
Definition: mtb_ipc.h:362

## Snippet : Message mailbox example

/* General: error handling is not shown. Use CY_ASSERT(CY_RSLT_SUCCESS == result); to check */
#define CHANNEL_NUM MTB_IPC_CHAN_0
#define MBOX_IDX 1UL
#define IPC_SEMAPHORE_NUM 1UL
#define READ_SEMAPHORE_NUM 2UL
#define WRITE_SEMAPHORE_NUM 3UL
#define MESSAGES_TO_SEND 5
/*************************************************************/
/* Receiver (CPU0) */
/*************************************************************/
cy_rslt_t rslt0;
mtb_ipc_mbox_receiver_t receiver;
mtb_ipc_t obj;
mtb_ipc_config_t config1;
config1.internal_channel_index = MTB_IPC_CHAN_0;
config1.semaphore_irq = MTB_IPC_IRQ_USER;
config1.queue_irq = MTB_IPC_IRQ_USER + 1UL;
config1.semaphore_num =IPC_SEMAPHORE_NUM;
mtb_ipc_shared_t* shared;
MTB_IPC_SHARED_DATA_ALLOC(shared);
rslt0 = mtb_ipc_init(&obj, shared, &config1);
//Example packet
typedef struct
{
int priority;
char* op_code;
} packet;
mtb_ipc_mbox_data_t* mbox_data;
mtb_ipc_mbox_config_t mbox_cfg;
MTB_IPC_MBOX_DATA_ALLOC(mbox_data);
mbox_cfg.write_semaphore_num = READ_SEMAPHORE_NUM;
mbox_cfg.read_semaphore_num = WRITE_SEMAPHORE_NUM;
mbox_cfg.mailbox_idx = MBOX_IDX;
rslt0 = mtb_ipc_mbox_receiver_init(&obj, &receiver, mbox_data, &mbox_cfg);
for (int i = 0; i < MESSAGES_TO_SEND; ++i)
{
packet* received_packet = NULL;
rslt0 =
mtb_ipc_mbox_receiver_get(&receiver, (void**)&received_packet, MTB_IPC_NEVER_TIMEOUT);
if (received_packet != NULL)
{
//Do something
}
}
/*************************************************************/
/* Sender (CPU1) */
/*************************************************************/
cy_rslt_t rslt1;
mtb_ipc_t obj1;
mtb_ipc_config_t config2;
config2.internal_channel_index = MTB_IPC_CHAN_0;
config2.semaphore_irq = MTB_IPC_IRQ_USER + 2UL;
config2.queue_irq = MTB_IPC_IRQ_USER + 3UL;
config2.semaphore_num = IPC_SEMAPHORE_NUM;
rslt0 = mtb_ipc_get_handle(&obj1, &config2, 100);
mtb_ipc_mbox_sender_t sender;
/* Messages should be in shared memory using CY_SECTION_SHAREDMEM*/
packet task_message_arr[MESSAGES_TO_SEND];
rslt1 = mtb_ipc_mbox_sender_get_handle(&obj1, &sender, MBOX_IDX);
for (int i = 0; i < MESSAGES_TO_SEND; ++i)
{
rslt1 = mtb_ipc_mbox_sender_put(&sender, &task_message_arr[i], MTB_IPC_NEVER_TIMEOUT);
}
MTB_IPC_MBOX_DATA_ALLOC
#define MTB_IPC_MBOX_DATA_ALLOC(mailbox_data)
Macro for mailbox data shared memory allocation.
Definition: mtb_ipc_impl.h:251
mtb_ipc_mbox_data_t
IPC mailbox data element User should allocate but not modify anything in this struct.
Definition: mtb_ipc_impl.h:483
mtb_ipc_mbox_t
IPC mailbox handle element User should allocate but not modify anything in this struct.
Definition: mtb_ipc_impl.h:496
mtb_ipc_mbox_config_t::mailbox_idx
uint32_t mailbox_idx
The index of the mailbox.
Definition: mtb_ipc.h:347
mtb_ipc_mbox_config_t::write_semaphore_num
uint32_t write_semaphore_num
The semaphore number to use for guarding writes.
Definition: mtb_ipc.h:353
mtb_ipc_mbox_config_t::read_semaphore_num
uint32_t read_semaphore_num
The semaphore number to use for guarding reads.
Definition: mtb_ipc.h:350
mtb_ipc_mbox_sender_get_handle
cy_rslt_t mtb_ipc_mbox_sender_get_handle(mtb_ipc_t *obj, mtb_ipc_mbox_sender_t *sender, uint32_t mbox_idx)
Gets a handle pointer for a given mailbox index.
Definition: mtb_ipc.c:3014
mtb_ipc_mbox_receiver_init
cy_rslt_t mtb_ipc_mbox_receiver_init(mtb_ipc_t *obj, mtb_ipc_mbox_receiver_t *receiver, mtb_ipc_mbox_data_t *mbox_obj, const mtb_ipc_mbox_config_t *config)
Creates a single mailbox based on a given number.
Definition: mtb_ipc.c:2904
mtb_ipc_mbox_receiver_get
cy_rslt_t mtb_ipc_mbox_receiver_get(mtb_ipc_mbox_receiver_t *receiver, void **payload, uint64_t timeout_us)
Removes one item from the mailbox.
mtb_ipc_mbox_sender_put
cy_rslt_t mtb_ipc_mbox_sender_put(mtb_ipc_mbox_sender_t *sender, void *payload, uint64_t timeout_us)
Adds item to the mailbox.
mtb_ipc_mbox_config_t
User Config Struct to set up a Mailbox Items to be populated by caller before initialization Read/Wri...
Definition: mtb_ipc.h:344

## API Reference
| IPC Results
| IPC specific return codes.
| IPC
| Implementation specific interface for using the IPC library.

## Data Structures
struct | mtb_ipc_semaphore_config_t
| User Config Struct to set up a Semaphore Items to be populated by caller before initialization Semaphore number defines a specific semaphore and should be less than _MTB_IPC_SEMA_COUNT. More...
struct | mtb_ipc_mbox_config_t
| User Config Struct to set up a Mailbox Items to be populated by caller before initialization Read/Write Semaphore number defines a specific semaphore and should be less than _MTB_IPC_SEMA_COUNT. More...
struct | mtb_ipc_queue_config_t
| User Config Struct to set up a Queue Items to be populated by caller before initialization Combination of channel_num and queue_num uniquely defines a specific Queue. More...
struct | mtb_ipc_config_t
| IPC object config struct. More...

## Macros
#define | MTB_IPC_QUEUE_ALL_EVENTS ( MTB_IPC_QUEUE_WRITE | MTB_IPC_QUEUE_READ | MTB_IPC_QUEUE_FULL | MTB_IPC_QUEUE_EMPTY | MTB_IPC_QUEUE_RESET )
| Aggregate of all the Queue events.
#define | MTB_IPC_NEVER_TIMEOUT (0xFFFFFFFFFFFFFFFFUL)
| This define can be used as timeout argument for the IPC HAL driver functions, that take timeout as input parameter, in order to make function never time out (wait forever)
#define | MTB_IPC_NEVER_TIMEOUT_MS (0xFFFFFFFFUL)
| This define can be used as timeout argument for the IPC driver functions, that take timeout as input parameter, in order to make function never time out (wait forever) in functions that take ms an an argument.

## Typedefs
typedef void(* | mtb_ipc_queue_event_callback_t) (void *callback_arg, mtb_ipc_queue_event_t event)
| Queue Event handler for IPC interrupts.
typedef void(* | mtb_ipc_mbox_event_callback_t) (void *callback_arg, mtb_ipc_mbox_event_t event)
| Callback handler for IPC mailbox interrupts.

## Enumerations
enum | mtb_ipc_mbox_event_t { MTB_IPC_MBOX_FULL = 1 << 0UL , MTB_IPC_MBOX_EMPTY = 1 << 1UL }
| Flags enum of IPC Mailbox events. More...
enum | mtb_ipc_queue_event_t { MTB_IPC_NO_INTR = 0UL , MTB_IPC_QUEUE_WRITE = 1 << 0UL , MTB_IPC_QUEUE_READ = 1 << 1UL , MTB_IPC_QUEUE_FULL = 1 << 2UL , MTB_IPC_QUEUE_EMPTY = 1 << 3UL , MTB_IPC_QUEUE_RESET = 1 << 4UL }
| Flags enum of IPC events. More...

## Functions
cy_rslt_t | mtb_ipc_init (mtb_ipc_t *obj, mtb_ipc_shared_t *shared_data, const mtb_ipc_config_t *config)
| Initialize IPC library Driver. More...
cy_rslt_t | mtb_ipc_reinit_hw (const mtb_ipc_t *obj)
| Reinitialize IPC Hardware. More...
cy_rslt_t | mtb_ipc_get_handle (mtb_ipc_t *obj, const mtb_ipc_config_t *config, uint64_t timeout_ms)
| Get initialized IPC library Driver Call before any other IPC library functions. More...
void | mtb_ipc_semaphore_process_interrupt (mtb_ipc_t *obj)
| Process IPC library interrupt for Semaphores Place inside an ISR registered for the semaphore interrupt specified for this core during init. More...
void | mtb_ipc_queue_process_interrupt (const mtb_ipc_t *obj)
| Process IPC library interrupt for Queues Place inside an ISR registered for the queue interrupt specified for this core during init. More...
cy_rslt_t | mtb_ipc_semaphore_init (mtb_ipc_t *obj, mtb_ipc_semaphore_t *semaphore, mtb_ipc_semaphore_data_t *sema_obj, const mtb_ipc_semaphore_config_t *config)
| Creates a single semaphore based on a given number. More...
cy_rslt_t | mtb_ipc_semaphore_get_handle (mtb_ipc_t *obj, mtb_ipc_semaphore_t *semaphore, uint32_t semaphore_num, uint64_t timeout_us)
| Finds an already initialized semaphore based on a given number. More...
void | mtb_ipc_semaphore_free (const mtb_ipc_semaphore_t *semaphore)
| Frees the IPC semaphore. More...
cy_rslt_t | mtb_ipc_semaphore_take (const mtb_ipc_semaphore_t *semaphore, uint64_t timeout_us)
| Takes/acquires a semaphore. More...
cy_rslt_t | mtb_ipc_semaphore_give (const mtb_ipc_semaphore_t *semaphore)
| Gives/releases a semaphore. More...
cy_rslt_t | mtb_ipc_queue_init (mtb_ipc_t *obj, mtb_ipc_queue_t *queue, mtb_ipc_queue_data_t *queue_obj, const mtb_ipc_queue_config_t *config)
| Creates a new queue for a given IPC channel based on the given queue number and other parameters. More...
void | mtb_ipc_queue_free (mtb_ipc_queue_t *queue)
| Frees the queue. More...
cy_rslt_t | mtb_ipc_queue_get_handle (mtb_ipc_t *obj, mtb_ipc_queue_t *queue, uint32_t channel_num, uint32_t queue_num)
| Gets a handle pointer for a given IPC channel and queue number. More...
void | mtb_ipc_queue_register_callback (mtb_ipc_queue_t *queue, mtb_ipc_queue_event_callback_t callback, void *callback_arg)
| Registers a callback to be executed when certain events occur. More...
void | mtb_ipc_queue_enable_event (mtb_ipc_queue_t *queue, mtb_ipc_queue_event_t event, bool enable)
| Enables which events trigger the callback execution. More...
cy_rslt_t | mtb_ipc_queue_put (mtb_ipc_queue_t *queue, void *msg, uint64_t timeout_us)
| Adds one item to the queue. More...
cy_rslt_t | mtb_ipc_queue_get (mtb_ipc_queue_t *queue, void *msg, uint64_t timeout_us)
| Removes one item from the queue. More...
uint32_t | mtb_ipc_queue_count (const mtb_ipc_queue_t *queue)
| Returns how many items are in the queue. More...
cy_rslt_t | mtb_ipc_queue_reset (const mtb_ipc_queue_t *queue)
| Clears all the items in the queue. More...
cy_rslt_t | mtb_ipc_mbox_receiver_init (mtb_ipc_t *obj, mtb_ipc_mbox_receiver_t *receiver, mtb_ipc_mbox_data_t *mbox_obj, const mtb_ipc_mbox_config_t *config)
| Creates a single mailbox based on a given number. More...
cy_rslt_t | mtb_ipc_mbox_sender_get_handle (mtb_ipc_t *obj, mtb_ipc_mbox_sender_t *sender, uint32_t mbox_idx)
| Gets a handle pointer for a given mailbox index. More...
void | mtb_ipc_mbox_receiver_free (mtb_ipc_mbox_receiver_t *receiver)
| Frees the mailbox and disconnects the receiver handle. More...
void | mtb_ipc_mbox_sender_free (mtb_ipc_mbox_sender_t *sender)
| Disconnects the sender handle from the shared mailbox object. More...
void | mtb_ipc_mbox_receiver_register_callback (mtb_ipc_mbox_receiver_t *receiver, mtb_ipc_mbox_event_callback_t callback, void *callback_arg)
| Registers a callback to be executed on the receiver core when certain events occur. More...
void | mtb_ipc_mbox_sender_register_callback (mtb_ipc_mbox_sender_t *sender, mtb_ipc_mbox_event_callback_t callback, void *callback_arg)
| Registers a callback to be executed on the sender core when certain events occur. More...
cy_rslt_t | mtb_ipc_mbox_sender_put (mtb_ipc_mbox_sender_t *sender, void *payload, uint64_t timeout_us)
| Adds item to the mailbox. More...
cy_rslt_t | mtb_ipc_mbox_receiver_get (mtb_ipc_mbox_receiver_t *receiver, void **payload, uint64_t timeout_us)
| Removes one item from the mailbox. More...
void | mtb_ipc_mbox_receiver_enable_event (mtb_ipc_mbox_receiver_t *receiver, mtb_ipc_mbox_event_t event, bool enable)
| Enables which events trigger the callback execution for the receiver. More...
void | mtb_ipc_mbox_sender_enable_event (mtb_ipc_mbox_sender_t *sender, mtb_ipc_mbox_event_t event, bool enable)
| Enables which events trigger the callback execution for the sender. More...

## Data Structure Documentation

## ◆ mtb_ipc_semaphore_config_t

struct mtb_ipc_semaphore_config_t

Data Fields
bool | preemptable | Allows whether the semaphore can be preempted by another task. If preemptable is enabled (true), the user must ensure that there are no deadlocks in the system, which can be caused by an interrupt that occurs after the IPC channel is locked. Unless the user is ready to handle IPC channel locks correctly at the application level, set preemptable to false.
uint32_t | semaphore_num | The semaphore number to initialize. Please refer to implementation specific documentation for valid range for this parameter.

## ◆ mtb_ipc_mbox_config_t

struct mtb_ipc_mbox_config_t

Data Fields
uint32_t | mailbox_idx | The index of the mailbox. This must be unique as to not clash with other mailboxes.
uint32_t | read_semaphore_num | The semaphore number to use for guarding reads. The semaphore with this number will be automatically initialized by the mailbox
uint32_t | write_semaphore_num | The semaphore number to use for guarding writes. The semaphore with this number will be automatically initialized by the mailbox.

## ◆ mtb_ipc_queue_config_t

struct mtb_ipc_queue_config_t

Data Fields
mtb_ipc_channel_t | channel_num | IPC channel number (e.g. MTB_IPC_CHAN_0) Please refer to implementation specific documentation for number of available IPC channels for particular device.
uint32_t | queue_num | Queue number, which must be unique for each queue in scope of one IPC channel.
uint32_t | max_num_items | Maximum number of items (packets) allowed in the queue.
uint32_t | item_size | Size of each packet (item) in the Queue.
void * | queue_pool | Pointer to the queue packets in shared memory. This memory will be cleared by IPC library Queue Initialization. Packet list is an array of packets of max_num_items. It is used as a circular array, first_item is an index to first item stored.
uint32_t | semaphore_num | Semaphore number to use with this queue.

## ◆ mtb_ipc_config_t

struct mtb_ipc_config_t

Data Fields
mtb_ipc_channel_t | internal_channel_index | IPC channel number (e.g. MTB_IPC_CHAN_0) Please refer to implementation specific documentation for number of available IPC channels for particular device. This must match the IPC object initialized on the other core for this core to access the shared memory.
uint32_t | semaphore_irq | User Defined IRQ for use on this core for all semaphores. A unique IRQ must be used for each core
uint32_t | queue_irq | User Defined IRQ for use on this core for all queues. A unique IRQ must be used for each core
uint32_t | semaphore_num | User defined semaphore number to use for access to shared region and all MTB IPC operations.

## Enumeration Type Documentation

## ◆ mtb_ipc_mbox_event_t

enum mtb_ipc_mbox_event_t

Flags enum of IPC Mailbox events.

Multiple events can be enabled via mtb_ipc_mbox_receiver_enable_event mtb_ipc_mbox_sender_enable_event and the callback from mtb_ipc_mbox_receiver_register_callback or mtb_ipc_mbox_sender_register_callback will be run to notify.

Enumerator
MTB_IPC_MBOX_FULL | Mailbox is full.
MTB_IPC_MBOX_EMPTY | Mailbox is empty.

## ◆ mtb_ipc_queue_event_t

enum mtb_ipc_queue_event_t

Flags enum of IPC events.

Multiple events can be enabled via mtb_ipc_queue_enable_event and the callback from mtb_ipc_queue_register_callback will be run to notify.

Enumerator
MTB_IPC_NO_INTR | No interrupt.
MTB_IPC_QUEUE_WRITE | New item was written to the queue.
MTB_IPC_QUEUE_READ | New item was read from the queue.
MTB_IPC_QUEUE_FULL | Queue is full.
MTB_IPC_QUEUE_EMPTY | Queue is empty.
MTB_IPC_QUEUE_RESET | Queue was reset.

## Function Documentation

## ◆ mtb_ipc_init()

cy_rslt_t mtb_ipc_init | ( | mtb_ipc_t * | obj,
|  | mtb_ipc_shared_t * | shared_data,
|  | const mtb_ipc_config_t * | config
| ) |  |

Initialize IPC library Driver.

Call before any other IPC library functions. Must be called before any other core calls mtb_ipc_get_handle. The initialization of the semaphore must be done by the init core on startup or during cybsp_init() as the IPC driver assumes it has already been done. The MTB IPC has no way of ensuring it hasn't been already initialized on the channel, so it is up to user to ensure that init is called once on one core and mtb_ipc_get_handle is called on remaining core(s).

Parameters

  obj | - Object for the IPC library instance
  shared_data | - pointer to the allocated shared memory object. MTB_IPC_SHARED_DATA_ALLOC macro can (and not mandatory) be used in order to allocate memory for shared data (mtb_ipc_shared_t) in shared section.
  config | - The user-provided configuration. Fields internal_channel_index, semaphore_irq, queue_irq, semaphore_num are expected to be filled by user before initialization. Please refer to Snippet 1: Binary semaphore example for initialization guidance.

Returns
  CY_RSLT_SUCCESS MTB_IPC_RSLT_ERR_INVALID_PARAMETER MTB_IPC_RSLT_ERR_TIMEOUT

## ◆ mtb_ipc_reinit_hw()

cy_rslt_t mtb_ipc_reinit_hw | ( | const mtb_ipc_t * | obj | ) |

Reinitialize IPC Hardware.

If the underlying IPC hardware is reset (for example, because its containing power domain was powered off and then subsequently powered back on), this function must be called immediately after the IPC hardware is powered back on, before any other IPC operations are performed by any core.

Note
  It is only valid to call this function if `mtb_ipc_init` was previously called. This function may only be called from the core which originally called `mtb_ipc_init`.

Parameters

  obj | - Object for the IPC library instance

Returns
  CY_RSLT_SUCCESS MTB_IPC_RSLT_ERR_NOT_INITIALIZED

## ◆ mtb_ipc_get_handle()

cy_rslt_t mtb_ipc_get_handle | ( | mtb_ipc_t * | obj,
|  | const mtb_ipc_config_t * | config,
|  | uint64_t | timeout_ms
| ) |  |

Get initialized IPC library Driver Call before any other IPC library functions.

Call from Cores other than that which called mtb_ipc_init to initialize the system, timeout_ms is the timeout for waiting the initializing core to finish initialization. This function initializes the Shared Memory Data structures for IPC library Semaphore and IPC library Queue usage.

IRQ channels provided must be different than those used in mtb_ipc_init on the initialization core.

Parameters

  obj | - Object for the IPC library instance
  timeout_ms | - time in milliseconds for non-initializing core to wait for initializing core to complete initialization
  config | - User provided configuration of the IPC library instance, whose fields internal_ipc_channel, semaphore_num must match config on the core that initialized to ensure compatibility. Please refer to Snippet 1: Binary semaphore example for initialization guidance.

Returns
  CY_RSLT_SUCCESS MTB_IPC_RSLT_ERR_TIMEOUT MTB_IPC_RSLT_ERR_INVALID_PARAMETER MTB_IPC_RSLT_ERR_INVALID_IRQ_CHANNEL

## ◆ mtb_ipc_semaphore_process_interrupt()

void mtb_ipc_semaphore_process_interrupt | ( | mtb_ipc_t * | obj | ) |

Process IPC library interrupt for Semaphores Place inside an ISR registered for the semaphore interrupt specified for this core during init.

This function is used to perform interrupt functionality for instantiated semaphore objects.

Parameters

  obj | - Object for the IPC library instance

Process IPC library interrupt for Semaphores Place inside an ISR registered for the semaphore interrupt specified for this core during init.

It iterates through associated RTOS semaphores so it only is looking for relevant semaphores instead of whole linked list.

Set index to unused as the interrupt has signaled it was given

## ◆ mtb_ipc_queue_process_interrupt()

void mtb_ipc_queue_process_interrupt | ( | const mtb_ipc_t * | obj | ) |

Process IPC library interrupt for Queues Place inside an ISR registered for the queue interrupt specified for this core during init.

This function is used to perform interrupt functionality for instantiated queue objects.

Parameters

  obj | - Object for the IPC library instance

Process IPC library interrupt for Queues Place inside an ISR registered for the queue interrupt specified for this core during init.

## ◆ mtb_ipc_semaphore_init()

cy_rslt_t mtb_ipc_semaphore_init | ( | mtb_ipc_t * | obj,
|  | mtb_ipc_semaphore_t * | semaphore,
|  | mtb_ipc_semaphore_data_t * | sema_obj,
|  | const mtb_ipc_semaphore_config_t * | config
| ) |  |

Creates a single semaphore based on a given number.

The semaphore number range starts at 0. the max number depends on a few factors max = _MTB_IPC_SEMA_COUNT - 1 (IPC driver semaphore) - num_queues - (num_queues * num_processes_per_queue)

Note
  MTB_IPC_SEMAPHORE_DATA_ALLOC macro can (and not mandatory) be used in order to allocate memory for semaphore data (mtb_ipc_semaphore_data_t) in shared section. This function must be called before accessing the semaphore. Only one core must call this function. Other cores call mtb_ipc_semaphore_get_handle to retrieve this information after initialization.

Parameters

  [out] | obj | Pointer to an IPC object. Must be initialized by mtb_ipc_init before initializing a semaphore.
  [out] | semaphore | Handle to an IPC semaphore. This handle exists per core and is for api access to the shared sema_obj.
  [in] | sema_obj | Semaphore data stored in shared memory.
  [in] | config | The user-provided configuration. Please refer to Snippet 1: Binary semaphore example for initialization guidance

Returns
  CY_RSLT_SUCCESS MTB_IPC_RSLT_ERR_INVALID_PARAMETER MTB_IPC_RSLT_ERR_SEMA_NUM_IN_USE MTB_IPC_RSLT_ERR_SEMA_FAIL MTB_IPC_RSLT_ERR_CANT_OPERATE_IN_ISR_W_TIMEOUT MTB_IPC_RSLT_ERR_SEMA_TAKEN

## ◆ mtb_ipc_semaphore_get_handle()

cy_rslt_t mtb_ipc_semaphore_get_handle | ( | mtb_ipc_t * | obj,
|  | mtb_ipc_semaphore_t * | semaphore,
|  | uint32_t | semaphore_num,
|  | uint64_t | timeout_us
| ) |  |

Finds an already initialized semaphore based on a given number.

This function must be called before accessing the semaphore from a different Core than it was initialized on. mtb_ipc_semaphore_init must be called on the initializing core before this function is called, else it will timeout.

Parameters

  [out] | obj | Handle to an IPC object pointer.
  [out] | semaphore | Handle to an IPC semaphore. This handle exists per core and is for api access to the shared semaphore data.
  [in] | semaphore_num | The semaphore number to get a pointer for
  [in] | timeout_us | Timeout (in uSec) to wait while trying to get the handle

Returns
  CY_RSLT_SUCCESS MTB_IPC_RSLT_ERR_INVALID_PARAMETER MTB_IPC_RSLT_ERR_NO_SEMA_AVAILABLE MTB_IPC_RSLT_ERR_CANT_OPERATE_IN_ISR_W_TIMEOUT MTB_IPC_RSLT_ERR_SEMA_TAKEN

Finds an already initialized semaphore based on a given number.

## ◆ mtb_ipc_semaphore_free()

void mtb_ipc_semaphore_free | ( | const mtb_ipc_semaphore_t * | semaphore | ) |

Frees the IPC semaphore.

This function frees the resources associated with the semaphore.

Parameters

  [in] | semaphore | The semaphore object.

Frees the IPC semaphore.

## ◆ mtb_ipc_semaphore_take()

cy_rslt_t mtb_ipc_semaphore_take | ( | const mtb_ipc_semaphore_t * | semaphore,
|  | uint64_t | timeout_us
| ) |  |

Takes/acquires a semaphore.

If the semaphore is available, it is acquired and this function returns. This function has a timeout argument (in microseconds). If the semaphore is not available, it blocks until it times out or succeeds in acquiring it.

Parameters

  [in] | semaphore | The semaphore object.
  [in] | timeout_us | Timeout in microseconds. Value 0 can be used if no timeout needed while MTB_IPC_NEVER_TIMEOUT can be used to make function block until semaphore is successfully taken.

Returns
  CY_RSLT_SUCCESS MTB_IPC_RSLT_ERR_INVALID_PARAMETER MTB_IPC_RSLT_ERR_SEMA_TAKEN MTB_IPC_RSLT_ERR_SEMA_FAIL MTB_IPC_RSLT_ERR_CANT_OPERATE_IN_ISR_W_TIMEOUT

## ◆ mtb_ipc_semaphore_give()

cy_rslt_t mtb_ipc_semaphore_give | ( | const mtb_ipc_semaphore_t * | semaphore | ) |

Gives/releases a semaphore.

The semaphore is released allowing other tasks waiting on the semaphore to take it.

Parameters

  [in] | semaphore | The semaphore object.

Returns
  CY_RSLT_SUCCESS MTB_IPC_RSLT_ERR_SEMA_FAIL MTB_IPC_RSLT_ERR_INVALID_PARAMETER MTB_IPC_RSLT_ERR_CANT_OPERATE_IN_ISR_W_TIMEOUT

## ◆ mtb_ipc_queue_init()

cy_rslt_t mtb_ipc_queue_init | ( | mtb_ipc_t * | obj,
|  | mtb_ipc_queue_t * | queue,
|  | mtb_ipc_queue_data_t * | queue_obj,
|  | const mtb_ipc_queue_config_t * | config
| ) |  |

Creates a new queue for a given IPC channel based on the given queue number and other parameters.

This function requires mtb_ipc_queue_data_t (queue_obj) pointer to shared memory. mtb_ipc_queue_data_t is used by other tasks/CPUs to refer to the queue. Note that this function must be called only by one of the tasks/CPUs for the same IPC channel. This CPU can call the function multiple times for the same IPC channel, but with a different queue number. The IPC channel index must be different from the channel index used for mtb_ipc_init because that channel is used internally by the semaphores.

Note
  MTB_IPC_QUEUE_DATA_ALLOC and MTB_IPC_QUEUE_POOL_ALLOC macro can (and not mandatory) be used in order to allocate memory for (respectively) queue data (mtb_ipc_queue_data_t) and queue pool in shared section. Please refer to implementation specific documentation for the requirements for memory allocation if macro is not used. Please refer to Snippet 2: Message queue example for initialization guidance.

Parameters

  [out] | obj | Pointer to an IPC object. Must be initialized by mtb_ipc_init before initializing a queue.
  [out] | queue | Queue handle used to reference queue_obj store in shared memory. The queue acts as the per-core handle for the shared data.
  [in] | queue_obj | Queue data object stored in shared memory.
  [in] | config | The user-provided configuration. Please refer to Snippet 2: Message queue example for initialization guidance.

Returns
  CY_RSLT_SUCCESS MTB_IPC_RSLT_ERR_INVALID_PARAMETER MTB_IPC_RSLT_ERR_SEMA_TAKEN MTB_IPC_RSLT_ERR_SEMA_FAIL MTB_IPC_RSLT_ERR_CANT_OPERATE_IN_ISR_W_TIMEOUT MTB_IPC_RSLT_ERR_QUEUE_NOT_FOUND

## ◆ mtb_ipc_queue_free()

void mtb_ipc_queue_free | ( | mtb_ipc_queue_t * | queue | ) |

Frees the queue.

This operation only removes the queue handle from the list of available queues. The queue pool and the queue handle allocated in the shared memory need to be freed (if dynamically allocated) by the application.

Parameters

  [out] | queue | Queue handle used to reference queue_obj store in shared memory. The queue acts as the per-core handle for the shared data.

## ◆ mtb_ipc_queue_get_handle()

cy_rslt_t mtb_ipc_queue_get_handle | ( | mtb_ipc_t * | obj,
|  | mtb_ipc_queue_t * | queue,
|  | uint32_t | channel_num,
|  | uint32_t | queue_num
| ) |  |

Gets a handle pointer for a given IPC channel and queue number.

This function should be called by other tasks/CPUs that have not called the initialization function. Unpredicted behavior can happen if this function is called before mtb_ipc_queue_init. Please refer to implementation specific documentation for additional details.

Parameters

  [out] | obj | The IPC object handle.
  [in] | queue | Queue handle used to reference queue_obj store in shared memory. The queue acts as the per-core handle for the shared data.
  [in] | channel_num | IPC channel to use for the queue messaging.
  [in] | queue_num | Queue number.

Returns
  CY_RSLT_SUCCESS MTB_IPC_RSLT_ERR_INVALID_PARAMETER MTB_IPC_RSLT_ERR_SEMA_TAKEN MTB_IPC_RSLT_ERR_SEMA_FAIL MTB_IPC_RSLT_ERR_CANT_OPERATE_IN_ISR_W_TIMEOUT MTB_IPC_RSLT_ERR_QUEUE_NOT_FOUND

## ◆ mtb_ipc_queue_register_callback()

void mtb_ipc_queue_register_callback | ( | mtb_ipc_queue_t * | queue,
|  | mtb_ipc_queue_event_callback_t | callback,
|  | void * | callback_arg
| ) |  |

Registers a callback to be executed when certain events occur.

Parameters

  [in] | queue | Queue handle used to reference queue_obj store in shared memory. The queue acts as the per-core handle for the shared data.
  [in] | callback | The callback handler which will be invoked when an event triggers.
  [in] | callback_arg | Generic argument that will be provided to the callback when called.

## ◆ mtb_ipc_queue_enable_event()

void mtb_ipc_queue_enable_event | ( | mtb_ipc_queue_t * | queue,
|  | mtb_ipc_queue_event_t | event,
|  | bool | enable
| ) |  |

Enables which events trigger the callback execution.

It can trigger when a new item is written to the queue, read from the queue, when the queue becomes full, when the queue becomes empty or when there is a reset. Note that these events might execute callbacks associated to all queues that belong to an IPC channel.

Parameters

  [in] | queue | Queue handle used to reference queue_obj store in shared memory. The queue acts as the per-core handle for the shared data.
  [in] | event | The IPC event type
  [in] | enable | True to turn on specified events, False to turn off

Enables which events trigger the callback execution.

## ◆ mtb_ipc_queue_put()

cy_rslt_t mtb_ipc_queue_put | ( | mtb_ipc_queue_t * | queue,
|  | void * | msg,
|  | uint64_t | timeout_us
| ) |  |

Adds one item to the queue.

This function can be called by any task/CPU. This function has a timeout argument (in microseconds). If the queue is full, it stays there until it times out or the queue is no longer full. This function can be blocking or non-blocking (timeout set to ZERO).

Parameters

  [in] | queue | Queue handle used to reference queue_obj store in shared memory. The queue acts as the per-core handle for the shared data.
  [in] | msg | Location of message queue item
  [in] | timeout_us | Timeout in microseconds. Value 0 can be used if no timeout needed while MTB_IPC_NEVER_TIMEOUT can be used to make function block until element is successfully put into the queue.

Returns
  CY_RSLT_SUCCESS MTB_IPC_RSLT_ERR_INVALID_PARAMETER MTB_IPC_RSLT_ERR_SEMA_TAKEN MTB_IPC_RSLT_ERR_SEMA_FAIL MTB_IPC_RSLT_ERR_CANT_OPERATE_IN_ISR_W_TIMEOUT MTB_IPC_RSLT_ERR_QUEUE_NOT_FOUND MTB_IPC_RSLT_ERR_QUEUE_FULL

## ◆ mtb_ipc_queue_get()

cy_rslt_t mtb_ipc_queue_get | ( | mtb_ipc_queue_t * | queue,
|  | void * | msg,
|  | uint64_t | timeout_us
| ) |  |

Removes one item from the queue.

This function can be called by any task/CPU. This function has a timeout argument (in microseconds). If the queue is empty, it stays there until it times out or the queue receives a new item. This function can be blocking or non-blocking (timeout set to ZERO).

Parameters

  [in] | queue | Queue handle used to reference queue_obj store in shared memory. The queue acts as the per-core handle for the shared data.
  [out] | msg | Location to copy message queue item to
  [in] | timeout_us | Timeout in microseconds. Value 0 can be used if no timeout needed while MTB_IPC_NEVER_TIMEOUT can be used to make function block until element is successfully taken from the queue.

Returns
  CY_RSLT_SUCCESS MTB_IPC_RSLT_ERR_INVALID_PARAMETER MTB_IPC_RSLT_ERR_SEMA_TAKEN MTB_IPC_RSLT_ERR_SEMA_FAIL MTB_IPC_RSLT_ERR_CANT_OPERATE_IN_ISR_W_TIMEOUT MTB_IPC_RSLT_ERR_QUEUE_NOT_FOUND MTB_IPC_RSLT_ERR_QUEUE_EMPTY

Removes one item from the queue.

## ◆ mtb_ipc_queue_count()

uint32_t mtb_ipc_queue_count | ( | const mtb_ipc_queue_t * | queue | ) |

Returns how many items are in the queue.

This function can be called by any task/CPU.

Parameters

  [in] | queue | Queue handle used to reference queue_obj store in shared memory. The queue acts as the per-core handle for the shared data.

Returns
  Number of items in the queue

Returns how many items are in the queue.

## ◆ mtb_ipc_queue_reset()

cy_rslt_t mtb_ipc_queue_reset | ( | const mtb_ipc_queue_t * | queue | ) |

Clears all the items in the queue.

This function can be called by the any task/CPU.

Parameters

  [in] | queue | Queue handle used to reference queue_obj store in shared memory. The queue acts as the per-core handle for the shared data.

Returns
  CY_RSLT_SUCCESS MTB_IPC_RSLT_ERR_INVALID_PARAMETER

Clears all the items in the queue.

## ◆ mtb_ipc_mbox_receiver_init()

cy_rslt_t mtb_ipc_mbox_receiver_init | ( | mtb_ipc_t * | obj,
|  | mtb_ipc_mbox_receiver_t * | receiver,
|  | mtb_ipc_mbox_data_t * | mbox_obj,
|  | const mtb_ipc_mbox_config_t * | config
| ) |  |

Creates a single mailbox based on a given number.

The mailbox number range is 0- MTB_IPC_MAX_MBOXES.

Note
  MTB_IPC_MBOX_DATA_ALLOC macro can (and not mandatory) be used in order to allocate memory for mailbox data (mtb_ipc_mbox_data_t) in the shared section. This function must be called before accessing the mailbox. Only one core must call this function. Other cores have to call mtb_ipc_mbox_sender_get_handle to retrieve this information after initialization. Do not call this in an interrupt service routine.

Parameters

  [in] | obj | Pointer to an IPC object. Must be initialized by mtb_ipc_init before initializing a mailbox.
  [out] | receiver | Handle to the mailbox on the core intended to be the receiver.
  [in] | mbox_obj | Mailbox data stored in shared memory.
  [in] | config | The user-provided configuration. Please refer to Snippet 1: Binary semaphore example for initialization guidance

Returns
  CY_RSLT_SUCCESS MTB_IPC_RSLT_ERR_INVALID_PARAMETER MTB_IPC_RSLT_ERR_SEMA_NUM_IN_USE MTB_IPC_RSLT_ERR_MBOX_IDX_IN_USE MTB_IPC_RSLT_ERR_SEMA_FAIL MTB_IPC_RSLT_ERR_SEMA_TAKEN

## ◆ mtb_ipc_mbox_sender_get_handle()

cy_rslt_t mtb_ipc_mbox_sender_get_handle | ( | mtb_ipc_t * | obj,
|  | mtb_ipc_mbox_sender_t * | sender,
|  | uint32_t | mbox_idx
| ) |  |

Gets a handle pointer for a given mailbox index.

This function should be called by the core intended to be the mailbox sender. Unpredicted behavior can happen if this function is called before mtb_ipc_mbox_receiver_init. Do not call this in an interrupt service routine.

Parameters

  [in] | obj | The IPC object handle.
  [out] | sender | Handle to the mailbox on the core intended to be the sender
  [in] | mbox_idx | Mailbox number in range 0 - MTB_IPC_MAX_MBOXES.

Returns
  CY_RSLT_SUCCESS MTB_IPC_RSLT_ERR_INVALID_PARAMETER MTB_IPC_RSLT_ERR_SEMA_TAKEN MTB_IPC_RSLT_ERR_MBOX_NOT_FOUND

THis function cannot be called in an ISR

## ◆ mtb_ipc_mbox_receiver_free()

void mtb_ipc_mbox_receiver_free | ( | mtb_ipc_mbox_receiver_t * | receiver | ) |

Frees the mailbox and disconnects the receiver handle.

This should be called after freeing the sender on the other core.

This operation only removes the mailbox handle from the list of available mailboxes. The mailbox object allocated in the shared memory needs to be freed (if dynamically allocated) by the application.

Parameters

  [out] | receiver | Mailbox handle used to reference mbox_object stored in shared memory. The receiver acts as the per-core handle for the shared data.

## ◆ mtb_ipc_mbox_sender_free()

void mtb_ipc_mbox_sender_free | ( | mtb_ipc_mbox_sender_t * | sender | ) |

Disconnects the sender handle from the shared mailbox object.

This must be done before mtb_ipc_mbox_receiver_free.

This operation only removes the mailbox handle from the list of available mailboxes. The mailbox object allocated in the shared memory needs to be freed (if dynamically allocated) by the application.

Parameters

  [out] | sender | Mailbox handle used to reference mbox_object stored in shared memory. The sender acts as the per-core handle for the shared data.

## ◆ mtb_ipc_mbox_receiver_register_callback()

void mtb_ipc_mbox_receiver_register_callback | ( | mtb_ipc_mbox_receiver_t * | receiver,
|  | mtb_ipc_mbox_event_callback_t | callback,
|  | void * | callback_arg
| ) |  |

Registers a callback to be executed on the receiver core when certain events occur.

Parameters

  [in] | receiver | Mailbox handle used to reference mbox_obj store in shared memory. The receiver acts as the per-core handle for the shared data.
  [in] | callback | The callback handler which will be invoked when an event triggers.
  [in] | callback_arg | Generic argument that will be provided to the callback when called.

## ◆ mtb_ipc_mbox_sender_register_callback()

void mtb_ipc_mbox_sender_register_callback | ( | mtb_ipc_mbox_sender_t * | sender,
|  | mtb_ipc_mbox_event_callback_t | callback,
|  | void * | callback_arg
| ) |  |

Registers a callback to be executed on the sender core when certain events occur.

Parameters

  [in] | sender | Mailbox handle used to reference mbox_obj store in shared memory. The sender acts as the per-core handle for the shared data.
  [in] | callback | The callback handler which will be invoked when an event triggers.
  [in] | callback_arg | Generic argument that will be provided to the callback when called.

## ◆ mtb_ipc_mbox_sender_put()

cy_rslt_t mtb_ipc_mbox_sender_put | ( | mtb_ipc_mbox_sender_t * | sender,
|  | void * | payload,
|  | uint64_t | timeout_us
| ) |  |

Adds item to the mailbox.

This function can only be called by the sender for this mailbox. If the mailbox is full, it stays there until it times out or the mailbox is no longer full. This function can be blocking or non-blocking (timeout set to ZERO).

Parameters

  [in] | sender | Mailbox handle used to reference mailbox object store in shared memory. The sender acts as the per-core handle for the shared data.
  [in] | payload | Location of payload item
  [in] | timeout_us | Timeout in microseconds. Value 0 can be used if no timeout needed while MTB_IPC_NEVER_TIMEOUT can be used to make function block until element is successfully put into the mailbox.

Returns
  CY_RSLT_SUCCESS MTB_IPC_RSLT_ERR_INVALID_PARAMETER MTB_IPC_RSLT_ERR_TIMEOUT MTB_IPC_RSLT_ERR_CANT_OPERATE_IN_ISR_W_TIMEOUT MTB_IPC_RSLT_ERR_MBOX_FULL

## ◆ mtb_ipc_mbox_receiver_get()

cy_rslt_t mtb_ipc_mbox_receiver_get | ( | mtb_ipc_mbox_receiver_t * | receiver,
|  | void ** | payload,
|  | uint64_t | timeout_us
| ) |  |

Removes one item from the mailbox.

This function can be only called by a receiver handle. This function has a timeout argument (in microseconds). If the mailbox is empty, it stays there until it times out or the mailbox receives a new item. This function can be blocking or non-blocking (timeout set to ZERO).

Parameters

  [in] | receiver | Mailbox handle used to reference mbox_obj store in shared memory. The receiver acts as the per-core handle for the shared data.
  [out] | payload | Location to copy message mailbox item to
  [in] | timeout_us | Timeout in microseconds. Value 0 can be used if no timeout needed while MTB_IPC_NEVER_TIMEOUT can be used to make function block until element is successfully taken from the mailbox.

Returns
  CY_RSLT_SUCCESS MTB_IPC_RSLT_ERR_INVALID_PARAMETER MTB_IPC_RSLT_ERR_TIMEOUT MTB_IPC_RSLT_ERR_CANT_OPERATE_IN_ISR_W_TIMEOUT MTB_IPC_RSLT_ERR_MBOX_EMPTY

## ◆ mtb_ipc_mbox_receiver_enable_event()

void mtb_ipc_mbox_receiver_enable_event | ( | mtb_ipc_mbox_receiver_t * | receiver,
|  | mtb_ipc_mbox_event_t | event,
|  | bool | enable
| ) |  |

Enables which events trigger the callback execution for the receiver.

It can trigger for these events mtb_ipc_mbox_event_t.

Parameters

  [in] | receiver | Mailbox handle used to reference mbox_obj stored in shared memory. The receiver acts as the per-core handle for the shared data.
  [in] | event | The IPC mailbox event type
  [in] | enable | True to turn on specified events, False to turn off

## ◆ mtb_ipc_mbox_sender_enable_event()

void mtb_ipc_mbox_sender_enable_event | ( | mtb_ipc_mbox_sender_t * | sender,
|  | mtb_ipc_mbox_event_t | event,
|  | bool | enable
| ) |  |

Enables which events trigger the callback execution for the sender.

It can trigger for these events mtb_ipc_mbox_event_t.

Parameters

  [in] | sender | Mailbox handle used to reference mbox_obj stored in shared memory. The sender acts as the per-core handle for the shared data.
  [in] | event | The IPC mailbox event type
  [in] | enable | True to turn on specified events, False to turn off