/* 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__