mbed-os/components/TARGET_PSA/spm/COMPONENT_SPM_MAILBOX/ipc_queue.h

127 lines
3.7 KiB
C

/* Copyright (c) 2018 ARM Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __PSA_MBED_IPC_QUEUE_H__
#define __PSA_MBED_IPC_QUEUE_H__
// Includes
// --------
#include "mbed_assert.h"
#include "cmsis_os2.h"
#include "cmsis_compiler.h"
#include "rtx_lib.h"
// IPC Queue Definitions
// ---------------------
#ifndef IPC_QUEUE_SLOTS
#define IPC_QUEUE_SLOTS 4
#endif
// Maximum number of queue items equals (IPC_QUEUE_SLOTS - 1).
// Therefore we enforce a minimum of 2 IPC_QUEUE_SLOTS
#if IPC_QUEUE_SLOTS <= 1
#undef IPC_QUEUE_SLOTS
#define IPC_QUEUE_SLOTS 2
#endif
#define IPC_QUEUE_BASE_MAGIC 0x63284A0C
#define IPC_QUEUE_PRODUCER_MAGIC 0XA248D9FF
#define IPC_QUEUE_CONSUMER_MAGIC 0XA68B6542
#define IPC_QUEUE_WAIT_ON_FULL_MS 500
#define IPC_QUEUE_WAIT_ON_EMPTY_MS 500
#define IPC_QUEUE_SEM_MAX_COUNT (1UL) // Maximum number of available tokens for an IPC Queue semaphore
#define IPC_QUEUE_SEM_INITIAL_COUNT (0UL) // Initial number of available tokens for an IPC Queue semaphore
// NOTE: STRUCT SIZE MUST BE 4 BYTES ALIGNED !!
typedef __PACKED_STRUCT ipc_queue_item_t {
uint32_t a;
uint32_t b;
uint32_t c;
} __ALIGNED(4) ipc_queue_item_t;
MBED_STATIC_ASSERT((sizeof(ipc_queue_item_t) % sizeof(uint32_t) == 0), "ipc_queue_item_t: Struct size must be 4 bytes aligned!");
// NOTE: STRUCT SIZE MUST BE 4 BYTES ALIGNED !!
typedef __PACKED_STRUCT ipc_base_queue_t {
uint32_t magic;
volatile uint32_t read_idx;
volatile uint32_t write_idx;
ipc_queue_item_t data[IPC_QUEUE_SLOTS];
} __ALIGNED(4) ipc_base_queue_t;
MBED_STATIC_ASSERT((sizeof(ipc_base_queue_t) % sizeof(uint32_t) == 0), "ipc_base_queue_t: Struct size must be 4 bytes aligned!");
typedef struct ipc_producer_queue_t {
uint32_t magic;
volatile __PACKED uint32_t *read_idx;
volatile __PACKED uint32_t *write_idx;
__PACKED ipc_queue_item_t *data;
osMutexId_t mutex;
osSemaphoreId_t full_queue_sem;
} ipc_producer_queue_t;
typedef struct ipc_consumer_queue_t {
uint32_t magic;
volatile __PACKED uint32_t *read_idx;
volatile __PACKED uint32_t *write_idx;
__PACKED ipc_queue_item_t *data;
osSemaphoreId_t read_sem;
} ipc_consumer_queue_t;
// Event handling functions
// ------------------------
void on_new_item(void);
void on_vacancy(void);
void on_popped_item(ipc_queue_item_t item);
// IPC Queue API
// -------------
void ipc_producer_queue_init(ipc_producer_queue_t *queue,
ipc_base_queue_t *base_queue_mem,
osMutexId_t mutex,
osSemaphoreId_t full_queue_sem
);
void ipc_consumer_queue_init(ipc_consumer_queue_t *queue,
ipc_base_queue_t *base_queue_mem,
osSemaphoreId_t read_sem
);
void ipc_queue_enqueue(ipc_producer_queue_t *queue,
ipc_queue_item_t item_ptr
);
void ipc_queue_drain(ipc_consumer_queue_t *queue);
#endif // __PSA_MBED_IPC_QUEUE_H__