CANopenNode
CO_driver_target.h
Go to the documentation of this file.
1 
29 #ifndef CO_DRIVER_TARGET_H
30 #define CO_DRIVER_TARGET_H
31 
32 /* This file contains device and application specific definitions.
33  * It is included from CO_driver.h, which contains documentation
34  * for common definitions below. */
35 
36 #include <stddef.h>
37 #include <stdbool.h>
38 #include <stdint.h>
39 #include <endian.h>
40 #ifndef CO_SINGLE_THREAD
41 #include <pthread.h>
42 #endif
43 #include <linux/can.h>
44 #include <net/if.h>
45 #include <sys/epoll.h>
46 
47 #ifdef CO_DRIVER_CUSTOM
48 #include "CO_driver_custom.h"
49 #endif
50 #include "CO_error.h"
51 
52 #ifdef __cplusplus
53 extern "C" {
54 #endif
55 
56 /* TODO some parts are disabled in non-finished pre-release */
57 #define CO_CONFIG_HB_CONS (0)
58 #define CO_CONFIG_TIME (0)
59 #define CO_CONFIG_SYNC (0)
60 #define CO_CONFIG_PDO (0)
61 #define CO_CONFIG_TRACE (0)
62 
63 
64 /* Stack configuration override default values.
65  * For more information see file CO_config.h. */
66 #ifdef CO_SINGLE_THREAD
67 #define CO_CONFIG_FLAG_CALLBACK_PRE_USED 0
68 #else
69 #define CO_CONFIG_FLAG_CALLBACK_PRE_USED CO_CONFIG_FLAG_CALLBACK_PRE
70 #endif
71 
72 #ifndef CO_CONFIG_NMT
73 #define CO_CONFIG_NMT (CO_CONFIG_NMT_CALLBACK_CHANGE | \
74  CO_CONFIG_NMT_MASTER | \
75  CO_CONFIG_FLAG_CALLBACK_PRE_USED | \
76  CO_CONFIG_FLAG_TIMERNEXT)
77 #endif
78 
79 #ifndef CO_CONFIG_HB_CONS
80 #define CO_CONFIG_HB_CONS (CO_CONFIG_HB_CONS_ENABLE | \
81  CO_CONFIG_HB_CONS_CALLBACK_CHANGE | \
82  CO_CONFIG_FLAG_CALLBACK_PRE_USED | \
83  CO_CONFIG_FLAG_TIMERNEXT)
84 #endif
85 
86 #ifndef CO_CONFIG_EM
87 #define CO_CONFIG_EM (CO_CONFIG_EM_PRODUCER | \
88  CO_CONFIG_EM_PROD_CONFIGURABLE | \
89  CO_CONFIG_EM_PROD_INHIBIT | \
90  CO_CONFIG_EM_HISTORY | \
91  CO_CONFIG_EM_STATUS_BITS | \
92  CO_CONFIG_EM_CONSUMER | \
93  CO_CONFIG_FLAG_CALLBACK_PRE_USED | \
94  CO_CONFIG_FLAG_TIMERNEXT)
95 #endif
96 
97 #ifndef CO_CONFIG_SDO_SRV
98 #define CO_CONFIG_SDO_SRV (CO_CONFIG_SDO_SRV_SEGMENTED | \
99  CO_CONFIG_SDO_SRV_BLOCK | \
100  CO_CONFIG_FLAG_CALLBACK_PRE_USED | \
101  CO_CONFIG_FLAG_TIMERNEXT | \
102  CO_CONFIG_FLAG_OD_DYNAMIC)
103 #endif
104 
105 #ifndef CO_CONFIG_SDO_SRV_BUFFER_SIZE
106 #define CO_CONFIG_SDO_SRV_BUFFER_SIZE 900
107 #endif
108 
109 #ifndef CO_CONFIG_SDO_CLI
110 #define CO_CONFIG_SDO_CLI (CO_CONFIG_SDO_CLI_ENABLE | \
111  CO_CONFIG_SDO_CLI_SEGMENTED | \
112  CO_CONFIG_SDO_CLI_BLOCK | \
113  CO_CONFIG_SDO_CLI_LOCAL | \
114  CO_CONFIG_FLAG_CALLBACK_PRE_USED | \
115  CO_CONFIG_FLAG_TIMERNEXT | \
116  CO_CONFIG_FLAG_OD_DYNAMIC)
117 #endif
118 
119 #ifndef CO_CONFIG_TIME
120 #define CO_CONFIG_TIME (CO_CONFIG_TIME_ENABLE | \
121  CO_CONFIG_TIME_PRODUCER | \
122  CO_CONFIG_FLAG_CALLBACK_PRE_USED)
123 #endif
124 
125 #ifndef CO_CONFIG_SYNC
126 #define CO_CONFIG_SYNC (CO_CONFIG_SYNC_ENABLE | \
127  CO_CONFIG_SYNC_PRODUCER | \
128  CO_CONFIG_FLAG_CALLBACK_PRE_USED | \
129  CO_CONFIG_FLAG_TIMERNEXT)
130 #endif
131 
132 #ifndef CO_CONFIG_PDO
133 #define CO_CONFIG_PDO (CO_CONFIG_RPDO_ENABLE | \
134  CO_CONFIG_TPDO_ENABLE | \
135  CO_CONFIG_PDO_SYNC_ENABLE | \
136  CO_CONFIG_RPDO_CALLS_EXTENSION | \
137  CO_CONFIG_TPDO_CALLS_EXTENSION | \
138  CO_CONFIG_FLAG_CALLBACK_PRE_USED | \
139  CO_CONFIG_FLAG_TIMERNEXT)
140 #endif
141 
142 #ifndef CO_CONFIG_LEDS
143 #define CO_CONFIG_LEDS (CO_CONFIG_LEDS_ENABLE | \
144  CO_CONFIG_FLAG_TIMERNEXT)
145 #endif
146 
147 #ifndef CO_CONFIG_LSS
148 #define CO_CONFIG_LSS (CO_CONFIG_LSS_SLAVE | \
149  CO_CONFIG_LSS_SLAVE_FASTSCAN_DIRECT_RESPOND | \
150  CO_CONFIG_LSS_MASTER | \
151  CO_CONFIG_FLAG_CALLBACK_PRE_USED)
152 #endif
153 
154 #ifndef CO_CONFIG_GTW
155 #define CO_CONFIG_GTW (CO_CONFIG_GTW_ASCII | \
156  CO_CONFIG_GTW_ASCII_SDO | \
157  CO_CONFIG_GTW_ASCII_NMT | \
158  CO_CONFIG_GTW_ASCII_LSS | \
159  CO_CONFIG_GTW_ASCII_LOG | \
160  CO_CONFIG_GTW_ASCII_ERROR_DESC | \
161  CO_CONFIG_GTW_ASCII_PRINT_HELP | \
162  CO_CONFIG_GTW_ASCII_PRINT_LEDS)
163 #define CO_CONFIG_GTW_BLOCK_DL_LOOP 3
164 #define CO_CONFIG_GTWA_COMM_BUF_SIZE 2000
165 #define CO_CONFIG_GTWA_LOG_BUF_SIZE 10000
166 #endif
167 
168 #ifndef CO_CONFIG_CRC16
169 #define CO_CONFIG_CRC16 (CO_CONFIG_CRC16_ENABLE)
170 #endif
171 
172 #ifndef CO_CONFIG_FIFO
173 #define CO_CONFIG_FIFO (CO_CONFIG_FIFO_ENABLE | \
174  CO_CONFIG_FIFO_ALT_READ | \
175  CO_CONFIG_FIFO_CRC16_CCITT | \
176  CO_CONFIG_FIFO_ASCII_COMMANDS | \
177  CO_CONFIG_FIFO_ASCII_DATATYPES)
178 #endif
179 
180 #ifndef CO_CONFIG_TRACE
181 #define CO_CONFIG_TRACE (CO_CONFIG_TRACE_ENABLE)
182 #endif
183 
184 
185 /* Print debug info from some internal parts of the stack */
186 #if (CO_CONFIG_DEBUG) & CO_CONFIG_DEBUG_COMMON
187 #include <stdio.h>
188 #include <syslog.h>
189 #define CO_DEBUG_COMMON(msg) log_printf(LOG_DEBUG, DBG_CO_DEBUG, msg);
190 #endif
191 
192 
201 /* Macro for passing additional information about error, see CO_driver.h. */
202 #define CO_errinfo(CANmodule, err) CANmodule->errinfo = err
203 
224 #ifndef CO_DRIVER_MULTI_INTERFACE
225 #define CO_DRIVER_MULTI_INTERFACE 0
226 #endif
227 
245 #ifndef CO_DRIVER_ERROR_REPORTING
246 #define CO_DRIVER_ERROR_REPORTING 1
247 #endif
248 
249 /* skip this section for Doxygen, because it is documented in CO_driver.h */
250 #ifndef CO_DOXYGEN
251 
252 /* Basic definitions */
253 #ifdef __BYTE_ORDER
254 #if __BYTE_ORDER == __LITTLE_ENDIAN
255  #define CO_LITTLE_ENDIAN
256  #define CO_SWAP_16(x) x
257  #define CO_SWAP_32(x) x
258  #define CO_SWAP_64(x) x
259 #else
260  #define CO_BIG_ENDIAN
261  #include <byteswap.h>
262  #define CO_SWAP_16(x) bswap_16(x)
263  #define CO_SWAP_32(x) bswap_32(x)
264  #define CO_SWAP_64(x) bswap_64(x)
265 #endif
266 #endif
267 /* #define CO_USE_LEDS */
268 /* NULL is defined in stddef.h */
269 /* true and false are defined in stdbool.h */
270 /* int8_t to uint64_t are defined in stdint.h */
271 typedef unsigned char bool_t;
272 typedef float float32_t;
273 typedef double float64_t;
274 typedef char char_t;
275 typedef unsigned char oChar_t;
276 typedef unsigned char domain_t;
277 
278 
279 /* CAN receive message structure as aligned in socketCAN. */
280 typedef struct {
281  uint32_t ident;
282  uint8_t DLC;
283  uint8_t padding[3];
284  uint8_t data[8];
285 } CO_CANrxMsg_t;
286 
287 /* Access to received CAN message */
288 static inline uint16_t CO_CANrxMsg_readIdent(void *rxMsg) {
289  CO_CANrxMsg_t *rxMsgCasted = (CO_CANrxMsg_t *)rxMsg;
290  return (uint16_t) (rxMsgCasted->ident & CAN_SFF_MASK);
291 }
292 static inline uint8_t CO_CANrxMsg_readDLC(void *rxMsg) {
293  CO_CANrxMsg_t *rxMsgCasted = (CO_CANrxMsg_t *)rxMsg;
294  return (uint8_t) (rxMsgCasted->DLC);
295 }
296 static inline uint8_t *CO_CANrxMsg_readData(void *rxMsg) {
297  CO_CANrxMsg_t *rxMsgCasted = (CO_CANrxMsg_t *)rxMsg;
298  return (uint8_t *) (rxMsgCasted->data);
299 }
300 
301 
302 /* Received message object */
303 typedef struct {
304  uint32_t ident;
305  uint32_t mask;
306  void *object;
307  void (*CANrx_callback)(void *object, void *message);
308  int can_ifindex; /* CAN Interface index from last message */
309  struct timespec timestamp; /* time of reception of last message */
310 } CO_CANrx_t;
311 
312 /* Transmit message object as aligned in socketCAN. */
313 typedef struct {
314  uint32_t ident;
315  uint8_t DLC;
316  uint8_t padding[3]; /* ensure alignment */
317  uint8_t data[8];
318  volatile bool_t bufferFull; /* not used */
319  volatile bool_t syncFlag; /* info about transmit message */
320  int can_ifindex; /* CAN Interface index to use */
321 } CO_CANtx_t;
322 
323 
324 /* Max COB ID for standard frame format */
325 #define CO_CAN_MSG_SFF_MAX_COB_ID (1 << CAN_SFF_ID_BITS)
326 
327 /* CAN interface object (CANptr), passed to CO_CANinit() */
328 typedef struct {
329  int can_ifindex; /* CAN Interface index */
330  int epoll_fd; /* File descriptor for epoll, which waits for
331  CAN receive event */
332 } CO_CANptrSocketCan_t;
333 
334 /* socketCAN interface object */
335 typedef struct {
336  int can_ifindex; /* CAN Interface index */
337  char ifName[IFNAMSIZ]; /* CAN Interface name */
338  int fd; /* socketCAN file descriptor */
339 #if CO_DRIVER_ERROR_REPORTING > 0 || defined CO_DOXYGEN
340  CO_CANinterfaceErrorhandler_t errorhandler;
341 #endif
342 } CO_CANinterface_t;
343 
344 /* CAN module object */
345 typedef struct {
346  /* List of can interfaces. From CO_CANmodule_init() or one per
347  * CO_CANmodule_addInterface() call */
348  CO_CANinterface_t *CANinterfaces;
349  uint32_t CANinterfaceCount; /* interface count */
350  CO_CANrx_t *rxArray;
351  uint16_t rxSize;
352  struct can_filter *rxFilter;/* socketCAN filter list, one per rx buffer */
353  uint32_t rxDropCount; /* messages dropped on rx socket queue */
354  CO_CANtx_t *txArray;
355  uint16_t txSize;
356  uint16_t CANerrorStatus;
357  int32_t errinfo;
358  volatile bool_t CANnormal;
359  int epoll_fd; /* File descriptor for epoll, which waits for
360  CAN receive event */
361 #if CO_DRIVER_MULTI_INTERFACE > 0 || defined CO_DOXYGEN
362  /* Lookup tables Cob ID to rx/tx array index.
363  * Only feasible for SFF Messages. */
364  uint32_t rxIdentToIndex[CO_CAN_MSG_SFF_MAX_COB_ID];
365  uint32_t txIdentToIndex[CO_CAN_MSG_SFF_MAX_COB_ID];
366 #endif
368 
369 #ifdef CO_SINGLE_THREAD
370 #define CO_LOCK_CAN_SEND()
371 #define CO_UNLOCK_CAN_SEND()
372 #define CO_LOCK_EMCY()
373 #define CO_UNLOCK_EMCY()
374 #define CO_LOCK_OD()
375 #define CO_UNLOCK_OD()
376 #define CO_MemoryBarrier()
377 #else
378 
379 /* (un)lock critical section in CO_CANsend() - unused */
380 #define CO_LOCK_CAN_SEND()
381 #define CO_UNLOCK_CAN_SEND()
382 
383 /* (un)lock critical section in CO_errorReport() or CO_errorReset() */
384 extern pthread_mutex_t CO_EMCY_mutex;
385 static inline int CO_LOCK_EMCY() {
386  return pthread_mutex_lock(&CO_EMCY_mutex);
387 }
388 static inline void CO_UNLOCK_EMCY() {
389  (void)pthread_mutex_unlock(&CO_EMCY_mutex);
390 }
391 
392 /* (un)lock critical section when accessing Object Dictionary */
393 extern pthread_mutex_t CO_OD_mutex;
394 static inline int CO_LOCK_OD() {
395  return pthread_mutex_lock(&CO_OD_mutex);
396 }
397 static inline void CO_UNLOCK_OD() {
398  (void)pthread_mutex_unlock(&CO_OD_mutex);
399 }
400 
401 /* Synchronization between CAN receive and message processing threads. */
402 #define CO_MemoryBarrier() {__sync_synchronize();}
403 #endif /* CO_SINGLE_THREAD */
404 
405 #define CO_FLAG_READ(rxNew) ((rxNew) != NULL)
406 #define CO_FLAG_SET(rxNew) {CO_MemoryBarrier(); rxNew = (void*)1L;}
407 #define CO_FLAG_CLEAR(rxNew) {CO_MemoryBarrier(); rxNew = NULL;}
408 
409 #endif /* #ifndef CO_DOXYGEN */
410 
411 
412 #if CO_DRIVER_MULTI_INTERFACE > 0 || defined CO_DOXYGEN
413 
424  int can_ifindex);
425 
442  uint16_t ident,
443  const void **const CANptrRx,
444  struct timespec *timestamp);
445 
462  uint16_t ident,
463  const void *CANptrTx);
464 #endif /* CO_DRIVER_MULTI_INTERFACE */
465 
466 
492  struct epoll_event *ev,
493  CO_CANrxMsg_t *buffer,
494  int32_t *msgIndex);
495 
498 #ifdef __cplusplus
499 }
500 #endif /* __cplusplus */
501 
502 #endif /* CO_DRIVER_TARGET_H */
uint32_t
unsigned long int uint32_t
UNSIGNED32 in CANopen (0007h), 32-bit unsigned integer.
Definition: CO_driver.h:155
CO_CANtxBuffer_setInterface
CO_ReturnError_t CO_CANtxBuffer_setInterface(CO_CANmodule_t *CANmodule, uint16_t ident, const void *CANptrTx)
Set which interface should be used for message buffer transmission.
CO_CANmodule_addInterface
CO_ReturnError_t CO_CANmodule_addInterface(CO_CANmodule_t *CANmodule, int can_ifindex)
Add socketCAN interface to can driver.
CO_error.h
CANopenNode Linux socketCAN Error handling.
char_t
char char_t
VISIBLE_STRING in CANopen (0009h), string of signed 8-bit values.
Definition: CO_driver.h:163
CO_UNLOCK_EMCY
#define CO_UNLOCK_EMCY()
Unlock critical section in CO_errorReport() or CO_errorReset()
Definition: CO_driver.h:394
uint16_t
unsigned int uint16_t
UNSIGNED16 in CANopen (0006h), 16-bit unsigned integer.
Definition: CO_driver.h:153
CO_LOCK_EMCY
#define CO_LOCK_EMCY()
Lock critical section in CO_errorReport() or CO_errorReset()
Definition: CO_driver.h:392
CO_ReturnError_t
CO_ReturnError_t
Return values of some CANopen functions.
Definition: CO_driver.h:488
CO_CANrxMsg_readDLC
static uint8_t CO_CANrxMsg_readDLC(void *rxMsg)
CANrx_callback() can read Data Length Code from received CAN message.
Definition: CO_driver.h:230
bool_t
unsigned char bool_t
Boolean data type for general use.
Definition: CO_driver.h:141
CANrx_callback
void CANrx_callback(void *object, void *rxMsg)
CAN receive callback function which pre-processes received CAN message.
CO_CANrxMsg_readData
static uint8_t * CO_CANrxMsg_readData(void *rxMsg)
CANrx_callback() can read pointer to data from received CAN message.
Definition: CO_driver.h:242
int32_t
signed long int int32_t
INTEGER32 in CANopen (0004h), 32-bit signed integer.
Definition: CO_driver.h:147
CO_LOCK_OD
#define CO_LOCK_OD()
Lock critical section when accessing Object Dictionary.
Definition: CO_driver.h:396
CO_CANrxMsg_readIdent
static uint16_t CO_CANrxMsg_readIdent(void *rxMsg)
CANrx_callback() can read CAN identifier from received CAN message.
Definition: CO_driver.h:218
CO_CANrxFromEpoll
bool_t CO_CANrxFromEpoll(CO_CANmodule_t *CANmodule, struct epoll_event *ev, CO_CANrxMsg_t *buffer, int32_t *msgIndex)
Receives CAN messages from matching epoll event.
Definition: CO_driver.c:842
float64_t
double float64_t
REAL64 in CANopen (0011h), double precision floating point value, 64-bit.
Definition: CO_driver.h:161
float32_t
float float32_t
REAL32 in CANopen (0008h), single precision floating point value, 32-bit.
Definition: CO_driver.h:159
oChar_t
unsigned char oChar_t
OCTET_STRING in CANopen (000Ah), string of unsigned 8-bit values.
Definition: CO_driver.h:165
CO_CANrxBuffer_getInterface
bool_t CO_CANrxBuffer_getInterface(CO_CANmodule_t *CANmodule, uint16_t ident, const void **const CANptrRx, struct timespec *timestamp)
Check on which interface the last message for one message buffer was received.
CO_UNLOCK_OD
#define CO_UNLOCK_OD()
Unock critical section when accessing Object Dictionary.
Definition: CO_driver.h:398
CO_CANrx_t
Configuration object for CAN received message for specific CANopenNode Object.
Definition: CO_driver.h:257
CO_CANmodule_t
Complete CAN module object.
Definition: CO_driver.h:319
domain_t
unsigned char domain_t
DOMAIN in CANopen (000Fh), used to transfer a large block of data.
Definition: CO_driver.h:167
CO_CANtx_t
Configuration object for CAN transmit message for specific CANopenNode Object.
Definition: CO_driver.h:299
CO_CANinterfaceErrorhandler_t
socketCAN interface error handling
Definition: CO_error.h:113
uint8_t
unsigned char uint8_t
UNSIGNED8 in CANopen (0005h), 8-bit unsigned integer.
Definition: CO_driver.h:151