CO_driver_target.h
Go to the documentation of this file.
#ifndef CO_DRIVER_TARGET_H
#define CO_DRIVER_TARGET_H
/* This file contains device and application specific definitions.
* It is included from CO_driver.h, which contains documentation
* for common definitions below. */
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <endian.h>
#ifndef CO_SINGLE_THREAD
#include <pthread.h>
#endif
#include <linux/can.h>
#include <net/if.h>
#include <sys/epoll.h>
#ifdef CO_DRIVER_CUSTOM
#include "CO_driver_custom.h"
#endif
#include "CO_error.h"
#ifdef __cplusplus
extern "C" {
#endif
/* TODO some parts are disabled in non-finished pre-release */
#define CO_CONFIG_HB_CONS (0)
#define CO_CONFIG_TIME (0)
#define CO_CONFIG_SYNC (0)
#define CO_CONFIG_PDO (0)
#define CO_CONFIG_TRACE (0)
/* Stack configuration override default values.
* For more information see file CO_config.h. */
#ifdef CO_SINGLE_THREAD
#define CO_CONFIG_FLAG_CALLBACK_PRE_USED 0
#else
#define CO_CONFIG_FLAG_CALLBACK_PRE_USED CO_CONFIG_FLAG_CALLBACK_PRE
#endif
#ifndef CO_CONFIG_NMT
#define CO_CONFIG_NMT (CO_CONFIG_NMT_CALLBACK_CHANGE | \
CO_CONFIG_NMT_MASTER | \
CO_CONFIG_FLAG_CALLBACK_PRE_USED | \
CO_CONFIG_FLAG_TIMERNEXT)
#endif
#ifndef CO_CONFIG_HB_CONS
#define CO_CONFIG_HB_CONS (CO_CONFIG_HB_CONS_ENABLE | \
CO_CONFIG_HB_CONS_CALLBACK_CHANGE | \
CO_CONFIG_FLAG_CALLBACK_PRE_USED | \
CO_CONFIG_FLAG_TIMERNEXT)
#endif
#ifndef CO_CONFIG_EM
#define CO_CONFIG_EM (CO_CONFIG_EM_PRODUCER | \
CO_CONFIG_EM_PROD_CONFIGURABLE | \
CO_CONFIG_EM_PROD_INHIBIT | \
CO_CONFIG_EM_HISTORY | \
CO_CONFIG_EM_STATUS_BITS | \
CO_CONFIG_EM_CONSUMER | \
CO_CONFIG_FLAG_CALLBACK_PRE_USED | \
CO_CONFIG_FLAG_TIMERNEXT)
#endif
#ifndef CO_CONFIG_SDO_SRV
#define CO_CONFIG_SDO_SRV (CO_CONFIG_SDO_SRV_SEGMENTED | \
CO_CONFIG_SDO_SRV_BLOCK | \
CO_CONFIG_FLAG_CALLBACK_PRE_USED | \
CO_CONFIG_FLAG_TIMERNEXT | \
CO_CONFIG_FLAG_OD_DYNAMIC)
#endif
#ifndef CO_CONFIG_SDO_SRV_BUFFER_SIZE
#define CO_CONFIG_SDO_SRV_BUFFER_SIZE 900
#endif
#ifndef CO_CONFIG_SDO_CLI
#define CO_CONFIG_SDO_CLI (CO_CONFIG_SDO_CLI_ENABLE | \
CO_CONFIG_SDO_CLI_SEGMENTED | \
CO_CONFIG_SDO_CLI_BLOCK | \
CO_CONFIG_SDO_CLI_LOCAL | \
CO_CONFIG_FLAG_CALLBACK_PRE_USED | \
CO_CONFIG_FLAG_TIMERNEXT | \
CO_CONFIG_FLAG_OD_DYNAMIC)
#endif
#ifndef CO_CONFIG_TIME
#define CO_CONFIG_TIME (CO_CONFIG_TIME_ENABLE | \
CO_CONFIG_TIME_PRODUCER | \
CO_CONFIG_FLAG_CALLBACK_PRE_USED)
#endif
#ifndef CO_CONFIG_SYNC
#define CO_CONFIG_SYNC (CO_CONFIG_SYNC_ENABLE | \
CO_CONFIG_SYNC_PRODUCER | \
CO_CONFIG_FLAG_CALLBACK_PRE_USED | \
CO_CONFIG_FLAG_TIMERNEXT)
#endif
#ifndef CO_CONFIG_PDO
#define CO_CONFIG_PDO (CO_CONFIG_RPDO_ENABLE | \
CO_CONFIG_TPDO_ENABLE | \
CO_CONFIG_PDO_SYNC_ENABLE | \
CO_CONFIG_RPDO_CALLS_EXTENSION | \
CO_CONFIG_TPDO_CALLS_EXTENSION | \
CO_CONFIG_FLAG_CALLBACK_PRE_USED | \
CO_CONFIG_FLAG_TIMERNEXT)
#endif
#ifndef CO_CONFIG_LEDS
#define CO_CONFIG_LEDS (CO_CONFIG_LEDS_ENABLE | \
CO_CONFIG_FLAG_TIMERNEXT)
#endif
#ifndef CO_CONFIG_LSS
#define CO_CONFIG_LSS (CO_CONFIG_LSS_SLAVE | \
CO_CONFIG_LSS_SLAVE_FASTSCAN_DIRECT_RESPOND | \
CO_CONFIG_LSS_MASTER | \
CO_CONFIG_FLAG_CALLBACK_PRE_USED)
#endif
#ifndef CO_CONFIG_GTW
#define CO_CONFIG_GTW (CO_CONFIG_GTW_ASCII | \
CO_CONFIG_GTW_ASCII_SDO | \
CO_CONFIG_GTW_ASCII_NMT | \
CO_CONFIG_GTW_ASCII_LSS | \
CO_CONFIG_GTW_ASCII_LOG | \
CO_CONFIG_GTW_ASCII_ERROR_DESC | \
CO_CONFIG_GTW_ASCII_PRINT_HELP | \
CO_CONFIG_GTW_ASCII_PRINT_LEDS)
#define CO_CONFIG_GTW_BLOCK_DL_LOOP 3
#define CO_CONFIG_GTWA_COMM_BUF_SIZE 2000
#define CO_CONFIG_GTWA_LOG_BUF_SIZE 10000
#endif
#ifndef CO_CONFIG_CRC16
#define CO_CONFIG_CRC16 (CO_CONFIG_CRC16_ENABLE)
#endif
#ifndef CO_CONFIG_FIFO
#define CO_CONFIG_FIFO (CO_CONFIG_FIFO_ENABLE | \
CO_CONFIG_FIFO_ALT_READ | \
CO_CONFIG_FIFO_CRC16_CCITT | \
CO_CONFIG_FIFO_ASCII_COMMANDS | \
CO_CONFIG_FIFO_ASCII_DATATYPES)
#endif
#ifndef CO_CONFIG_TRACE
#define CO_CONFIG_TRACE (CO_CONFIG_TRACE_ENABLE)
#endif
/* Print debug info from some internal parts of the stack */
#if (CO_CONFIG_DEBUG) & CO_CONFIG_DEBUG_COMMON
#include <stdio.h>
#include <syslog.h>
#define CO_DEBUG_COMMON(msg) log_printf(LOG_DEBUG, DBG_CO_DEBUG, msg);
#endif
/* Macro for passing additional information about error, see CO_driver.h. */
#define CO_errinfo(CANmodule, err) CANmodule->errinfo = err
#ifndef CO_DRIVER_MULTI_INTERFACE
#define CO_DRIVER_MULTI_INTERFACE 0
#endif
#ifndef CO_DRIVER_ERROR_REPORTING
#define CO_DRIVER_ERROR_REPORTING 1
#endif
/* skip this section for Doxygen, because it is documented in CO_driver.h */
#ifndef CO_DOXYGEN
/* Basic definitions */
#ifdef __BYTE_ORDER
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define CO_LITTLE_ENDIAN
#define CO_SWAP_16(x) x
#define CO_SWAP_32(x) x
#define CO_SWAP_64(x) x
#else
#define CO_BIG_ENDIAN
#include <byteswap.h>
#define CO_SWAP_16(x) bswap_16(x)
#define CO_SWAP_32(x) bswap_32(x)
#define CO_SWAP_64(x) bswap_64(x)
#endif
#endif
/* #define CO_USE_LEDS */
/* NULL is defined in stddef.h */
/* true and false are defined in stdbool.h */
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t;
typedef float float32_t;
typedef double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* CAN receive message structure as aligned in socketCAN. */
typedef struct {
uint32_t ident;
uint8_t DLC;
uint8_t padding[3];
uint8_t data[8];
} CO_CANrxMsg_t;
/* Access to received CAN message */
static inline uint16_t CO_CANrxMsg_readIdent(void *rxMsg) {
CO_CANrxMsg_t *rxMsgCasted = (CO_CANrxMsg_t *)rxMsg;
return (uint16_t) (rxMsgCasted->ident & CAN_SFF_MASK);
}
static inline uint8_t CO_CANrxMsg_readDLC(void *rxMsg) {
CO_CANrxMsg_t *rxMsgCasted = (CO_CANrxMsg_t *)rxMsg;
return (uint8_t) (rxMsgCasted->DLC);
}
static inline uint8_t *CO_CANrxMsg_readData(void *rxMsg) {
CO_CANrxMsg_t *rxMsgCasted = (CO_CANrxMsg_t *)rxMsg;
return (uint8_t *) (rxMsgCasted->data);
}
/* Received message object */
typedef struct {
uint32_t ident;
uint32_t mask;
void *object;
void (*CANrx_callback)(void *object, void *message);
int can_ifindex; /* CAN Interface index from last message */
struct timespec timestamp; /* time of reception of last message */
} CO_CANrx_t;
/* Transmit message object as aligned in socketCAN. */
typedef struct {
uint32_t ident;
uint8_t DLC;
uint8_t padding[3]; /* ensure alignment */
uint8_t data[8];
volatile bool_t bufferFull; /* not used */
volatile bool_t syncFlag; /* info about transmit message */
int can_ifindex; /* CAN Interface index to use */
} CO_CANtx_t;
/* Max COB ID for standard frame format */
#define CO_CAN_MSG_SFF_MAX_COB_ID (1 << CAN_SFF_ID_BITS)
/* CAN interface object (CANptr), passed to CO_CANinit() */
typedef struct {
int can_ifindex; /* CAN Interface index */
int epoll_fd; /* File descriptor for epoll, which waits for
CAN receive event */
} CO_CANptrSocketCan_t;
/* socketCAN interface object */
typedef struct {
int can_ifindex; /* CAN Interface index */
char ifName[IFNAMSIZ]; /* CAN Interface name */
int fd; /* socketCAN file descriptor */
#if CO_DRIVER_ERROR_REPORTING > 0 || defined CO_DOXYGEN
CO_CANinterfaceErrorhandler_t errorhandler;
#endif
} CO_CANinterface_t;
/* CAN module object */
typedef struct {
/* List of can interfaces. From CO_CANmodule_init() or one per
* CO_CANmodule_addInterface() call */
CO_CANinterface_t *CANinterfaces;
uint32_t CANinterfaceCount; /* interface count */
CO_CANrx_t *rxArray;
uint16_t rxSize;
struct can_filter *rxFilter;/* socketCAN filter list, one per rx buffer */
uint32_t rxDropCount; /* messages dropped on rx socket queue */
CO_CANtx_t *txArray;
uint16_t txSize;
uint16_t CANerrorStatus;
int32_t errinfo;
volatile bool_t CANnormal;
int epoll_fd; /* File descriptor for epoll, which waits for
CAN receive event */
#if CO_DRIVER_MULTI_INTERFACE > 0 || defined CO_DOXYGEN
/* Lookup tables Cob ID to rx/tx array index.
* Only feasible for SFF Messages. */
uint32_t rxIdentToIndex[CO_CAN_MSG_SFF_MAX_COB_ID];
uint32_t txIdentToIndex[CO_CAN_MSG_SFF_MAX_COB_ID];
#endif
} CO_CANmodule_t;
#ifdef CO_SINGLE_THREAD
#define CO_LOCK_CAN_SEND()
#define CO_UNLOCK_CAN_SEND()
#define CO_LOCK_EMCY()
#define CO_UNLOCK_EMCY()
#define CO_LOCK_OD()
#define CO_UNLOCK_OD()
#define CO_MemoryBarrier()
#else
/* (un)lock critical section in CO_CANsend() - unused */
#define CO_LOCK_CAN_SEND()
#define CO_UNLOCK_CAN_SEND()
/* (un)lock critical section in CO_errorReport() or CO_errorReset() */
extern pthread_mutex_t CO_EMCY_mutex;
static inline int CO_LOCK_EMCY() {
return pthread_mutex_lock(&CO_EMCY_mutex);
}
static inline void CO_UNLOCK_EMCY() {
(void)pthread_mutex_unlock(&CO_EMCY_mutex);
}
/* (un)lock critical section when accessing Object Dictionary */
extern pthread_mutex_t CO_OD_mutex;
static inline int CO_LOCK_OD() {
return pthread_mutex_lock(&CO_OD_mutex);
}
static inline void CO_UNLOCK_OD() {
(void)pthread_mutex_unlock(&CO_OD_mutex);
}
/* Synchronization between CAN receive and message processing threads. */
#define CO_MemoryBarrier() {__sync_synchronize();}
#endif /* CO_SINGLE_THREAD */
#define CO_FLAG_READ(rxNew) ((rxNew) != NULL)
#define CO_FLAG_SET(rxNew) {CO_MemoryBarrier(); rxNew = (void*)1L;}
#define CO_FLAG_CLEAR(rxNew) {CO_MemoryBarrier(); rxNew = NULL;}
#endif /* #ifndef CO_DOXYGEN */
#if CO_DRIVER_MULTI_INTERFACE > 0 || defined CO_DOXYGEN
CO_ReturnError_t CO_CANmodule_addInterface(CO_CANmodule_t *CANmodule,
int can_ifindex);
bool_t CO_CANrxBuffer_getInterface(CO_CANmodule_t *CANmodule,
uint16_t ident,
const void **const CANptrRx,
struct timespec *timestamp);
CO_ReturnError_t CO_CANtxBuffer_setInterface(CO_CANmodule_t *CANmodule,
uint16_t ident,
const void *CANptrTx);
#endif /* CO_DRIVER_MULTI_INTERFACE */
bool_t CO_CANrxFromEpoll(CO_CANmodule_t *CANmodule,
struct epoll_event *ev,
CO_CANrxMsg_t *buffer,
int32_t *msgIndex);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#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