summaryrefslogtreecommitdiff
path: root/include/linux/mcc_common.h
blob: b0055b906d00f5b8980232bd5a537ecd9c7fd6b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
/*
 * 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__ */