324 lines
9.0 KiB
C
324 lines
9.0 KiB
C
|
/*
|
||
|
* This is the MCC library header file
|
||
|
*
|
||
|
* Copyright (C) 2014-2015 Freescale Semiconductor, Inc. All Rights Reserved.
|
||
|
*
|
||
|
*
|
||
|
* SPDX-License-Identifier: GPL-2.0+ and/or BSD-3-Clause
|
||
|
* The GPL-2.0+ license for this file can be found in the COPYING.GPL file
|
||
|
* included with this distribution or at
|
||
|
* http://www.gnu.org/licenses/gpl-2.0.html
|
||
|
* The BSD-3-Clause License for this file can be found in the COPYING.BSD file
|
||
|
* included with this distribution or at
|
||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||
|
*/
|
||
|
|
||
|
#ifndef __MCC_COMMON__
|
||
|
#define __MCC_COMMON__
|
||
|
|
||
|
#define MCC_INIT_STRING "mccisrd"
|
||
|
#define MCC_VERSION_STRING "002.000"
|
||
|
#define null ((void*)0)
|
||
|
|
||
|
/*!
|
||
|
* \brief MCC_BOOLEAN type.
|
||
|
*
|
||
|
* Boolean type definiton for the MCC library.
|
||
|
*/
|
||
|
typedef unsigned int MCC_BOOLEAN;
|
||
|
|
||
|
/*!
|
||
|
* \brief MCC_MEM_SIZE type.
|
||
|
*
|
||
|
* Mem size type definiton for the MCC library.
|
||
|
*/
|
||
|
typedef unsigned int MCC_MEM_SIZE;
|
||
|
|
||
|
/*!
|
||
|
* \brief MCC_CORE type.
|
||
|
*
|
||
|
* This unsigned integer value specifies the core number for the endpoint definition.
|
||
|
*
|
||
|
* \see MCC_NODE
|
||
|
* \see MCC_PORT
|
||
|
* \see MCC_ENDPOINT
|
||
|
*/
|
||
|
typedef unsigned int MCC_CORE;
|
||
|
|
||
|
/*!
|
||
|
* \brief MCC_NODE type.
|
||
|
*
|
||
|
* This unsigned integer value specifies the node number for the endpoint definition.
|
||
|
*
|
||
|
* \see MCC_CORE
|
||
|
* \see MCC_PORT
|
||
|
* \see MCC_ENDPOINT
|
||
|
*/
|
||
|
typedef unsigned int MCC_NODE;
|
||
|
|
||
|
/*!
|
||
|
* \brief MCC_PORT type.
|
||
|
*
|
||
|
* This unsigned integer value specifies the port number for the endpoint definition.
|
||
|
*
|
||
|
* \see MCC_CORE
|
||
|
* \see MCC_NODE
|
||
|
* \see MCC_ENDPOINT
|
||
|
*/
|
||
|
typedef unsigned int MCC_PORT;
|
||
|
|
||
|
#if defined(__IAR_SYSTEMS_ICC__)
|
||
|
__packed
|
||
|
#endif
|
||
|
/*!
|
||
|
* \brief Endpoint structure.
|
||
|
*
|
||
|
* Endpoints are receive buffer queues, implemented in shared RAM,
|
||
|
* and are addressed by a triplet containing core, node, and port.
|
||
|
*
|
||
|
* \see MCC_BOOKEEPING_STRUCT
|
||
|
* \see MCC_CORE
|
||
|
* \see MCC_NODE
|
||
|
* \see MCC_PORT
|
||
|
*/
|
||
|
struct mcc_endpoint {
|
||
|
/*! \brief Core number - identifies the core within the processor */
|
||
|
MCC_CORE core;
|
||
|
|
||
|
/*! \brief Node number - in Linux any user process participating in MCC is a unique node;
|
||
|
MQX has only one node */
|
||
|
MCC_NODE node;
|
||
|
|
||
|
/*! \brief Port number - both Linux and MQX can have an arbitrary number of ports per node */
|
||
|
MCC_PORT port;
|
||
|
#if defined(__IAR_SYSTEMS_ICC__)
|
||
|
};
|
||
|
#else
|
||
|
}__attribute__((packed));
|
||
|
#endif
|
||
|
typedef struct mcc_endpoint MCC_ENDPOINT;
|
||
|
|
||
|
#if defined(__IAR_SYSTEMS_ICC__)
|
||
|
__packed
|
||
|
#endif
|
||
|
/*!
|
||
|
* \brief Receive buffer structure.
|
||
|
*
|
||
|
* This is the receive buffer structure used for exchanging data.
|
||
|
*
|
||
|
* \see MCC_BOOKEEPING_STRUCT
|
||
|
*/
|
||
|
struct mcc_receive_buffer {
|
||
|
/*! \brief Pointer to the next receive buffer */
|
||
|
struct mcc_receive_buffer *next;
|
||
|
|
||
|
/*! \brief Source endpoint */
|
||
|
MCC_ENDPOINT source;
|
||
|
|
||
|
/*! \brief Length of data stored in this buffer */
|
||
|
MCC_MEM_SIZE data_len;
|
||
|
|
||
|
/*! \brief Space for data storage */
|
||
|
char data [MCC_ATTR_BUFFER_SIZE_IN_BYTES];
|
||
|
#if defined(__IAR_SYSTEMS_ICC__)
|
||
|
};
|
||
|
#else
|
||
|
}__attribute__((packed));
|
||
|
#endif
|
||
|
typedef struct mcc_receive_buffer MCC_RECEIVE_BUFFER;
|
||
|
|
||
|
#if defined(__IAR_SYSTEMS_ICC__)
|
||
|
__packed
|
||
|
#endif
|
||
|
/*!
|
||
|
* \brief List of buffers.
|
||
|
*
|
||
|
* Each endpoint keeps the list of received buffers.
|
||
|
* The list of free buffers is kept in bookkeeping data structure.
|
||
|
*
|
||
|
* \see MCC_RECEIVE_BUFFER
|
||
|
* \see MCC_BOOKEEPING_STRUCT
|
||
|
*/
|
||
|
struct mcc_receive_list {
|
||
|
/*! \brief Head of a buffers list */
|
||
|
MCC_RECEIVE_BUFFER * head;
|
||
|
|
||
|
/*! \brief Tail of a buffers list */
|
||
|
MCC_RECEIVE_BUFFER * tail;
|
||
|
#if defined(__IAR_SYSTEMS_ICC__)
|
||
|
};
|
||
|
#else
|
||
|
}__attribute__((packed));
|
||
|
#endif
|
||
|
typedef struct mcc_receive_list MCC_RECEIVE_LIST;
|
||
|
|
||
|
#define BUFFER_QUEUED (0)
|
||
|
#define BUFFER_FREED (1)
|
||
|
typedef unsigned int MCC_SIGNAL_TYPE;
|
||
|
#if defined(__IAR_SYSTEMS_ICC__)
|
||
|
__packed
|
||
|
#endif
|
||
|
/*!
|
||
|
* \brief Signals and signal queues.
|
||
|
*
|
||
|
* This is one item of a signal queue.
|
||
|
*
|
||
|
* \see MCC_SIGNAL_TYPE
|
||
|
* \see MCC_ENDPOINT
|
||
|
* \see MCC_BOOKEEPING_STRUCT
|
||
|
*/
|
||
|
struct mcc_signal {
|
||
|
/*! \brief Signal type - BUFFER_QUEUED or BUFFER_FREED */
|
||
|
MCC_SIGNAL_TYPE type;
|
||
|
|
||
|
/*! \brief Destination endpoint */
|
||
|
MCC_ENDPOINT destination;
|
||
|
#if defined(__IAR_SYSTEMS_ICC__)
|
||
|
};
|
||
|
#else
|
||
|
}__attribute__((packed));
|
||
|
#endif
|
||
|
typedef struct mcc_signal MCC_SIGNAL;
|
||
|
|
||
|
#if defined(__IAR_SYSTEMS_ICC__)
|
||
|
__packed
|
||
|
#endif
|
||
|
/*!
|
||
|
* \brief Endpoint registration table.
|
||
|
*
|
||
|
* This is used for matching each endpoint structure with it's list of received buffers.
|
||
|
*
|
||
|
* \see MCC_ENDPOINT
|
||
|
* \see MCC_RECEIVE_LIST
|
||
|
* \see MCC_BOOKEEPING_STRUCT
|
||
|
*/
|
||
|
struct mcc_endpoint_map_item {
|
||
|
/*! \brief Endpoint tripplet */
|
||
|
MCC_ENDPOINT endpoint;
|
||
|
|
||
|
/*! \brief List of received buffers */
|
||
|
MCC_RECEIVE_LIST list;
|
||
|
#if defined(__IAR_SYSTEMS_ICC__)
|
||
|
};
|
||
|
#else
|
||
|
}__attribute__((packed));
|
||
|
#endif
|
||
|
typedef struct mcc_endpoint_map_item MCC_ENDPOINT_MAP_ITEM;
|
||
|
|
||
|
#if defined(__IAR_SYSTEMS_ICC__)
|
||
|
__packed
|
||
|
#endif
|
||
|
/*!
|
||
|
* \brief MCC info structure.
|
||
|
*
|
||
|
* This is used for additional information about the MCC implementation.
|
||
|
*
|
||
|
* \see MCC_BOOKEEPING_STRUCT
|
||
|
*/
|
||
|
struct mcc_info_struct {
|
||
|
/*! \brief <major>.<minor> - minor is changed whenever patched, major indicates compatibility */
|
||
|
char version_string[sizeof(MCC_VERSION_STRING)];
|
||
|
#if defined(__IAR_SYSTEMS_ICC__)
|
||
|
};
|
||
|
#else
|
||
|
}__attribute__((packed));
|
||
|
#endif
|
||
|
typedef struct mcc_info_struct MCC_INFO_STRUCT;
|
||
|
|
||
|
#if defined(__IAR_SYSTEMS_ICC__)
|
||
|
__packed
|
||
|
#endif
|
||
|
/*!
|
||
|
* \brief Share Memory data - Bookkeeping data and buffers.
|
||
|
*
|
||
|
* This is used for "bookkeeping data" such as endpoint and signal queue head
|
||
|
* and tail pointers and fixed size data buffers. The whole mcc_bookeeping_struct
|
||
|
* as well as each individual structure members has to be defined and stored in the
|
||
|
* memory as packed structure. This way, the same structure member offsets will be ensured
|
||
|
* on all cores/OSes/compilers. Compiler-specific pragmas for data packing have to be applied.
|
||
|
*
|
||
|
* \see MCC_RECEIVE_LIST
|
||
|
* \see MCC_SIGNAL
|
||
|
* \see MCC_ENDPOINT_MAP_ITEM
|
||
|
* \see MCC_RECEIVE_BUFFER
|
||
|
*/
|
||
|
struct mcc_bookeeping_struct {
|
||
|
/*! \brief String that indicates if this structure has been already initialized */
|
||
|
char init_string[sizeof(MCC_INIT_STRING)];
|
||
|
|
||
|
/*! \brief String that indicates the MCC library version */
|
||
|
char version_string[sizeof(MCC_VERSION_STRING)];
|
||
|
|
||
|
/*! \brief List of free buffers */
|
||
|
MCC_RECEIVE_LIST free_list;
|
||
|
|
||
|
/*! \brief Each core has it's own queue of received signals */
|
||
|
MCC_SIGNAL signals_received[MCC_NUM_CORES][MCC_MAX_OUTSTANDING_SIGNALS];
|
||
|
|
||
|
/*! \brief Signal queue head for each core */
|
||
|
unsigned int signal_queue_head[MCC_NUM_CORES];
|
||
|
|
||
|
/*! \brief Signal queue tail for each core */
|
||
|
unsigned int signal_queue_tail[MCC_NUM_CORES];
|
||
|
|
||
|
/*! \brief Endpoint map */
|
||
|
MCC_ENDPOINT_MAP_ITEM endpoint_table[MCC_ATTR_MAX_RECEIVE_ENDPOINTS];
|
||
|
|
||
|
/*! \brief Receive buffers, the number is defined in mcc_config.h (MCC_ATTR_NUM_RECEIVE_BUFFERS) */
|
||
|
MCC_RECEIVE_BUFFER r_buffers[MCC_ATTR_NUM_RECEIVE_BUFFERS];
|
||
|
#if defined(__IAR_SYSTEMS_ICC__)
|
||
|
};
|
||
|
#else
|
||
|
}__attribute__((packed));
|
||
|
#endif
|
||
|
typedef struct mcc_bookeeping_struct MCC_BOOKEEPING_STRUCT;
|
||
|
|
||
|
extern MCC_BOOKEEPING_STRUCT * bookeeping_data;
|
||
|
|
||
|
/*
|
||
|
* Common Macros
|
||
|
*/
|
||
|
#define MCC_RESERVED_PORT_NUMBER (0)
|
||
|
#define MCC_MAX_RECEIVE_ENDPOINTS_COUNT (255)
|
||
|
|
||
|
/*
|
||
|
* Errors
|
||
|
*/
|
||
|
#define MCC_SUCCESS (0) /* function returned successfully */
|
||
|
#define MCC_ERR_TIMEOUT (1) /* blocking function timed out before completing */
|
||
|
#define MCC_ERR_INVAL (2) /* invalid input parameter */
|
||
|
#define MCC_ERR_NOMEM (3) /* out of shared memory for message transmission */
|
||
|
#define MCC_ERR_ENDPOINT (4) /* invalid endpoint / endpoint doesn't exist */
|
||
|
#define MCC_ERR_SEMAPHORE (5) /* semaphore handling error */
|
||
|
#define MCC_ERR_DEV (6) /* Device Open Error */
|
||
|
#define MCC_ERR_INT (7) /* Interrupt Error */
|
||
|
#define MCC_ERR_SQ_FULL (8) /* Signal queue is full */
|
||
|
#define MCC_ERR_SQ_EMPTY (9) /* Signal queue is empty */
|
||
|
#define MCC_ERR_VERSION (10) /* Incorrect MCC version used - compatibility issue */
|
||
|
#define MCC_ERR_OSSYNC (11) /* OS-dependent synchronization module issue */
|
||
|
|
||
|
/*
|
||
|
* OS Selection
|
||
|
*/
|
||
|
#define MCC_LINUX (1) /* Linux OS used */
|
||
|
#define MCC_MQX (2) /* MQX RTOS used */
|
||
|
|
||
|
MCC_RECEIVE_LIST * mcc_get_endpoint_list(MCC_ENDPOINT endpoint);
|
||
|
MCC_RECEIVE_BUFFER * mcc_dequeue_buffer(MCC_RECEIVE_LIST *list);
|
||
|
void mcc_queue_buffer(MCC_RECEIVE_LIST *list, MCC_RECEIVE_BUFFER * r_buffer);
|
||
|
int mcc_remove_endpoint(MCC_ENDPOINT endpoint);
|
||
|
int mcc_register_endpoint(MCC_ENDPOINT endpoint);
|
||
|
int mcc_queue_signal(MCC_CORE core, MCC_SIGNAL signal);
|
||
|
int mcc_dequeue_signal(MCC_CORE core, MCC_SIGNAL *signal);
|
||
|
|
||
|
#define MCC_SIGNAL_QUEUE_FULL(core) (((bookeeping_data->signal_queue_tail[core] + 1) % MCC_MAX_OUTSTANDING_SIGNALS) == bookeeping_data->signal_queue_head[core])
|
||
|
#define MCC_SIGNAL_QUEUE_EMPTY(core) (bookeeping_data->signal_queue_head[core] == bookeeping_data->signal_queue_tail[core])
|
||
|
#define MCC_ENDPOINTS_EQUAL(e1, e2) ((e1.core == e2.core) && (e1.node == e2.node) && (e1.port == e2.port))
|
||
|
|
||
|
#if (MCC_ATTR_MAX_RECEIVE_ENDPOINTS > MCC_MAX_RECEIVE_ENDPOINTS_COUNT)
|
||
|
#error User-defined maximum number of endpoints can not exceed the value of MCC_MAX_RECEIVE_ENDPOINTS_COUNT
|
||
|
#endif
|
||
|
|
||
|
#endif /* __MCC_COMMON__ */
|
||
|
|