diff --git a/socketCAN/CO_Linux_threads.c b/socketCAN/CO_Linux_threads.c index e147a28..d6b84e0 100644 --- a/socketCAN/CO_Linux_threads.c +++ b/socketCAN/CO_Linux_threads.c @@ -125,9 +125,13 @@ void CANrx_threadTmr_process(void) if(CO->CANmodule[0]->CANnormal) { for (i = 0; i <= missed; i++) { + +#if CO_NO_SYNC == 1 /* Process Sync */ syncWas = CO_process_SYNC(CO, threadRT.us_interval, NULL); - +#else + syncWas = false; +#endif /* Read inputs */ CO_process_RPDO(CO, syncWas); diff --git a/socketCAN/CO_driver.c b/socketCAN/CO_driver.c index 9f6f76c..82b4875 100644 --- a/socketCAN/CO_driver.c +++ b/socketCAN/CO_driver.c @@ -36,9 +36,13 @@ #include "301/CO_driver.h" -#if defined CO_DRIVER_ERROR_REPORTING && __has_include("syslog/log.h") - #include "syslog/log.h" - #include "msgs.h" +#if defined CO_DRIVER_ERROR_REPORTING + #if __has_include("syslog1/log.h") + #include "syslog/log.h" + #include "msgs.h" + #else + #include "CO_msgs.h" + #endif #else #define log_printf(macropar_prio, macropar_message, ...) #endif @@ -52,7 +56,7 @@ pthread_mutex_t CO_EMCY_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t CO_OD_mutex = PTHREAD_MUTEX_INITIALIZER; #ifndef CO_DRIVER_MULTI_INTERFACE -static CO_ReturnError_t CO_CANmodule_addInterface(CO_CANmodule_t *CANmodule, int32_t CANbaseAddress); +static CO_ReturnError_t CO_CANmodule_addInterface(CO_CANmodule_t *CANmodule, const void *CANptr); #endif #ifdef CO_DRIVER_MULTI_INTERFACE @@ -175,7 +179,7 @@ static CO_ReturnError_t setRxFilters(CO_CANmodule_t *CANmodule) /******************************************************************************/ void CO_CANsetConfigurationMode(void *CANptr) { - /* Can't do anything because no object is provided */ + /* Can't do anything because no reference to CANmodule_t is provided */ } @@ -272,7 +276,7 @@ CO_ReturnError_t CO_CANmodule_init( rxArray[i].object = NULL; rxArray[i].CANrx_callback = NULL; #ifdef CO_DRIVER_MULTI_INTERFACE - rxArray[i].CANbaseAddress = -1; + rxArray[i].CANptr = NULL; rxArray[i].timestamp.tv_sec = 0; rxArray[i].timestamp.tv_nsec = 0; #endif @@ -280,8 +284,7 @@ CO_ReturnError_t CO_CANmodule_init( #ifndef CO_DRIVER_MULTI_INTERFACE /* add one interface */ - intptr_t CANaddr = (intptr_t)CANptr; - ret = CO_CANmodule_addInterface(CANmodule, (int32_t)CANaddr); + ret = CO_CANmodule_addInterface(CANmodule, CANptr); if (ret != CO_ERROR_NO) { CO_CANmodule_disable(CANmodule); } @@ -298,7 +301,7 @@ static #endif CO_ReturnError_t CO_CANmodule_addInterface( CO_CANmodule_t *CANmodule, - int32_t CANbaseAddress) + const void *CANptr) { int32_t ret; int32_t tmp; @@ -312,7 +315,7 @@ CO_ReturnError_t CO_CANmodule_addInterface( can_err_mask_t err_mask; #endif - if (CANmodule->CANnormal) { + if (CANmodule->CANnormal != false) { /* can't change config now! */ return CO_ERROR_INVALID_STATE; } @@ -327,8 +330,8 @@ CO_ReturnError_t CO_CANmodule_addInterface( } interface = &CANmodule->CANinterfaces[CANmodule->CANinterfaceCount - 1]; - interface->CANbaseAddress = CANbaseAddress; - ifName = if_indextoname(CANbaseAddress, interface->ifName); + interface->CANptr = CANptr; + ifName = if_indextoname((uintptr_t)interface->CANptr, interface->ifName); if (ifName == NULL) { log_printf(LOG_DEBUG, DBG_ERRNO, "if_indextoname()"); return CO_ERROR_ILLEGAL_ARGUMENT; @@ -376,7 +379,7 @@ CO_ReturnError_t CO_CANmodule_addInterface( /* bind socket */ memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.can_family = AF_CAN; - sockAddr.can_ifindex = CANbaseAddress; + sockAddr.can_ifindex = (uintptr_t)interface->CANptr; ret = bind(interface->fd, (struct sockaddr*)&sockAddr, sizeof(sockAddr)); if(ret < 0){ log_printf(LOG_ERR, CAN_BINDING_FAILED, interface->ifName); @@ -506,7 +509,7 @@ CO_ReturnError_t CO_CANrxBufferInit( buffer->object = object; buffer->CANrx_callback = CANrx_callback; #ifdef CO_DRIVER_MULTI_INTERFACE - buffer->CANbaseAddress = -1; + buffer->CANptr = NULL; buffer->timestamp.tv_nsec = 0; buffer->timestamp.tv_sec = 0; #endif @@ -538,36 +541,35 @@ CO_ReturnError_t CO_CANrxBufferInit( /******************************************************************************/ bool_t CO_CANrxBuffer_getInterface( CO_CANmodule_t *CANmodule, - uint32_t ident, - int32_t *CANbaseAddressRx, + uint16_t ident, + const void **const CANptrRx, struct timespec *timestamp) { - if (CANmodule != NULL){ - uint32_t index; - CO_CANrx_t *buffer; + CO_CANrx_t *buffer; - index = CO_CANgetIndexFromIdent(CANmodule->rxIdentToIndex, ident); - if ((index == CO_INVALID_COB_ID) || (index > CANmodule->rxSize)) { - return false; - } - buffer = &CANmodule->rxArray[index]; - - /* return values */ - if (CANbaseAddressRx != NULL) { - *CANbaseAddressRx = buffer->CANbaseAddress; - } - if (timestamp != NULL) { - *timestamp = buffer->timestamp; - } - - if (buffer->CANbaseAddress >= 0) { - return true; - } - else { - return false; - } + if (CANmodule == NULL){ + return false; + } + + const uint32_t index = CO_CANgetIndexFromIdent(CANmodule->rxIdentToIndex, ident); + if ((index == CO_INVALID_COB_ID) || (index > CANmodule->rxSize)) { + return false; + } + buffer = &CANmodule->rxArray[index]; + + /* return values */ + if (CANptrRx != NULL) { + *CANptrRx = buffer->CANptr; + } + if (timestamp != NULL) { + *timestamp = buffer->timestamp; + } + if (buffer->CANptr != NULL) { + return true; + } + else { + return false; } - return false; } #endif @@ -592,7 +594,7 @@ CO_CANtx_t *CO_CANtxBufferInit( CO_CANsetIdentToIndex(CANmodule->txIdentToIndex, index, ident, buffer->ident); #endif - buffer->CANbaseAddress = -1; + buffer->CANptr = NULL; /* CAN identifier and rtr */ buffer->ident = ident & CAN_SFF_MASK; @@ -612,8 +614,8 @@ CO_CANtx_t *CO_CANtxBufferInit( /******************************************************************************/ CO_ReturnError_t CO_CANtxBuffer_setInterface( CO_CANmodule_t *CANmodule, - uint32_t ident, - int32_t CANbaseAddressTx) + uint16_t ident, + const void *CANptrTx) { if (CANmodule != NULL) { uint32_t index; @@ -622,7 +624,7 @@ CO_ReturnError_t CO_CANtxBuffer_setInterface( if ((index == CO_INVALID_COB_ID) || (index > CANmodule->txSize)) { return CO_ERROR_PARAMETERS; } - CANmodule->txArray[index].CANbaseAddress = CANbaseAddressTx; + CANmodule->txArray[index].CANptr = CANptrTx; return CO_ERROR_NO; } @@ -743,8 +745,8 @@ CO_ReturnError_t CO_CANCheckSend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer) for (i = 0; i < CANmodule->CANinterfaceCount; i++) { CO_CANinterface_t *interface = &CANmodule->CANinterfaces[i]; - if (buffer->CANbaseAddress < 0 || - buffer->CANbaseAddress == interface->CANbaseAddress) { + if ((buffer->CANptr == NULL) || + buffer->CANptr == interface->CANptr) { CO_ReturnError_t tmp; @@ -890,7 +892,9 @@ int32_t CO_CANrxWait(CO_CANmodule_t *CANmodule, int fdTimer, CO_CANrxMsg_t *buff { int32_t retval; int32_t ret; - int32_t CANbaseAddress __attribute__((unused)); +#ifdef CO_DRIVER_MULTI_INTERFACE + const void *CANptr; +#endif CO_ReturnError_t err; CO_CANinterface_t *interface = NULL; struct epoll_event ev[1]; @@ -949,8 +953,10 @@ int32_t CO_CANrxWait(CO_CANmodule_t *CANmodule, int fdTimer, CO_CANrxMsg_t *buff interface = &CANmodule->CANinterfaces[i]; if (ev[0].data.fd == interface->fd) { +#ifdef CO_DRIVER_MULTI_INTERFACE /* get interface handle */ - CANbaseAddress = interface->CANbaseAddress; + CANdriverState = interface->CANptr; +#endif /* get message */ err = CO_CANread(CANmodule, interface, &msg, ×tamp); if (err != CO_ERROR_NO) { @@ -989,7 +995,7 @@ int32_t CO_CANrxWait(CO_CANmodule_t *CANmodule, int fdTimer, CO_CANrxMsg_t *buff #ifdef CO_DRIVER_MULTI_INTERFACE /* Store message info */ CANmodule->rxArray[msgIndex].timestamp = timestamp; - CANmodule->rxArray[msgIndex].CANbaseAddress = CANbaseAddress; + CANmodule->rxArray[msgIndex].CANptr = CANptr; #endif } retval = msgIndex; diff --git a/socketCAN/CO_driver_target.h b/socketCAN/CO_driver_target.h index 53ef9dc..5577ac9 100644 --- a/socketCAN/CO_driver_target.h +++ b/socketCAN/CO_driver_target.h @@ -129,7 +129,6 @@ static inline uint8_t *CO_CANrxMsg_readData(void *rxMsg) { } - /* Received message object */ typedef struct { uint32_t ident; @@ -138,7 +137,7 @@ typedef struct { void (*CANrx_callback)(void *object, void *message); #ifdef CO_DRIVER_MULTI_INTERFACE /* info about last received message */ - int32_t CANbaseAddress; /* CAN Interface identifier */ + const void *CANptr; /* CAN Interface identifier */ struct timespec timestamp; /* time of reception */ #endif } CO_CANrx_t; @@ -231,12 +230,12 @@ static inline void CO_UNLOCK_OD() { * Function must be called after CO_CANmodule_init. * * @param CANmodule This object will be initialized. - * @param CANbaseAddress CAN module base address. + * @param CANptr CAN module interface index (return value if_nametoindex(), NO pointer!). * @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, - int32_t CANbaseAddress); + const void *CANptr); /* * Check on which interface the last message for one message buffer was received @@ -246,7 +245,7 @@ CO_ReturnError_t CO_CANmodule_addInterface(CO_CANmodule_t *CANmodule, * * @param CANmodule This object. * @param ident 11-bit standard CAN Identifier. - * @param [out] CANbaseAddressRx message was received on this interface + * @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 @@ -254,8 +253,8 @@ CO_ReturnError_t CO_CANmodule_addInterface(CO_CANmodule_t *CANmodule, * @retval true base address and timestamp are valid */ bool_t CO_CANrxBuffer_getInterface(CO_CANmodule_t *CANmodule, - uint32_t ident, - int32_t *CANbaseAddressRx, + uint16_t ident, + const void **const CANptrRx, struct timespec *timestamp); /* @@ -264,26 +263,26 @@ bool_t CO_CANrxBuffer_getInterface(CO_CANmodule_t *CANmodule, * 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 "-1" is used, a message is transmitted on + * 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. - * @param CANbaseAddressTx use this interface. -1 = not specified + * @param CANptrTx use this interface. NULL = not specified * * @return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT. */ CO_ReturnError_t CO_CANtxBuffer_setInterface(CO_CANmodule_t *CANmodule, - uint32_t ident, - int32_t CANbaseAddressTx); -#endif + uint16_t ident, + const void *CANptrTx); +#endif /* CO_DRIVER_MULTI_INTERFACE */ /* * Functions receives CAN messages. It is blocking. * * This function can be used in two ways - * - automatic mode (call callback that is set by CO_CANrxBufferInit() function) + * - automatic mode (call callback that is set by #CO_CANrxBufferInit() function) * - manual mode (evaluate message filters, return received message) * * Both modes can be combined. diff --git a/socketCAN/CO_error.c b/socketCAN/CO_error.c index 25d3bc1..f0a0db3 100644 --- a/socketCAN/CO_error.c +++ b/socketCAN/CO_error.c @@ -32,10 +32,13 @@ #include "301/CO_driver.h" #include "CO_error.h" - -#if defined CO_DRIVER_ERROR_REPORTING && __has_include("syslog/log.h") - #include "syslog/log.h" - #include "msgs.h" +#if defined CO_DRIVER_ERROR_REPORTING + #if __has_include("syslog/log.h") + #include "syslog/log.h" + #include "msgs.h" + #else + #include "CO_msgs.h" + #endif #else #define log_printf(macropar_prio, macropar_message, ...) #endif @@ -192,7 +195,7 @@ void CO_CANerror_init( } CANerrorhandler->fd = fd; - CANerrorhandler->ifName = ifName; + memcpy(CANerrorhandler->ifName, ifName, sizeof(CANerrorhandler->ifName)); CANerrorhandler->noackCounter = 0; CANerrorhandler->listenOnly = false; CANerrorhandler->timestamp.tv_sec = 0; diff --git a/socketCAN/CO_error.h b/socketCAN/CO_error.h index 732c1a8..0db38c0 100644 --- a/socketCAN/CO_error.h +++ b/socketCAN/CO_error.h @@ -71,11 +71,11 @@ typedef enum { */ typedef struct { int fd; /**< interface FD */ - const char *ifName; /**< interface name as string */ + char ifName[IFNAMSIZ]; /**< interface name as string */ uint32_t noackCounter; - volatile unsigned char listenOnly; /**< set to listen only mode */ + volatile bool_t listenOnly; /**< set to listen only mode */ struct timespec timestamp; /**< listen only mode started at this time */ } CO_CANinterfaceErrorhandler_t; diff --git a/socketCAN/CO_msgs.h b/socketCAN/CO_msgs.h new file mode 100644 index 0000000..9a3d836 --- /dev/null +++ b/socketCAN/CO_msgs.h @@ -0,0 +1,95 @@ +/** + * CAN module object for Linux socketCAN. + * + * This file is a template for other microcontrollers. + * + * @file CO_msgs.h + * @ingroup CO_driver + * @author Martin Wagner + * @copyright 2020 Neuberger Gebaeudeautomation GmbH + * + * + * This file is part of CANopenNode, an opensource CANopen Stack. + * Project home page is . + * For more information on CANopen see . + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef CO_MSGS_H +#define CO_MSGS_H + +#include +#include +#include "CO_msgs.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * message printing function + */ +#define log_printf(macropar_prio, macropar_message, ...) \ + if (macropar_prio < LOG_DEBUG) { \ + printf(macropar_message, ##__VA_ARGS__); \ + } + +/* + * message logging function. You need to open the log previous to this. + */ +//#define log_printf(macropar_prio, macropar_message, ...) syslog(macropar_prio, macropar_message, ##__VA_ARGS__); + + + +/* + * Message definitions for Linux CANopen socket driver (notice and errors) + */ +#define CAN_NOT_FOUND "CAN Interface \"%s\" not found" +#define CAN_INIT_FAILED "CAN Interface \"%s\" Init failed" +#define CAN_NAMETOINDEX "Interface \"%s\" -> Index %d" +#define CAN_SOCKET_BUF_SIZE "CAN Interface \"%s\" Buffer set to %d messages (%d Bytes)" +#define CAN_BINDING_FAILED "Binding CAN Interface \"%s\" failed" +#define CAN_ERROR_FILTER_FAILED "Setting CAN Interface \"%s\" error filter failed" +#define CAN_FILTER_FAILED "Setting CAN Interface \"%s\" message filter failed" +#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" + +/* + * Debug + */ +#define DBG_ERRNO "(%s) OS error \"%s\" in %s", __func__, strerror(errno) +#define DBG_CAN_TX_FAILED "(%s) Transmitting CAN msg OID 0x%08x 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__ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/** @} */ +#endif