socketCAN driver:
- Always enable CANptr and timestamp info in CO_CANrx_t. - Update documentation
This commit is contained in:
parent
f21cde9ab0
commit
9d17b0d671
11 changed files with 148 additions and 112 deletions
|
|
@ -129,7 +129,7 @@ extern "C" {
|
|||
|
||||
#ifdef CO_DOXYGEN
|
||||
/**
|
||||
* @defgroup CO_NO_OBJ Number of CANopenNode communication objects.
|
||||
* @defgroup CO_NO_OBJ Configuration
|
||||
*
|
||||
* Definitions specify, which and how many CANopenNode communication objects
|
||||
* will be used in current configuration. Usage of some objects is mandatory and
|
||||
|
|
|
|||
2
Doxyfile
2
Doxyfile
|
|
@ -2057,7 +2057,7 @@ PREDEFINED = CO_DOXYGEN \
|
|||
CO_NO_SDO_CLIENT=1 \
|
||||
CO_NO_NMT_MASTER=1 \
|
||||
CO_NO_LSS_SERVER \
|
||||
CO_NO_LSS_CLIENT \
|
||||
CO_NO_LSS_CLIENT=1 \
|
||||
CO_NO_TRACE=1
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ Change Log
|
|||
- NMT self start functionality (OD object 1F80) implemented to strictly folow standard. Default value for object 1F80 have to be updated in OD editor. See README.md.
|
||||
### Fixed
|
||||
- Various fixes.
|
||||
- neuberger-socketCAN fixed.
|
||||
### Added
|
||||
- CANopen TIME protocol added.
|
||||
|
||||
|
|
|
|||
|
|
@ -111,9 +111,9 @@ void CANrx_threadTmr_close(void)
|
|||
void CANrx_threadTmr_process(void)
|
||||
{
|
||||
int32_t result;
|
||||
int32_t i;
|
||||
uint64_t i;
|
||||
bool_t syncWas;
|
||||
unsigned long long missed;
|
||||
uint64_t missed;
|
||||
|
||||
result = CO_CANrxWait(CO->CANmodule[0], threadRT.interval_fd, NULL);
|
||||
if (result < 0) {
|
||||
|
|
|
|||
|
|
@ -33,75 +33,90 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup CO_socketCAN socketCAN
|
||||
* @{
|
||||
*
|
||||
* Linux specific interface to CANopenNode
|
||||
*
|
||||
* CANopenNode runs in two threads: timer based realtime thread for CAN receive,
|
||||
* SYNC and PDO and mainline thread for other processing.
|
||||
* CANopenNode runs in two threads:
|
||||
* - timer based real-time thread for CAN receive, SYNC and PDO, see
|
||||
* CANrx_threadTmr_process()
|
||||
* - mainline thread for other processing, see threadMain_process()
|
||||
*
|
||||
* The "threads" specified here do not fork threads themselves, but require
|
||||
* that two threads are provided by the calling application.
|
||||
* It uses the global CO object and has one thread-local struct for variables.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Initialize mainline thread.
|
||||
*
|
||||
* threadMain is non-realtime thread for CANopenNode processing. It is nonblocking
|
||||
* and should be called cyclically in 50 ms intervals or less if necessary. This
|
||||
* is indicated by the callback function.
|
||||
* This thread processes CO_process() function from CANopen.c file.
|
||||
*
|
||||
* @param callback this function is called to indicate #threadMain_process() has
|
||||
* work to do
|
||||
* @param object this pointer is given to _callback()_
|
||||
*/
|
||||
extern void threadMain_init(void (*callback)(void*), void *object);
|
||||
|
||||
|
||||
/**
|
||||
* Cleanup mainline thread.
|
||||
*/
|
||||
extern void threadMain_close(void);
|
||||
|
||||
|
||||
/**
|
||||
* Process mainline thread.
|
||||
*
|
||||
* Function must be called cyclically and after callback
|
||||
* threadMain is non-realtime thread for CANopenNode processing. It is
|
||||
* initialized by threadMain_init(). There is no configuration for CANopen
|
||||
* objects. There is also no configuration for epool or interval timer or notify
|
||||
* pipe. These must be specified externally.
|
||||
*
|
||||
* threadMain_process() calls CO_process() function for processing mainline
|
||||
* CANopen objects. It is non-blocking and should be called cyclically in 50 ms
|
||||
* intervals (typically). Function must also be called immediately after
|
||||
* callback provided in threadMain_init() is called.
|
||||
*
|
||||
* @param reset return value from CO_process() function.
|
||||
*/
|
||||
extern void threadMain_process(CO_NMT_reset_cmd_t *reset);
|
||||
|
||||
|
||||
/**
|
||||
* Initialize realtime thread.
|
||||
*
|
||||
* CANrx_threadTmr is realtime thread for CANopenNode processing. It is nonblocking
|
||||
* and must be executed at CAN message receive or periodically in 1ms (or something)
|
||||
* intervals. Inside interval is processed CANopen SYNC message, RPDOs(inputs)
|
||||
* and TPDOs(outputs).
|
||||
* CANrx_threadTmr uses CAN socket from CO_driver.c
|
||||
*
|
||||
* @remark If realtime is required, this thread must be registred as such in the Linux
|
||||
* kernel.
|
||||
*
|
||||
* @param interval_us Interval of periodic timer in microseconds, recommended
|
||||
* value for realtime response: 1000 us
|
||||
*/
|
||||
extern void CANrx_threadTmr_init(uint32_t interval_us);
|
||||
|
||||
|
||||
/**
|
||||
* Terminate realtime thread.
|
||||
*/
|
||||
extern void CANrx_threadTmr_close(void);
|
||||
|
||||
|
||||
/**
|
||||
* Process realtime thread.
|
||||
* Process real-time thread.
|
||||
*
|
||||
* This function must be called inside an infinite loop. It blocks until either
|
||||
* some event happens or a timer runs out.
|
||||
* CANrx_threadTmr is realtime thread for CANopenNode processing. It is
|
||||
* initialized by CANrx_threadTmr_init(). There is no configuration for CANopen
|
||||
* objects. But configuration for epool event notification facility is included
|
||||
* in CO_CANmodule_init() from CO_driver.c. Epool is configured to monitor the
|
||||
* following file descriptors: notify pipe, CANrx sockets from all interfaces
|
||||
* and interval timer.
|
||||
*
|
||||
* CANrx_threadTmr_process() blocks on epoll_wait(). This is implemented inside
|
||||
* CO_CANrxWait() from CO_driver.c. New CAN message is processed in
|
||||
* CANrx_threadTmr_process() function, which calls CO_process_SYNC(),
|
||||
* CO_process_RPDO() and CO_process_TPDO() functions for each expired timer
|
||||
* interval. This function must be called inside an infinite loop.
|
||||
*
|
||||
* @remark If realtime is required, this thread must be registered as such in
|
||||
* the Linux kernel.
|
||||
*/
|
||||
extern void CANrx_threadTmr_process();
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* CANopen Object Dictionary storage object for Linux SocketCAN.
|
||||
*
|
||||
* @file CO_OD_storage.h
|
||||
* @ingroup CO_socketCAN
|
||||
* @ingroup CO_socketCAN_OD_storage
|
||||
* @author Janez Paternoster
|
||||
* @copyright 2015 - 2020 Janez Paternoster
|
||||
*
|
||||
|
|
@ -38,7 +38,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup CO_OD_storage OD_storage
|
||||
* @defgroup CO_socketCAN_OD_storage OD storage
|
||||
* @ingroup CO_socketCAN
|
||||
* @{
|
||||
*
|
||||
|
|
|
|||
|
|
@ -32,7 +32,9 @@
|
|||
#include <linux/can/error.h>
|
||||
#include <linux/net_tstamp.h>
|
||||
#include <sys/socket.h>
|
||||
#include <asm/socket.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "301/CO_driver.h"
|
||||
#include "CO_error.h"
|
||||
|
|
@ -268,11 +270,9 @@ CO_ReturnError_t CO_CANmodule_init(
|
|||
rxArray[i].mask = 0xFFFFFFFFU;
|
||||
rxArray[i].object = NULL;
|
||||
rxArray[i].CANrx_callback = NULL;
|
||||
#ifdef CO_DRIVER_MULTI_INTERFACE
|
||||
rxArray[i].CANptr = NULL;
|
||||
rxArray[i].timestamp.tv_sec = 0;
|
||||
rxArray[i].timestamp.tv_nsec = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef CO_DRIVER_MULTI_INTERFACE
|
||||
|
|
@ -344,7 +344,7 @@ CO_ReturnError_t CO_CANmodule_addInterface(
|
|||
log_printf(LOG_DEBUG, DBG_ERRNO, "setsockopt(ovfl)");
|
||||
return CO_ERROR_SYSCALL;
|
||||
}
|
||||
#ifdef CO_DRIVER_MULTI_INTERFACE
|
||||
|
||||
/* enable software time stamp mode (hardware timestamps do not work properly
|
||||
* on all devices)*/
|
||||
tmp = (SOF_TIMESTAMPING_SOFTWARE |
|
||||
|
|
@ -354,7 +354,6 @@ CO_ReturnError_t CO_CANmodule_addInterface(
|
|||
log_printf(LOG_DEBUG, DBG_ERRNO, "setsockopt(timestamping)");
|
||||
return CO_ERROR_SYSCALL;
|
||||
}
|
||||
#endif
|
||||
|
||||
//todo - modify rx buffer size? first one needs root
|
||||
//ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, (void *)&bytes, sLen);
|
||||
|
|
@ -501,11 +500,9 @@ CO_ReturnError_t CO_CANrxBufferInit(
|
|||
/* Configure object variables */
|
||||
buffer->object = object;
|
||||
buffer->CANrx_callback = CANrx_callback;
|
||||
#ifdef CO_DRIVER_MULTI_INTERFACE
|
||||
buffer->CANptr = NULL;
|
||||
buffer->timestamp.tv_nsec = 0;
|
||||
buffer->timestamp.tv_sec = 0;
|
||||
#endif
|
||||
|
||||
/* CAN identifier and CAN mask, bit aligned with CAN module */
|
||||
buffer->ident = ident & CAN_SFF_MASK;
|
||||
|
|
@ -626,7 +623,7 @@ CO_ReturnError_t CO_CANtxBuffer_setInterface(
|
|||
|
||||
#endif /* CO_DRIVER_MULTI_INTERFACE */
|
||||
|
||||
/******************************************************************************/
|
||||
/* send CAN message ***********************************************************/
|
||||
static CO_ReturnError_t CO_CANCheckSendInterface(
|
||||
CO_CANmodule_t *CANmodule,
|
||||
CO_CANtx_t *buffer,
|
||||
|
|
@ -773,12 +770,12 @@ void CO_CANverifyErrors(CO_CANmodule_t *CANmodule)
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Read CAN message from socket and verify some errors ************************/
|
||||
static CO_ReturnError_t CO_CANread(
|
||||
CO_CANmodule_t *CANmodule,
|
||||
CO_CANinterface_t *interface,
|
||||
struct can_frame *msg,
|
||||
struct timespec *timestamp)
|
||||
struct can_frame *msg, /* CAN message, return value */
|
||||
struct timespec *timestamp) /* timestamp of CAN message, return value */
|
||||
{
|
||||
int32_t n;
|
||||
uint32_t dropped;
|
||||
|
|
@ -838,10 +835,11 @@ static CO_ReturnError_t CO_CANread(
|
|||
}
|
||||
|
||||
|
||||
static int32_t CO_CANrxMsg(
|
||||
/* find msg inside rxArray and call corresponding CANrx_callback **************/
|
||||
static int32_t CO_CANrxMsg( /* return index of received message in rxArray or -1 */
|
||||
CO_CANmodule_t *CANmodule,
|
||||
struct can_frame *msg,
|
||||
CO_CANrxMsg_t *buffer)
|
||||
struct can_frame *msg, /* CAN message input */
|
||||
CO_CANrxMsg_t *buffer) /* If not NULL, msg will be copied to buffer */
|
||||
{
|
||||
int32_t retval;
|
||||
const CO_CANrxMsg_t *rcvMsg; /* pointer to received message in CAN module */
|
||||
|
|
@ -888,9 +886,7 @@ int32_t CO_CANrxWait(CO_CANmodule_t *CANmodule, int fdTimer, CO_CANrxMsg_t *buff
|
|||
{
|
||||
int32_t retval;
|
||||
int32_t ret;
|
||||
#ifdef CO_DRIVER_MULTI_INTERFACE
|
||||
const void *CANptr;
|
||||
#endif
|
||||
CO_ReturnError_t err;
|
||||
CO_CANinterface_t *interface = NULL;
|
||||
struct epoll_event ev[1];
|
||||
|
|
@ -938,7 +934,7 @@ int32_t CO_CANrxWait(CO_CANmodule_t *CANmodule, int fdTimer, CO_CANrxMsg_t *buff
|
|||
/* one of the sockets is ready */
|
||||
if ((ev[0].data.fd == CO_NotifyPipeGetFd(CANmodule->pipe)) ||
|
||||
(ev[0].data.fd == fdTimer)) {
|
||||
/* timer/pipe socket */
|
||||
/* timer or notify pipe */
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
|
|
@ -949,10 +945,8 @@ 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 */
|
||||
CANdriverState = interface->CANptr;
|
||||
#endif
|
||||
CANptr = interface->CANptr;
|
||||
/* get message */
|
||||
err = CO_CANread(CANmodule, interface, &msg, ×tamp);
|
||||
if (err != CO_ERROR_NO) {
|
||||
|
|
@ -983,16 +977,15 @@ int32_t CO_CANrxWait(CO_CANmodule_t *CANmodule, int fdTimer, CO_CANrxMsg_t *buff
|
|||
int32_t msgIndex;
|
||||
|
||||
#ifdef CO_DRIVER_ERROR_REPORTING
|
||||
/* clear listenOnly and noackCounter if necessary */
|
||||
CO_CANerror_rxMsg(&interface->errorhandler);
|
||||
#endif
|
||||
|
||||
msgIndex = CO_CANrxMsg(CANmodule, &msg, buffer);
|
||||
if (msgIndex > -1) {
|
||||
#ifdef CO_DRIVER_MULTI_INTERFACE
|
||||
/* Store message info */
|
||||
CANmodule->rxArray[msgIndex].timestamp = timestamp;
|
||||
CANmodule->rxArray[msgIndex].CANptr = CANptr;
|
||||
#endif
|
||||
}
|
||||
retval = msgIndex;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
/**
|
||||
* Linux socketCAN specific definitions for CANopenNode.
|
||||
*
|
||||
* @file CO_driver_target.h
|
||||
* @ingroup CO_socketCAN_driver_target
|
||||
* @author Janez Paternoster
|
||||
* @author Martin Wagner
|
||||
* @copyright 2004 - 2020 Janez Paternoster
|
||||
|
|
@ -25,15 +26,41 @@
|
|||
*/
|
||||
|
||||
|
||||
/* This file contains device and application specific definitions.
|
||||
* It is included from CO_driver.h, which contains documentation
|
||||
* for common definitions below. */
|
||||
|
||||
#ifndef CO_DRIVER_TARGET
|
||||
#define CO_DRIVER_TARGET
|
||||
|
||||
/* This file contains device and application specific definitions.
|
||||
* It is included from CO_driver.h, which contains documentation
|
||||
* for definitions below. */
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <endian.h>
|
||||
#include <pthread.h>
|
||||
#include <linux/can.h>
|
||||
#include <net/if.h>
|
||||
|
||||
/*
|
||||
* @name multi interface support
|
||||
#if __has_include("CO_driver_custom.h")
|
||||
#include "CO_driver_custom.h"
|
||||
#endif
|
||||
#include "CO_notify_pipe.h"
|
||||
#include "CO_error.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup CO_socketCAN_driver_target CO_driver_target.h
|
||||
* @ingroup CO_socketCAN
|
||||
* @{
|
||||
*
|
||||
* 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
|
||||
|
|
@ -51,40 +78,32 @@
|
|||
* This is not intended to realize interface redundancy!!!
|
||||
*/
|
||||
/* #define CO_DRIVER_MULTI_INTERFACE */
|
||||
#ifdef CO_DOXYGEN
|
||||
#define CO_DRIVER_MULTI_INTERFACE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* @name CAN bus error reporting
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* you need to enable error reporting in your kernel driver using
|
||||
* "ip link set canX type can berr-reporting on". Of course, the kernel
|
||||
* driver for your hardware needs this functionality to be implemented...
|
||||
* you need to enable error reporting in your kernel driver using:
|
||||
* @code{.sh}
|
||||
* ip link set canX type can berr-reporting on
|
||||
* @endcode
|
||||
* Of course, the kernel driver for your hardware needs this functionality to be
|
||||
* implemented...
|
||||
*/
|
||||
#ifndef CO_DRIVER_ERROR_REPORTING_DISABLE
|
||||
/* #define CO_DRIVER_ERROR_REPORTING */
|
||||
#ifdef CO_DOXYGEN
|
||||
#define CO_DRIVER_ERROR_REPORTING
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
#include <endian.h>
|
||||
#include <pthread.h>
|
||||
#include <linux/can.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include "CO_notify_pipe.h"
|
||||
#ifdef CO_DRIVER_ERROR_REPORTING
|
||||
#include "CO_error.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* skip this section for Doxygen, because it is documented in CO_driver.h */
|
||||
#ifndef CO_DOXYGEN
|
||||
|
||||
/* Basic definitions */
|
||||
#ifdef __BYTE_ORDER
|
||||
|
|
@ -135,11 +154,9 @@ typedef struct {
|
|||
uint32_t mask;
|
||||
void *object;
|
||||
void (*CANrx_callback)(void *object, void *message);
|
||||
#ifdef CO_DRIVER_MULTI_INTERFACE
|
||||
/* info about last received message */
|
||||
const void *CANptr; /* CAN Interface identifier */
|
||||
struct timespec timestamp; /* time of reception */
|
||||
#endif
|
||||
const void *CANptr; /* CAN Interface identifier from last
|
||||
message */
|
||||
struct timespec timestamp; /* time of reception of last message */
|
||||
} CO_CANrx_t;
|
||||
|
||||
/* Transmit message object as aligned in socketCAN. */
|
||||
|
|
@ -182,7 +199,8 @@ typedef struct {
|
|||
volatile bool_t CANnormal;
|
||||
void *em;
|
||||
CO_NotifyPipe_t *pipe; /* Notification Pipe */
|
||||
int fdEpoll; /* epoll FD */
|
||||
int fdEpoll; /* epoll FD for pipe, CANrx sockets in all
|
||||
interfaces and fdTimerRead */
|
||||
int fdTimerRead; /* timer handle from CANrxWait() */
|
||||
#ifdef CO_DRIVER_MULTI_INTERFACE
|
||||
/* Lookup tables Cob ID to rx/tx array index.
|
||||
|
|
@ -221,9 +239,11 @@ static inline void CO_UNLOCK_OD() {
|
|||
#define CO_FLAG_SET(rxNew) {CO_MemoryBarrier(); rxNew = (void*)1L;}
|
||||
#define CO_FLAG_CLEAR(rxNew) {CO_MemoryBarrier(); rxNew = NULL;}
|
||||
|
||||
#endif /* CO_DOXYGEN */
|
||||
|
||||
|
||||
#ifdef CO_DRIVER_MULTI_INTERFACE
|
||||
/*
|
||||
/**
|
||||
* Add socketCAN interface to can driver
|
||||
*
|
||||
* Function must be called after CO_CANmodule_init.
|
||||
|
|
@ -236,7 +256,7 @@ static inline void CO_UNLOCK_OD() {
|
|||
CO_ReturnError_t CO_CANmodule_addInterface(CO_CANmodule_t *CANmodule,
|
||||
const void *CANptr);
|
||||
|
||||
/*
|
||||
/**
|
||||
* 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
|
||||
|
|
@ -256,7 +276,7 @@ bool_t CO_CANrxBuffer_getInterface(CO_CANmodule_t *CANmodule,
|
|||
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
|
||||
|
|
@ -277,26 +297,33 @@ CO_ReturnError_t CO_CANtxBuffer_setInterface(CO_CANmodule_t *CANmodule,
|
|||
#endif /* CO_DRIVER_MULTI_INTERFACE */
|
||||
|
||||
|
||||
/*
|
||||
* Functions receives CAN messages. It is blocking.
|
||||
/**
|
||||
* Functions receives CAN messages (blocking)
|
||||
*
|
||||
* This function can be used in two ways
|
||||
* - automatic mode (call callback that is set by #CO_CANrxBufferInit() function)
|
||||
* - manual mode (evaluate message filters, return received message)
|
||||
* This function waits for received CAN message, CAN error frame, notification
|
||||
* pipe or fdTimer expiration. In case of CAN message it 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_.
|
||||
*
|
||||
* Both modes can be combined.
|
||||
* 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.
|
||||
* - manual mode: evaluate message filters, return received message
|
||||
*
|
||||
* @param CANmodule This object.
|
||||
* @param fdTimer file descriptor with activated timeout. fd is not read after
|
||||
* expiring! -1 if not used.
|
||||
* @param buffer [out] storage for received message or _NULL_
|
||||
* @retval >= 0 index of received message in array set by #CO_CANmodule_init()
|
||||
* _rxArray_, copy available in _buffer_
|
||||
* @retval -1 no message received
|
||||
* @param fdTimer File descriptor with activated timeout. If set to -1, then
|
||||
* timer will not be used. File descriptor must be read
|
||||
* externally if retval == -1! Read must be nonblocking and
|
||||
* provides number of timer expirations since last read.
|
||||
* @param [out] buffer Storage for received message or _NULL_ if not used.
|
||||
* @retval >= 0 index of received message in array from CO_CANmodule_t
|
||||
* _rxArray_, copy of CAN message is available in _buffer_.
|
||||
* @retval -1 no message received (timer expired or notification pipe or error)
|
||||
*/
|
||||
int32_t CO_CANrxWait(CO_CANmodule_t *CANmodule,
|
||||
int fdTimer,
|
||||
CO_CANrxMsg_t *buffer);
|
||||
int32_t CO_CANrxWait(CO_CANmodule_t* CANmodule, int fdTimer, CO_CANrxMsg_t* buffer);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <linux/can/error.h>
|
||||
|
||||
#include "301/CO_driver.h"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* CANopenNode Linux socketCAN Error handling.
|
||||
*
|
||||
* @file CO_error.h
|
||||
* @ingroup CO_socketCAN
|
||||
* @ingroup CO_socketCAN_ERROR
|
||||
* @author Martin Wagner
|
||||
* @copyright 2018 - 2020 Neuberger Gebaeudeautomation GmbH
|
||||
*
|
||||
|
|
@ -41,11 +41,11 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup CO_socketCAN_ERROR socketCAN_ERROR
|
||||
* @defgroup CO_socketCAN_ERROR CAN errors & Log
|
||||
* @ingroup CO_socketCAN
|
||||
* @{
|
||||
*
|
||||
* CANopen Errors and logging of messages
|
||||
* CANopen Errors and System message log
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
@ -108,9 +108,7 @@ typedef enum {
|
|||
typedef struct {
|
||||
int fd; /**< interface FD */
|
||||
char ifName[IFNAMSIZ]; /**< interface name as string */
|
||||
|
||||
uint32_t noackCounter;
|
||||
|
||||
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 */
|
||||
} CO_CANinterfaceErrorhandler_t;
|
||||
|
|
@ -143,7 +141,8 @@ void CO_CANerror_disable(
|
|||
/**
|
||||
* Message received event
|
||||
*
|
||||
* when a message is received at least one other CAN module is connected
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -154,7 +153,7 @@ void CO_CANerror_rxMsg(
|
|||
/**
|
||||
* Check if interface is ready for message transmission
|
||||
*
|
||||
* message musn't be transmitted if not ready
|
||||
* Message mustn't be transmitted if not ready.
|
||||
*
|
||||
* @param CANerrorhandler CAN error object.
|
||||
* @return CO_INTERFACE_ACTIVE message transmission ready
|
||||
|
|
@ -166,7 +165,7 @@ CO_CANinterfaceState_t CO_CANerror_txMsg(
|
|||
/**
|
||||
* Error message received event
|
||||
*
|
||||
* this handles all received error messages
|
||||
* This handles all received error messages.
|
||||
*
|
||||
* @param CANerrorhandler CAN error object.
|
||||
* @param msg received error message
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* Notify pipe for Linux threads.
|
||||
*
|
||||
* @file CO_notify_pipe.h
|
||||
* @ingroup CO_socketCAN
|
||||
* @ingroup CO_socketCAN_notify_pipe
|
||||
* @author Martin Wagner
|
||||
* @copyright 2017 - 2020 Neuberger Gebaeudeautomation GmbH
|
||||
*
|
||||
|
|
@ -32,7 +32,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup CO_pipe Pipe
|
||||
* @defgroup CO_socketCAN_notify_pipe Notify pipe
|
||||
* @ingroup CO_socketCAN
|
||||
* @{
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in a new issue