--- /dev/null
+CANopenNode/.clang-format
\ No newline at end of file
#endif
/**
- * @defgroup CO_applicationLinux Application interface to CANopenNode
- * Application interface, similar to Arduino, extended to CANopen and
- * additional, realtime thread.
+ * @defgroup CO_applicationLinux Application interface to CANopenNode Application interface, similar to Arduino,
+ * extended to CANopen and additional, realtime thread.
*
* @ingroup CO_socketCAN
* @{
*/
/**
- * Function is called once on the program startup, after Object dictionary
- * initialization and before CANopen initialization.
+ * Function is called once on the program startup, after Object dictionary initialization and before CANopen
+ * initialization.
*
* @param [in,out] bitRate Stored CAN bit rate, can be overridden.
* @param [in,out] nodeId Stored CANopen NodeId, can be overridden.
*
* @return @ref CO_ReturnError_t CO_ERROR_NO in case of success.
*/
-CO_ReturnError_t app_programStart(uint16_t *bitRate,
- uint8_t *nodeId,
- uint32_t *errInfo);
-
+CO_ReturnError_t app_programStart(uint16_t* bitRate, uint8_t* nodeId, uint32_t* errInfo);
/**
* Function is called after CANopen communication reset.
*
* @param co CANopen object.
*/
-void app_communicationReset(CO_t *co);
-
+void app_communicationReset(CO_t* co);
/**
* Function is called just before program ends.
*/
void app_programEnd();
-
/**
* Function is called cyclically from main().
*
* Place for the slower code (all must be non-blocking).
*
* @warning
- * Mind race conditions between this functions and app_programRt(), which
- * run from the realtime thread. If accessing Object dictionary variable which
- * is also mappable to PDO, it is necessary to use CO_LOCK_OD() and
- * CO_UNLOCK_OD() macros from @ref CO_critical_sections.
+ * Mind race conditions between this functions and app_programRt(), which run from the realtime thread. If accessing
+ * Object dictionary variable which is also mappable to PDO, it is necessary to use CO_LOCK_OD() and CO_UNLOCK_OD()
+ * macros from @ref CO_critical_sections.
*
* @param co CANopen object.
* @param timer1usDiff Time difference since last call in microseconds
*/
-void app_programAsync(CO_t *co, uint32_t timer1usDiff);
-
+void app_programAsync(CO_t* co, uint32_t timer1usDiff);
/**
* Function is called cyclically from realtime thread at constant intervals.
*
- * Code inside this function must be executed fast. Take care on race conditions
- * with app_programAsync.
+ * Code inside this function must be executed fast. Take care on race conditions with app_programAsync.
*
* @param co CANopen object.
* @param timer1usDiff Time difference since last call in microseconds
*/
-void app_programRt(CO_t *co, uint32_t timer1usDiff);
+void app_programRt(CO_t* co, uint32_t timer1usDiff);
/** @} */ /* CO_applicationLinux */
* See the License for the specific language governing permissions and limitations under the License.
*/
-
#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. */
+/* 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>
extern "C" {
#endif
-
-/* Stack configuration override default values.
- * For more information see file CO_config.h. */
+/* Stack configuration override default values. For more information see file CO_config.h. */
#ifdef CO_SINGLE_THREAD
#define CO_CONFIG_GLOBAL_FLAG_CALLBACK_PRE 0
#else
#define CO_CONFIG_GLOBAL_FLAG_TIMERNEXT CO_CONFIG_FLAG_TIMERNEXT
#ifndef CO_CONFIG_NMT
-#define CO_CONFIG_NMT (CO_CONFIG_NMT_CALLBACK_CHANGE | \
- CO_CONFIG_NMT_MASTER | \
- CO_CONFIG_GLOBAL_FLAG_CALLBACK_PRE | \
- CO_CONFIG_GLOBAL_FLAG_TIMERNEXT)
+#define CO_CONFIG_NMT \
+ (CO_CONFIG_NMT_CALLBACK_CHANGE | CO_CONFIG_NMT_MASTER | CO_CONFIG_GLOBAL_FLAG_CALLBACK_PRE \
+ | CO_CONFIG_GLOBAL_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_GLOBAL_FLAG_CALLBACK_PRE | \
- CO_CONFIG_GLOBAL_FLAG_TIMERNEXT | \
- CO_CONFIG_GLOBAL_FLAG_OD_DYNAMIC)
+#define CO_CONFIG_HB_CONS \
+ (CO_CONFIG_HB_CONS_ENABLE | CO_CONFIG_HB_CONS_CALLBACK_CHANGE | CO_CONFIG_GLOBAL_FLAG_CALLBACK_PRE \
+ | CO_CONFIG_GLOBAL_FLAG_TIMERNEXT | CO_CONFIG_GLOBAL_FLAG_OD_DYNAMIC)
#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_GLOBAL_FLAG_CALLBACK_PRE | \
- CO_CONFIG_GLOBAL_FLAG_TIMERNEXT)
+#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_GLOBAL_FLAG_CALLBACK_PRE \
+ | CO_CONFIG_GLOBAL_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_GLOBAL_FLAG_CALLBACK_PRE | \
- CO_CONFIG_GLOBAL_FLAG_TIMERNEXT | \
- CO_CONFIG_GLOBAL_FLAG_OD_DYNAMIC)
+#define CO_CONFIG_SDO_SRV \
+ (CO_CONFIG_SDO_SRV_SEGMENTED | CO_CONFIG_SDO_SRV_BLOCK | CO_CONFIG_GLOBAL_FLAG_CALLBACK_PRE \
+ | CO_CONFIG_GLOBAL_FLAG_TIMERNEXT | CO_CONFIG_GLOBAL_FLAG_OD_DYNAMIC)
#endif
#ifndef CO_CONFIG_SDO_SRV_BUFFER_SIZE
#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_GLOBAL_FLAG_CALLBACK_PRE | \
- CO_CONFIG_GLOBAL_FLAG_TIMERNEXT | \
- CO_CONFIG_GLOBAL_FLAG_OD_DYNAMIC)
+#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_GLOBAL_FLAG_CALLBACK_PRE | CO_CONFIG_GLOBAL_FLAG_TIMERNEXT | CO_CONFIG_GLOBAL_FLAG_OD_DYNAMIC)
#endif
#ifndef CO_CONFIG_TIME
-#define CO_CONFIG_TIME (CO_CONFIG_TIME_ENABLE | \
- CO_CONFIG_TIME_PRODUCER | \
- CO_CONFIG_GLOBAL_FLAG_CALLBACK_PRE | \
- CO_CONFIG_GLOBAL_FLAG_OD_DYNAMIC)
+#define CO_CONFIG_TIME \
+ (CO_CONFIG_TIME_ENABLE | CO_CONFIG_TIME_PRODUCER | CO_CONFIG_GLOBAL_FLAG_CALLBACK_PRE \
+ | CO_CONFIG_GLOBAL_FLAG_OD_DYNAMIC)
#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_GLOBAL_FLAG_CALLBACK_PRE)
+#define CO_CONFIG_LSS \
+ (CO_CONFIG_LSS_SLAVE | CO_CONFIG_LSS_SLAVE_FASTSCAN_DIRECT_RESPOND | CO_CONFIG_LSS_MASTER \
+ | CO_CONFIG_GLOBAL_FLAG_CALLBACK_PRE)
#endif
-#define CO_CONFIG_GFC (CO_CONFIG_GFC_ENABLE | \
- CO_CONFIG_GFC_CONSUMER | \
- CO_CONFIG_GFC_PRODUCER)
+#define CO_CONFIG_GFC (CO_CONFIG_GFC_ENABLE | CO_CONFIG_GFC_CONSUMER | CO_CONFIG_GFC_PRODUCER)
-#define CO_CONFIG_SRDO (CO_CONFIG_SRDO_ENABLE | \
- CO_CONFIG_SRDO_CHECK_TX | \
- CO_CONFIG_GLOBAL_FLAG_CALLBACK_PRE | \
- CO_CONFIG_GLOBAL_FLAG_TIMERNEXT)
+#define CO_CONFIG_SRDO \
+ (CO_CONFIG_SRDO_ENABLE | CO_CONFIG_SRDO_CHECK_TX | CO_CONFIG_GLOBAL_FLAG_CALLBACK_PRE \
+ | CO_CONFIG_GLOBAL_FLAG_TIMERNEXT)
#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_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
+#define CO_CONFIG_GTWA_LOG_BUF_SIZE 10000
#endif
#ifndef CO_CONFIG_CRC16
#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)
+#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
-
/* Print debug info from some internal parts of the stack */
#if (CO_CONFIG_DEBUG) & CO_CONFIG_DEBUG_COMMON
#include <stdio.h>
#define CO_DEBUG_COMMON(msg) log_printf(LOG_DEBUG, DBG_CO_DEBUG, msg);
#endif
-
/**
* @defgroup CO_socketCAN_driver_target CO_driver_target.h
* Linux socketCAN specific @ref CO_driver definitions for CANopenNode.
/**
* Multi interface support
*
- * Enable this to use interface combining at driver level. This
- * adds functions to broadcast/selective transmit messages on the
- * given interfaces as well as combining all received message into
- * one queue.
+ * Enable this to use interface combining at driver level. This adds functions to broadcast/selective transmit messages
+ * on the given interfaces as well as combining all received message into one queue.
*
- * If CO_DRIVER_MULTI_INTERFACE is set to 0, then CO_CANmodule_init()
- * adds single socketCAN interface specified by CANptr argument. In case of
- * failure, CO_CANmodule_init() returns CO_ERROR_SYSCALL.
+ * If CO_DRIVER_MULTI_INTERFACE is set to 0, then CO_CANmodule_init() adds single socketCAN interface specified by
+ * CANptr argument. In case of failure, CO_CANmodule_init() returns CO_ERROR_SYSCALL.
*
- * If CO_DRIVER_MULTI_INTERFACE is set to 1, then CO_CANmodule_init()
- * ignores CANptr argument. Interfaces must be added by
- * CO_CANmodule_addInterface() function after CO_CANmodule_init().
+ * If CO_DRIVER_MULTI_INTERFACE is set to 1, then CO_CANmodule_init() ignores CANptr argument. Interfaces must be added
+ * by CO_CANmodule_addInterface() function after CO_CANmodule_init().
*
* Macro is set to 0 (disabled) by default. It can be overridden.
*
/**
* CAN bus error reporting
*
- * CO_DRIVER_ERROR_REPORTING enabled adds support for socketCAN error detection
- * and handling functions inside the driver. This is needed when you have
- * CANopen with "0" connected nodes as a use case, as this is normally
- * forbidden in CAN.
+ * CO_DRIVER_ERROR_REPORTING enabled adds support for socketCAN error detection and handling functions inside the
+ * driver. This is needed when you have CANopen with "0" connected nodes as a use case, as this is normally forbidden
+ * in CAN.
*
* Macro is set to 1 (enabled) by default. It can be overridden.
*
* you need to enable error reporting in your kernel driver using:
* @code{.sh}
- * ip link set canX type can berr-reporting on
+ip link set canX type can berr-reporting on
* @endcode
* Of course, the kernel driver for your hardware needs this functionality to be
* implemented...
/* 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
+#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)
+#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
/* 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 uint_fast8_t bool_t;
-typedef float float32_t;
-typedef double float64_t;
-
+typedef uint_fast8_t bool_t;
+typedef float float32_t;
+typedef double float64_t;
/* CAN receive message structure as aligned in socketCAN. */
typedef struct {
} 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 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);
+
+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);
+ 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 */
+ 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 padding[3]; /* ensure alignment */
uint8_t data[8];
volatile bool_t bufferFull;
- volatile bool_t syncFlag; /* info about transmit message */
- int can_ifindex; /* CAN Interface index to use */
+ 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 */
+ 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 */
+ 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
/* CAN module object */
typedef struct {
- /* List of can interfaces. From CO_CANmodule_init() or one per
- * CO_CANmodule_addInterface() call */
- CO_CANinterface_t *CANinterfaces;
+ /* 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;
+ 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;
+ 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;
volatile bool_t CANnormal;
volatile uint16_t CANtxCount;
- int epoll_fd; /* File descriptor for epoll, which waits for
- CAN receive event */
+ 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. */
+ /* 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;
-
/* Data storage: Maximum file name length including path */
#ifndef CO_STORAGE_PATH_MAX
#define CO_STORAGE_PATH_MAX 255
/* Data storage object for one entry */
typedef struct {
- void *addr;
+ void* addr;
size_t len;
uint8_t subIndexOD;
uint8_t attr;
- /* Name of the file, where data block is stored */
- char filename[CO_STORAGE_PATH_MAX];
- /* CRC checksum of the data stored previously, for auto storage */
- uint16_t crc;
- /* Pointer to opened file, for auto storage */
- FILE *fp;
+ char filename[CO_STORAGE_PATH_MAX]; /* Name of the file, where data block is stored */
+ uint16_t crc; /* CRC checksum of the data stored previously, for auto storage */
+ FILE* fp; /* Pointer to opened file, for auto storage */
} CO_storage_entry_t;
-
#ifdef CO_SINGLE_THREAD
-#define CO_LOCK_CAN_SEND(CAN_MODULE) {(void) CAN_MODULE;}
-#define CO_UNLOCK_CAN_SEND(CAN_MODULE) {(void) CAN_MODULE;}
-#define CO_LOCK_EMCY(CAN_MODULE) {(void) CAN_MODULE;}
-#define CO_UNLOCK_EMCY(CAN_MODULE) {(void) CAN_MODULE;}
-#define CO_LOCK_OD(CAN_MODULE) {(void) CAN_MODULE;}
-#define CO_UNLOCK_OD(CAN_MODULE) {(void) CAN_MODULE;}
+#define CO_LOCK_CAN_SEND(CAN_MODULE) \
+ { (void)CAN_MODULE; }
+#define CO_UNLOCK_CAN_SEND(CAN_MODULE) \
+ { (void)CAN_MODULE; }
+#define CO_LOCK_EMCY(CAN_MODULE) \
+ { (void)CAN_MODULE; }
+#define CO_UNLOCK_EMCY(CAN_MODULE) \
+ { (void)CAN_MODULE; }
+#define CO_LOCK_OD(CAN_MODULE) \
+ { (void)CAN_MODULE; }
+#define CO_UNLOCK_OD(CAN_MODULE) \
+ { (void)CAN_MODULE; }
#define CO_MemoryBarrier()
#else
/* (un)lock critical section in CO_errorReport() or CO_errorReset() */
extern pthread_mutex_t CO_EMCY_mutex;
-static inline int CO_LOCK_EMCY(CO_CANmodule_t *CANmodule) {
+
+static inline int
+CO_LOCK_EMCY(CO_CANmodule_t* CANmodule) {
(void)CANmodule;
return pthread_mutex_lock(&CO_EMCY_mutex);
}
-static inline void CO_UNLOCK_EMCY(CO_CANmodule_t *CANmodule) {
+
+static inline void
+CO_UNLOCK_EMCY(CO_CANmodule_t* CANmodule) {
(void)CANmodule;
(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(CO_CANmodule_t *CANmodule) {
+
+static inline int
+CO_LOCK_OD(CO_CANmodule_t* CANmodule) {
(void)CANmodule;
return pthread_mutex_lock(&CO_OD_mutex);
}
-static inline void CO_UNLOCK_OD(CO_CANmodule_t *CANmodule) {
+
+static inline void
+CO_UNLOCK_OD(CO_CANmodule_t* CANmodule) {
(void)CANmodule;
(void)pthread_mutex_unlock(&CO_OD_mutex);
}
/* Synchronization between CAN receive and message processing threads. */
-#define CO_MemoryBarrier() {__sync_synchronize();}
+#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;}
+#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
/**
* Add socketCAN interface to can driver
*
* @param CANmodule This object will be initialized.
* @param can_ifindex CAN Interface index
- * @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT,
- * CO_ERROR_SYSCALL or CO_ERROR_INVALID_STATE.
+ * @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT, CO_ERROR_SYSCALL or CO_ERROR_INVALID_STATE.
*/
-CO_ReturnError_t CO_CANmodule_addInterface(CO_CANmodule_t *CANmodule,
- int can_ifindex);
+CO_ReturnError_t CO_CANmodule_addInterface(CO_CANmodule_t* CANmodule, int can_ifindex);
/**
* Check on which interface the last message for one message buffer was received
*
- * It is in the responsibility of the user to check that this information is
- * useful as some messages can be received at any time on any bus.
+ * It is in the responsibility of the user to check that this information is useful as some messages can be received at
+ * any time on any bus.
*
* @param CANmodule This object.
* @param ident 11-bit standard CAN Identifier.
* @param [out] CANptrRx message was received on this interface
* @param [out] timestamp message was received at this time (system clock)
*
- * @retval false message has never been received, therefore no base address
- * and timestamp are available
+ * @retval false message has never been received, therefore no base address and timestamp are available
* @retval true base address and timestamp are valid
*/
-bool_t CO_CANrxBuffer_getInterface(CO_CANmodule_t *CANmodule,
- uint16_t ident,
- const void **const CANptrRx,
- struct timespec *timestamp);
+bool_t CO_CANrxBuffer_getInterface(CO_CANmodule_t* CANmodule, uint16_t ident, const void** const CANptrRx,
+ struct timespec* timestamp);
/**
* Set which interface should be used for message buffer transmission
*
- * It is in the responsibility of the user to ensure that the correct interface
- * is used. Some messages need to be transmitted on all interfaces.
+ * It is in the responsibility of the user to ensure that the correct interface is used. Some messages need to be
+ * transmitted on all interfaces.
*
- * If given interface is unknown or NULL is used, a message is transmitted on
- * all available interfaces.
+ * If given interface is unknown or NULL is used, a message is transmitted on all available interfaces.
*
* @param CANmodule This object.
* @param ident 11-bit standard CAN Identifier.
*
* @return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT.
*/
-CO_ReturnError_t CO_CANtxBuffer_setInterface(CO_CANmodule_t *CANmodule,
- uint16_t ident,
- const void *CANptrTx);
+CO_ReturnError_t CO_CANtxBuffer_setInterface(CO_CANmodule_t* CANmodule, uint16_t ident, const void* CANptrTx);
#endif /* CO_DRIVER_MULTI_INTERFACE */
-
/**
* Receives CAN messages from matching epoll event
*
- * This function verifies, if epoll event matches event from any CANinterface.
- * In case of match, message is read from CAN and pre-processed for CANopenNode
- * objects. CAN error frames are also processed.
+ * This function verifies, if epoll event matches event from any CANinterface. In case of match, message is read from
+ * CAN and pre-processed for CANopenNode objects. CAN error frames are also processed.
*
- * In case of CAN message function searches _rxArray_ from CO_CANmodule_t and
- * if matched it calls the corresponding CANrx_callback, optionally copies
- * received CAN message to _buffer_ and returns index of matched _rxArray_.
+ * In case of CAN message function searches _rxArray_ from CO_CANmodule_t and if matched it calls the corresponding
+ * CANrx_callback, optionally copies received CAN message to _buffer_ and returns index of matched _rxArray_.
*
* This function can be used in two ways, which can be combined:
- * - automatic mode: If CANrx_callback is specified for matched _rxArray_, then
- * calls its callback.
+ * - automatic mode: If CANrx_callback is specified for matched _rxArray_, then calls its callback.
* - manual mode: evaluate message filters, return received message
*
* @param CANmodule This object.
* @param ev Epoll event, which vill be verified for matches.
* @param [out] buffer Storage for received message or _NULL_ if not used.
- * @param [out] msgIndex Index of received message in array from CO_CANmodule_t
- * _rxArray_, copy of CAN message is available in _buffer_.
+ * @param [out] msgIndex Index of received message in array from CO_CANmodule_t _rxArray_, copy of CAN message is
+ * available in _buffer_.
*
* @return True, if epoll event matches any CAN interface.
*/
-bool_t CO_CANrxFromEpoll(CO_CANmodule_t *CANmodule,
- struct epoll_event *ev,
- CO_CANrxMsg_t *buffer,
- int32_t *msgIndex);
+bool_t CO_CANrxFromEpoll(CO_CANmodule_t* CANmodule, struct epoll_event* ev, CO_CANrxMsg_t* buffer, int32_t* msgIndex);
/** @} */
* Linux specific interface to CANopenNode.
*
* @{
- * Linux includes CAN interface inside its kernel, so called SocketCAN. It
- * operates as a network device. For more information on Linux SocketCAN see
- * https://www.kernel.org/doc/html/latest/networking/can.html
+ * Linux includes CAN interface inside its kernel, so called SocketCAN. It operates as a network device. For more
+ * information on Linux SocketCAN see https://www.kernel.org/doc/html/latest/networking/can.html
*
- * Linux specific files for interfacing with Linux SocketCAN are located inside
- * "CANopenNode/socketCAN" directory.
+ * Linux specific files for interfacing with Linux SocketCAN are located inside "CANopenNode/socketCAN" directory.
*
- * CANopenNode runs as a set of non-blocking functions. It can run in single or
- * multiple threads. Best approach for RT IO device can be with two threads:
- * - timer based real-time thread for CAN receive, SYNC and PDO, see
- * @ref CO_epoll_processRT()
+ * CANopenNode runs as a set of non-blocking functions. It can run in single or multiple threads. Best approach for RT
+ * IO device can be with two threads:
+ * - timer based real-time thread for CAN receive, SYNC and PDO, see @ref CO_epoll_processRT()
* - mainline thread for other processing, see @ref CO_epoll_processMain()
*
- * Main references for Linux functions used here are Linux man pages and the
- * book: The Linux Programming Interface by Michael Kerrisk.
+ * Main references for Linux functions used here are Linux man pages and the book: The Linux Programming Interface by
+ * Michael Kerrisk.
* @}
*/
*
* @ingroup CO_socketCAN
* @{
- * The Linux epoll API performs a monitoring multiple file descriptors to see
- * if I/O is possible on any of them.
+ * The Linux epoll API performs a monitoring multiple file descriptors to see if I/O is possible on any of them.
*
- * CANopenNode uses epoll interface to provide an event based mechanism. Epoll
- * waits for multiple different events, such as: interval timer event,
- * notification event, CAN receive event or socket based event for gateway.
- * CANopenNode non-blocking functions are processed after each event.
+ * CANopenNode uses epoll interface to provide an event based mechanism. Epoll waits for multiple different events, such
+ * as: interval timer event, notification event, CAN receive event or socket based event for gateway. CANopenNode
+ * non-blocking functions are processed after each event.
*
- * CANopenNode itself offers functionality for calculation of time, when next
- * interval timer event should trigger the processing. It can also trigger
- * notification events in case of multi-thread operation.
+ * CANopenNode itself offers functionality for calculation of time, when next interval timer event should trigger the
+ * processing. It can also trigger notification events in case of multi-thread operation.
*/
/**
* Object for epoll, timer and event API.
*/
typedef struct {
- /** Epoll file descriptor */
- int epoll_fd;
- /** Notification event file descriptor */
- int event_fd;
- /** Interval timer file descriptor */
- int timer_fd;
- /** Interval of the timer in microseconds, from @ref CO_epoll_create() */
- uint32_t timerInterval_us;
- /** Time difference since last @ref CO_epoll_wait() execution in
- * microseconds */
- uint32_t timeDifference_us;
- /** Timer value in microseconds, which can be changed by application and can
- * shorten time of next @ref CO_epoll_wait() execution */
- uint32_t timerNext_us;
- /** True,if timer event is inside @ref CO_epoll_wait() */
- bool_t timerEvent;
- /** time value from the last process call in microseconds */
- uint64_t previousTime_us;
- /** Structure for timerfd */
- struct itimerspec tm;
- /** Structure for epoll_wait */
- struct epoll_event ev;
- /** true, if new epoll event is necessary to process */
- bool_t epoll_new;
+ int epoll_fd; /**< Epoll file descriptor */
+ int event_fd; /**< Notification event file descriptor */
+ int timer_fd; /**< Interval timer file descriptor */
+ uint32_t timerInterval_us; /**< Interval of the timer in microseconds, from @ref CO_epoll_create() */
+ uint32_t timeDifference_us; /**< Time difference since last @ref CO_epoll_wait() execution in microseconds */
+ uint32_t timerNext_us; /**< Timer value in microseconds, which can be changed by application and can shorten
+ time of next @ref CO_epoll_wait() execution */
+ bool_t timerEvent; /**< True,if timer event is inside @ref CO_epoll_wait() */
+ uint64_t previousTime_us; /**< time value from the last process call in microseconds */
+ struct itimerspec tm; /**< Structure for timerfd */
+ struct epoll_event ev; /**< Structure for epoll_wait */
+ bool_t epoll_new; /**< true, if new epoll event is necessary to process */
} CO_epoll_t;
/**
* Create Linux epoll, timerfd and eventfd
*
- * Create and configure multiple Linux notification facilities, which trigger
- * execution of the task. Epoll blocks and monitors multiple file descriptors,
- * timerfd triggers in constant timer intervals and eventfd triggers on external
+ * Create and configure multiple Linux notification facilities, which trigger execution of the task. Epoll blocks and
+ * monitors multiple file descriptors, timerfd triggers in constant timer intervals and eventfd triggers on external
* signal.
*
* @param ep This object
*
* @return @ref CO_ReturnError_t CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT or CO_ERROR_SYSCALL.
*/
-CO_ReturnError_t CO_epoll_create(CO_epoll_t *ep, uint32_t timerInterval_us);
+CO_ReturnError_t CO_epoll_create(CO_epoll_t* ep, uint32_t timerInterval_us);
/**
* Close epoll, timerfd and eventfd
*
* @param ep This object
*/
-void CO_epoll_close(CO_epoll_t *ep);
+void CO_epoll_close(CO_epoll_t* ep);
/**
* Wait for an epoll event
*
- * This function blocks until event registered on epoll: timerfd, eventfd, or
- * application specified event. Function also calculates timeDifference_us since
- * last call and prepares timerNext_us.
+ * This function blocks until event registered on epoll: timerfd, eventfd, or application specified event. Function also
+ * calculates timeDifference_us since last call and prepares timerNext_us.
*
* @param ep This object
*/
-void CO_epoll_wait(CO_epoll_t *ep);
+void CO_epoll_wait(CO_epoll_t* ep);
/**
* Closing function for an epoll event
*
- * This function must be called after @ref CO_epoll_wait(). Between them
- * should be application specified processing functions, which can check for
- * own events and do own processing. Application may also lower timerNext_us
- * variable. If lowered, then interval timer will be reconfigured and
- * @ref CO_epoll_wait() will be triggered earlier.
+ * This function must be called after @ref CO_epoll_wait(). Between them should be application specified processing
+ * functions, which can check for own events and do own processing. Application may also lower timerNext_us variable. If
+ * lowered, then interval timer will be reconfigured and @ref CO_epoll_wait() will be triggered earlier.
*
* @param ep This object
*/
-void CO_epoll_processLast(CO_epoll_t *ep);
+void CO_epoll_processLast(CO_epoll_t* ep);
/**
* Initialization of functions in CANopen reset-communication section
* @param ep This object
* @param co CANopen object
*/
-void CO_epoll_initCANopenMain(CO_epoll_t *ep, CO_t *co);
+void CO_epoll_initCANopenMain(CO_epoll_t* ep, CO_t* co);
/**
* Process CANopen mainline functions
*
- * This function calls @ref CO_process(). It is non-blocking and should execute
- * cyclically. It should be between @ref CO_epoll_wait() and
- * @ref CO_epoll_processLast() functions.
+ * This function calls @ref CO_process(). It is non-blocking and should execute cyclically. It should be between @ref
+ * CO_epoll_wait() and @ref CO_epoll_processLast() functions.
*
* @param ep This object
* @param co CANopen object
* @param enableGateway If true, gateway to external world will be enabled.
* @param [out] reset Return from @ref CO_process().
*/
-void CO_epoll_processMain(CO_epoll_t *ep,
- CO_t *co,
- bool_t enableGateway,
- CO_NMT_reset_cmd_t *reset);
-
+void CO_epoll_processMain(CO_epoll_t* ep, CO_t* co, bool_t enableGateway, CO_NMT_reset_cmd_t* reset);
/**
* Process CAN receive and realtime functions
*
- * This function checks epoll for CAN receive event and processes CANopen
- * realtime functions: @ref CO_process_SYNC(), @ref CO_process_RPDO() and
- * @ref CO_process_TPDO(). It is non-blocking and should execute cyclically.
- * It should be between @ref CO_epoll_wait() and @ref CO_epoll_processLast()
- * functions.
+ * This function checks epoll for CAN receive event and processes CANopen realtime functions: @ref CO_process_SYNC(),
+ * @ref CO_process_RPDO() and @ref CO_process_TPDO(). It is non-blocking and should execute cyclically. It should be
+ * between @ref CO_epoll_wait() and @ref CO_epoll_processLast() functions.
*
* Function can be used in the mainline thread or in own realtime thread.
*
- * Processing of CANopen realtime functions is protected with @ref CO_LOCK_OD.
- * Also Node-Id must be configured and CANmodule must be in CANnormal for
- * processing.
+ * Processing of CANopen realtime functions is protected with @ref CO_LOCK_OD. Also Node-Id must be configured and
+ * CANmodule must be in CANnormal for processing.
*
* @param ep Pointer to @ref CO_epoll_t object.
* @param co CANopen object
- * @param realtime Set to true, if function is called from the own realtime
- * thread, and is executed at short constant interval.
+ * @param realtime Set to true, if function is called from the own realtime thread, and is executed at short constant
+ * interval.
*/
-void CO_epoll_processRT(CO_epoll_t *ep,
- CO_t *co,
- bool_t realtime);
-
+void CO_epoll_processRT(CO_epoll_t* ep, CO_t* co, bool_t realtime);
-#if ((CO_CONFIG_GTW) & CO_CONFIG_GTW_ASCII) || defined CO_DOXYGEN
+#if ((CO_CONFIG_GTW)&CO_CONFIG_GTW_ASCII) || defined CO_DOXYGEN
/**
* Command interface type for gateway-ascii
*/
* Object for gateway
*/
typedef struct {
- /** Epoll file descriptor, from @ref CO_epoll_createGtw() */
- int epoll_fd;
- /** Command interface type or tcp port number, see
- * @ref CO_commandInterface_t */
- int32_t commandInterface;
- /** Socket timeout in microseconds */
- uint32_t socketTimeout_us;
- /** Socket timeout timer in microseconds */
- uint32_t socketTimeoutTmr_us;
- /** Path in case of local socket */
- char *localSocketPath;
- /** Gateway socket file descriptor */
- int gtwa_fdSocket;
- /** Gateway io stream file descriptor */
- int gtwa_fd;
- /** Indication of fresh command */
- bool_t freshCommand;
+ int epoll_fd; /**< Epoll file descriptor, from @ref CO_epoll_createGtw() */
+ int32_t commandInterface; /**< Command interface type or tcp port number, see @ref CO_commandInterface_t */
+ uint32_t socketTimeout_us; /**< Socket timeout in microseconds */
+ uint32_t socketTimeoutTmr_us; /**< Socket timeout timer in microseconds */
+ char* localSocketPath; /**< Path in case of local socket */
+ int gtwa_fdSocket; /**< Gateway socket file descriptor */
+ int gtwa_fd; /**< Gateway io stream file descriptor */
+ bool_t freshCommand; /**< Indication of fresh command */
} CO_epoll_gtw_t;
/**
* Create socket for gateway-ascii command interface and add it to epoll
*
- * Depending on arguments function configures stdio interface or local socket
- * or IP socket.
+ * Depending on arguments function configures stdio interface or local socket or IP socket.
*
* @param epGtw This object
* @param epoll_fd Already configured epoll file descriptor
*
* @return @ref CO_ReturnError_t CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT or CO_ERROR_SYSCALL.
*/
-CO_ReturnError_t CO_epoll_createGtw(CO_epoll_gtw_t *epGtw,
- int epoll_fd,
- int32_t commandInterface,
- uint32_t socketTimeout_ms,
- char *localSocketPath);
+CO_ReturnError_t CO_epoll_createGtw(CO_epoll_gtw_t* epGtw, int epoll_fd, int32_t commandInterface,
+ uint32_t socketTimeout_ms, char* localSocketPath);
/**
* Close gateway-ascii sockets
*
* @param epGtw This object
*/
-void CO_epoll_closeGtw(CO_epoll_gtw_t *epGtw);
+void CO_epoll_closeGtw(CO_epoll_gtw_t* epGtw);
/**
* Initialization of gateway functions in CANopen reset-communication section
* @param epGtw This object
* @param co CANopen object
*/
-void CO_epoll_initCANopenGtw(CO_epoll_gtw_t *epGtw, CO_t *co);
+void CO_epoll_initCANopenGtw(CO_epoll_gtw_t* epGtw, CO_t* co);
/**
* Process CANopen gateway functions
*
- * This function checks for epoll events and verifies socket connection timeout.
- * It is non-blocking and should execute cyclically. It should be between
- * @ref CO_epoll_wait() and @ref CO_epoll_processLast() functions.
+ * This function checks for epoll events and verifies socket connection timeout. It is non-blocking and should execute
+ * cyclically. It should be between @ref CO_epoll_wait() and @ref CO_epoll_processLast() functions.
*
* @param epGtw This object
* @param co CANopen object
* @param ep Pointer to @ref CO_epoll_t object.
*/
-void CO_epoll_processGtw(CO_epoll_gtw_t *epGtw,
- CO_t *co,
- CO_epoll_t *ep);
+void CO_epoll_processGtw(CO_epoll_gtw_t* epGtw, CO_t* co, CO_epoll_t* ep);
#endif /* (CO_CONFIG_GTW) & CO_CONFIG_GTW_ASCII */
/** @} */
* See the License for the specific language governing permissions and limitations under the License.
*/
-
#ifndef CO_ERROR_H
#define CO_ERROR_H
#include <net/if.h>
#if __has_include("CO_error_custom.h")
- #include "CO_error_custom.h"
+#include "CO_error_custom.h"
#else
- #include "CO_error_msgs.h"
+#include "CO_error_msgs.h"
#endif
#ifdef __cplusplus
/**
* Message logging function.
*
- * Function must be defined by application. It should record log message to some
- * place, for example syslog() call in Linux or logging functionality in
- * CANopen gateway @ref CO_CANopen_309_3.
+ * Function must be defined by application. It should record log message to some place, for example syslog() call in
+ * Linux or logging functionality in CANopen gateway @ref CO_CANopen_309_3.
*
- * By default system stores messages in /var/log/syslog file.
- * Log can optionally be configured before, for example to filter out less
- * critical errors than LOG_NOTICE, specify program name, print also process PID
- * and print also to standard error, set 'user' type of program, use:
+ * By default system stores messages in /var/log/syslog file. Log can optionally be configured before, for example to
+ * filter out less critical errors than LOG_NOTICE, specify program name, print also process PID and print also to
+ * standard error, set 'user' type of program, use:
* @code
- * setlogmask (LOG_UPTO (LOG_NOTICE));
- * openlog ("exampleprog", LOG_PID | LOG_PERROR, LOG_USER);
+setlogmask (LOG_UPTO (LOG_NOTICE));
+openlog ("exampleprog", LOG_PID | LOG_PERROR, LOG_USER);
* @endcode
*
* @param priority one of LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG
* @param format format string as in printf
*/
-void log_printf(int priority, const char *format, ...);
-
+void log_printf(int priority, const char* format, ...);
/**
* driver interface state
* - bus off (no influence on bus)
*/
typedef enum {
- CO_INTERFACE_ACTIVE, /**< CAN error passive/active */
- CO_INTERFACE_LISTEN_ONLY, /**< CAN error passive/active, but currently no other device on bus */
- CO_INTERFACE_BUS_OFF /**< CAN bus off */
+ CO_INTERFACE_ACTIVE, /**< CAN error passive/active */
+ CO_INTERFACE_LISTEN_ONLY, /**< CAN error passive/active, but currently no other device on bus */
+ CO_INTERFACE_BUS_OFF /**< CAN bus off */
} CO_CANinterfaceState_t;
-
/**
- * This is how many NO-ACKs need to be received in a row to assume
- * that no other nodes are connected to a bus and therefore are
- * assuming listen-only
+ * This is how many NO-ACKs need to be received in a row to assume that no other nodes are connected to a bus and
+ * therefore are assuming listen-only
*/
-#define CO_CANerror_NOACK_MAX 16
-
+#define CO_CANerror_NOACK_MAX 16
/**
- * This is how long we are going to block transmission if listen-only
- * mode is active
+ * This is how long we are going to block transmission if listen-only mode is active
*
* Time is in seconds.
*/
#define CO_CANerror_LISTEN_ONLY 10
-
/**
* socketCAN interface error handling
*/
typedef struct {
- int fd; /**< interface FD */
- char ifName[IFNAMSIZ]; /**< interface name as string */
- uint32_t noackCounter; /**< counts no ACK on CAN transmission */
- volatile unsigned char listenOnly; /**< set to listen only mode */
- struct timespec timestamp; /**< listen only mode started at this time */
- uint16_t CANerrorStatus; /**< CAN error status bitfield, see @ref CO_CAN_ERR_status_t */
+ int fd; /**< interface FD */
+ char ifName[IFNAMSIZ]; /**< interface name as string */
+ uint32_t noackCounter; /**< counts no ACK on CAN transmission */
+ volatile unsigned char listenOnly; /**< set to listen only mode */
+ struct timespec timestamp; /**< listen only mode started at this time */
+ uint16_t CANerrorStatus; /**< CAN error status bitfield, see @ref CO_CAN_ERR_status_t */
} CO_CANinterfaceErrorhandler_t;
-
/**
* Initialize CAN error handler
*
* @param fd interface file descriptor
* @param ifname interface name as string
*/
-void CO_CANerror_init(
- CO_CANinterfaceErrorhandler_t *CANerrorhandler,
- int fd,
- const char *ifname);
-
+void CO_CANerror_init(CO_CANinterfaceErrorhandler_t* CANerrorhandler, int fd, const char* ifname);
/**
* Reset CAN error handler
*
* @param CANerrorhandler CAN error object.
*/
-void CO_CANerror_disable(
- CO_CANinterfaceErrorhandler_t *CANerrorhandler);
-
+void CO_CANerror_disable(CO_CANinterfaceErrorhandler_t* CANerrorhandler);
/**
* Message received event
*
- * When a message is received at least one other CAN module is connected.
- * Function clears listenOnly and noackCounter error flags.
+ * When a message is received at least one other CAN module is connected. Function clears listenOnly and noackCounter
+ * error flags.
*
* @param CANerrorhandler CAN error object.
*/
-void CO_CANerror_rxMsg(
- CO_CANinterfaceErrorhandler_t *CANerrorhandler);
-
+void CO_CANerror_rxMsg(CO_CANinterfaceErrorhandler_t* CANerrorhandler);
/**
* Check if interface is ready for message transmission
* @param CANerrorhandler CAN error object.
* @return CO_INTERFACE_ACTIVE message transmission ready
*/
-CO_CANinterfaceState_t CO_CANerror_txMsg(
- CO_CANinterfaceErrorhandler_t *CANerrorhandler);
-
+CO_CANinterfaceState_t CO_CANerror_txMsg(CO_CANinterfaceErrorhandler_t* CANerrorhandler);
/**
* Error message received event
* @param msg received error message
* @return #CO_CANinterfaceState_t
*/
-CO_CANinterfaceState_t CO_CANerror_rxMsgError(
- CO_CANinterfaceErrorhandler_t *CANerrorhandler,
- const struct can_frame *msg);
-
+CO_CANinterfaceState_t CO_CANerror_rxMsgError(CO_CANinterfaceErrorhandler_t* CANerrorhandler,
+ const struct can_frame* msg);
/** @} */
* See the License for the specific language governing permissions and limitations under the License.
*/
-
#ifndef CO_ERROR_MSGS_H
#define CO_ERROR_MSGS_H
extern "C" {
#endif
-
/*
* Message definitions for Linux CANopen socket driver (notice and errors)
*/
-#define CAN_NOT_FOUND "(%s) CAN Interface \"%s\" not found", __func__
-#define CAN_INIT_FAILED "(%s) CAN Interface \"%s\" Init failed", __func__
-#define CAN_BINDING_FAILED "(%s) Binding CAN Interface \"%s\" failed", __func__
-#define CAN_ERROR_FILTER_FAILED "(%s) Setting CAN Interface \"%s\" error filter failed", __func__
-#define CAN_FILTER_FAILED "(%s) Setting CAN Interface \"%s\" message filter failed", __func__
-#define CAN_NAMETOINDEX "CAN Interface \"%s\" -> Index %d"
-#define CAN_SOCKET_BUF_SIZE "CAN Interface \"%s\" RX buffer set to %d messages (%d Bytes)"
+#define CAN_NOT_FOUND "(%s) CAN Interface \"%s\" not found", __func__
+#define CAN_INIT_FAILED "(%s) CAN Interface \"%s\" Init failed", __func__
+#define CAN_BINDING_FAILED "(%s) Binding CAN Interface \"%s\" failed", __func__
+#define CAN_ERROR_FILTER_FAILED "(%s) Setting CAN Interface \"%s\" error filter failed", __func__
+#define CAN_FILTER_FAILED "(%s) Setting CAN Interface \"%s\" message filter failed", __func__
+#define CAN_NAMETOINDEX "CAN Interface \"%s\" -> Index %d"
+#define CAN_SOCKET_BUF_SIZE "CAN Interface \"%s\" RX buffer set to %d messages (%d Bytes)"
#define CAN_RX_SOCKET_QUEUE_OVERFLOW "CAN Interface \"%s\" has lost %d messages"
-#define CAN_BUSOFF "CAN Interface \"%s\" changed to \"Bus Off\". Switching to Listen Only mode..."
-#define CAN_NOACK "CAN Interface \"%s\" no \"ACK\" received. Switching to Listen Only mode..."
-#define CAN_RX_PASSIVE "CAN Interface \"%s\" changed state to \"Rx Passive\""
-#define CAN_TX_PASSIVE "CAN Interface \"%s\" changed state to \"Tx Passive\""
-#define CAN_TX_LEVEL_ACTIVE "CAN Interface \"%s\" changed state to \"Active\""
-#define CAN_RX_BUF_OVERFLOW "CAN Interface \"%s\" Rx buffer overflow. Message dropped"
-#define CAN_TX_BUF_OVERFLOW "CAN Interface \"%s\" Tx buffer overflow. Message dropped"
-#define CAN_RX_LEVEL_WARNING "CAN Interface \"%s\" reached Rx Warning Level"
-#define CAN_TX_LEVEL_WARNING "CAN Interface \"%s\" reached Tx Warning Level"
-
+#define CAN_BUSOFF "CAN Interface \"%s\" changed to \"Bus Off\". Switching to Listen Only mode..."
+#define CAN_NOACK "CAN Interface \"%s\" no \"ACK\" received. Switching to Listen Only mode..."
+#define CAN_RX_PASSIVE "CAN Interface \"%s\" changed state to \"Rx Passive\""
+#define CAN_TX_PASSIVE "CAN Interface \"%s\" changed state to \"Tx Passive\""
+#define CAN_TX_LEVEL_ACTIVE "CAN Interface \"%s\" changed state to \"Active\""
+#define CAN_RX_BUF_OVERFLOW "CAN Interface \"%s\" Rx buffer overflow. Message dropped"
+#define CAN_TX_BUF_OVERFLOW "CAN Interface \"%s\" Tx buffer overflow. Message dropped"
+#define CAN_RX_LEVEL_WARNING "CAN Interface \"%s\" reached Rx Warning Level"
+#define CAN_TX_LEVEL_WARNING "CAN Interface \"%s\" reached Tx Warning Level"
/*
* Message definitions for debugging
*/
-#define DBG_GENERAL "(%s) Error: %s%d", __func__
-#define DBG_ERRNO "(%s) OS error \"%s\" in %s", __func__, strerror(errno)
-#define DBG_CO_DEBUG "(%s) CO_DEBUG: %s", __func__
-#define DBG_CAN_TX_FAILED "(%s) Transmitting CAN msg OID 0x%03x failed(%s)", __func__
-#define DBG_CAN_RX_PARAM_FAILED "(%s) Setting CAN rx buffer failed (%s)", __func__
-#define DBG_CAN_RX_FAILED "(%s) Receiving CAN msg failed (%s)", __func__
-#define DBG_CAN_ERROR_GENERAL "(%s) Socket error msg ID: 0x%08x, Data[0..7]: 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x (%s)", __func__
-#define DBG_CAN_RX_EPOLL "(%s) CAN Epoll error (0x%02x - %s)", __func__
-#define DBG_CAN_SET_LISTEN_ONLY "(%s) %s Set Listen Only", __func__
-#define DBG_CAN_CLR_LISTEN_ONLY "(%s) %s Leave Listen Only", __func__
+#define DBG_GENERAL "(%s) Error: %s%d", __func__
+#define DBG_ERRNO "(%s) OS error \"%s\" in %s", __func__, strerror(errno)
+#define DBG_CO_DEBUG "(%s) CO_DEBUG: %s", __func__
+#define DBG_CAN_TX_FAILED "(%s) Transmitting CAN msg OID 0x%03x failed(%s)", __func__
+#define DBG_CAN_RX_PARAM_FAILED "(%s) Setting CAN rx buffer failed (%s)", __func__
+#define DBG_CAN_RX_FAILED "(%s) Receiving CAN msg failed (%s)", __func__
+#define DBG_CAN_ERROR_GENERAL \
+ "(%s) Socket error msg ID: 0x%08x, Data[0..7]: 0x%02x, 0x%02x, 0x%02x, 0x%02x," \
+ " 0x%02x, 0x%02x, 0x%02x, 0x%02x (%s)", \
+ __func__
+#define DBG_CAN_RX_EPOLL "(%s) CAN Epoll error (0x%02x - %s)", __func__
+#define DBG_CAN_SET_LISTEN_ONLY "(%s) %s Set Listen Only", __func__
+#define DBG_CAN_CLR_LISTEN_ONLY "(%s) %s Leave Listen Only", __func__
/* mainline */
-#define DBG_EMERGENCY_RX "CANopen Emergency message from node 0x%02X: errorCode=0x%04X, errorRegister=0x%02X, errorBit=0x%02X, infoCode=0x%08X"
-#define DBG_NMT_CHANGE "CANopen NMT state changed to: \"%s\" (%d)"
-#define DBG_HB_CONS_NMT_CHANGE "CANopen Remote node ID = 0x%02X (index = %d): NMT state changed to: \"%s\" (%d)"
-#define DBG_ARGUMENT_UNKNOWN "(%s) Unknown %s argument: \"%s\"", __func__
-#define DBG_NOT_TCP_PORT "(%s) -c argument \"%s\" is not a valid tcp port", __func__
-#define DBG_WRONG_NODE_ID "(%s) Wrong node ID \"%d\"", __func__
-#define DBG_WRONG_PRIORITY "(%s) Wrong RT priority \"%d\"", __func__
-#define DBG_NO_CAN_DEVICE "(%s) Can't find CAN device \"%s\"", __func__
-#define DBG_STORAGE "(%s) Error with storage \"%s\"", __func__
-#define DBG_OD_ENTRY "(%s) Error in Object Dictionary entry: 0x%X", __func__
-#define DBG_CAN_OPEN "(%s) CANopen error in %s, err=%d", __func__
-#define DBG_CAN_OPEN_INFO "CANopen device, Node ID = 0x%02X, %s"
+#define DBG_EMERGENCY_RX \
+ "CANopen Emergency message from node 0x%02X: errorCode=0x%04X, errorRegister=0x%02X, errorBit=0x%02X, " \
+ "infoCode=0x%08X"
+#define DBG_NMT_CHANGE "CANopen NMT state changed to: \"%s\" (%d)"
+#define DBG_HB_CONS_NMT_CHANGE "CANopen Remote node ID = 0x%02X (index = %d): NMT state changed to: \"%s\" (%d)"
+#define DBG_ARGUMENT_UNKNOWN "(%s) Unknown %s argument: \"%s\"", __func__
+#define DBG_NOT_TCP_PORT "(%s) -c argument \"%s\" is not a valid tcp port", __func__
+#define DBG_WRONG_NODE_ID "(%s) Wrong node ID \"%d\"", __func__
+#define DBG_WRONG_PRIORITY "(%s) Wrong RT priority \"%d\"", __func__
+#define DBG_NO_CAN_DEVICE "(%s) Can't find CAN device \"%s\"", __func__
+#define DBG_STORAGE "(%s) Error with storage \"%s\"", __func__
+#define DBG_OD_ENTRY "(%s) Error in Object Dictionary entry: 0x%X", __func__
+#define DBG_CAN_OPEN "(%s) CANopen error in %s, err=%d", __func__
+#define DBG_CAN_OPEN_INFO "CANopen device, Node ID = 0x%02X, %s"
/* CO_epoll_interface */
-#define DBG_EPOLL_UNKNOWN "(%s) CAN Epoll error, events=0x%02x, fd=%d", __func__
-#define DBG_COMMAND_LOCAL_BIND "(%s) Can't bind local socket to path \"%s\"", __func__
-#define DBG_COMMAND_TCP_BIND "(%s) Can't bind tcp socket to port \"%d\"", __func__
-#define DBG_COMMAND_STDIO_INFO "CANopen command interface on \"standard IO\" started"
-#define DBG_COMMAND_LOCAL_INFO "CANopen command interface on local socket \"%s\" started"
-#define DBG_COMMAND_TCP_INFO "CANopen command interface on tcp port \"%d\" started"
-
+#define DBG_EPOLL_UNKNOWN "(%s) CAN Epoll error, events=0x%02x, fd=%d", __func__
+#define DBG_COMMAND_LOCAL_BIND "(%s) Can't bind local socket to path \"%s\"", __func__
+#define DBG_COMMAND_TCP_BIND "(%s) Can't bind tcp socket to port \"%d\"", __func__
+#define DBG_COMMAND_STDIO_INFO "CANopen command interface on \"standard IO\" started"
+#define DBG_COMMAND_LOCAL_INFO "CANopen command interface on local socket \"%s\" started"
+#define DBG_COMMAND_TCP_INFO "CANopen command interface on tcp port \"%d\" started"
#ifdef __cplusplus
}
#include "storage/CO_storage.h"
-#if ((CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE) || defined CO_DOXYGEN
+#if ((CO_CONFIG_STORAGE)&CO_CONFIG_STORAGE_ENABLE) || defined CO_DOXYGEN
#ifdef __cplusplus
extern "C" {
*
* @ingroup CO_socketCAN
* @{
- *
* See also @ref CO_storage.
*/
-
/**
* Initialize data storage object (Linux specific)
*
- * This function should be called by application after the program startup,
- * before @ref CO_CANopenInit(). This function initializes storage object,
- * OD extensions on objects 1010 and 1011, reads data from file, verifies them
- * and writes data to addresses specified inside entries. This function
- * internally calls @ref CO_storage_init().
+ * This function should be called by application after the program startup, before @ref CO_CANopenInit(). This function
+ * initializes storage object, OD extensions on objects 1010 and 1011, reads data from file, verifies them and writes
+ * data to addresses specified inside entries. This function internally calls @ref CO_storage_init().
*
* @param storage This object will be initialized. It must be defined by application and must exist permanently.
* @param CANmodule CAN device, used for @ref CO_LOCK_OD() macro.
* @param OD_1010_StoreParameters OD entry for 0x1010 -"Store parameters". Entry is optional, may be NULL.
- * @param OD_1011_RestoreDefaultParam OD entry for 0x1011 -"Restore default
- * parameters". Entry is optional, may be NULL.
+ * @param OD_1011_RestoreDefaultParam OD entry for 0x1011 -"Restore default parameters". Entry is optional, may be NULL.
* @param entries Pointer to array of storage entries, see @ref CO_storage_init.
* @param entriesCount Count of storage entries
- * @param [out] storageInitError If function returns CO_ERROR_DATA_CORRUPT,
- * then this variable contains a bit mask from subIndexOD values, where data
- * was not properly initialized. If other error, then this variable contains
- * index or erroneous entry.
+ * @param [out] storageInitError If function returns CO_ERROR_DATA_CORRUPT, then this variable contains a bit mask from
+ * subIndexOD values, where data was not properly initialized. If other error, then this variable contains index or
+ * erroneous entry.
*
- * @return CO_ERROR_NO, CO_ERROR_DATA_CORRUPT if data can not be initialized,
- * CO_ERROR_ILLEGAL_ARGUMENT or CO_ERROR_OUT_OF_MEMORY.
+ * @return CO_ERROR_NO, CO_ERROR_DATA_CORRUPT if data can not be initialized, CO_ERROR_ILLEGAL_ARGUMENT or
+ * CO_ERROR_OUT_OF_MEMORY.
*/
-CO_ReturnError_t CO_storageLinux_init(CO_storage_t *storage,
- CO_CANmodule_t *CANmodule,
- OD_entry_t *OD_1010_StoreParameters,
- OD_entry_t *OD_1011_RestoreDefaultParam,
- CO_storage_entry_t *entries,
- uint8_t entriesCount,
- uint32_t *storageInitError);
-
+CO_ReturnError_t CO_storageLinux_init(CO_storage_t* storage, CO_CANmodule_t* CANmodule,
+ OD_entry_t* OD_1010_StoreParameters, OD_entry_t* OD_1011_RestoreDefaultParam,
+ CO_storage_entry_t* entries, uint8_t entriesCount, uint32_t* storageInitError);
/**
* Automatically save data if differs from previous call.
*
- * Should be called cyclically by program. Each interval it verifies, if crc
- * checksum of data differs from previous checksum. If it does, data are saved
- * into pre-opened file.
+ * Should be called cyclically by program. Each interval it verifies, if crc checksum of data differs from previous
+ * checksum. If it does, data are saved into pre-opened file.
*
* @param storage This object
* @param closeFiles If true, then all files will be closed. Use on end of the program.
*
* @return 0 on success or bit mask from subIndexOD values, where data was not able to be saved.
*/
-uint32_t CO_storageLinux_auto_process(CO_storage_t *storage,
- bool_t closeFiles);
+uint32_t CO_storageLinux_auto_process(CO_storage_t* storage, bool_t closeFiles);
/** @} */ /* CO_storageLinux */