-
-
Notifications
You must be signed in to change notification settings - Fork 52
/
CO_error.h
163 lines (145 loc) · 4.94 KB
/
CO_error.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/**
* CANopenNode Linux socketCAN Error handling.
*
* @file CO_error.h
* @ingroup CO_socketCAN_ERROR
* @author Martin Wagner
* @copyright 2018 - 2020 Neuberger Gebaeudeautomation GmbH
*
*
* This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
*
* 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_ERROR_H
#define CO_ERROR_H
#include <stdint.h>
#include <errno.h>
#include <string.h>
#include <linux/can.h>
#include <net/if.h>
#if __has_include("CO_error_custom.h")
#include "CO_error_custom.h"
#else
#include "CO_error_msgs.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup CO_socketCAN_ERROR CAN errors & Log
* CANopen Errors and System message log
*
* @ingroup CO_socketCAN
* @{
*/
/**
* 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.
*
* 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);
* @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, ...);
/**
* driver interface state
*
* CAN hardware can be in the followning states:
* - error active (OK)
* - error passive (Can't generate error flags)
* - 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_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
*/
#define CO_CANerror_NOACK_MAX 16
/**
* 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 */
} CO_CANinterfaceErrorhandler_t;
/**
* Initialize CAN error handler
*
* We need one error handler per interface
*
* @param CANerrorhandler This object will be initialized.
* @param fd interface file descriptor
* @param ifname interface name as string
*/
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);
/**
* Message received event
*
* 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);
/**
* Check if interface is ready for message transmission
*
* Message mustn't be transmitted if not ready.
*
* @param CANerrorhandler CAN error object.
* @return CO_INTERFACE_ACTIVE message transmission ready
*/
CO_CANinterfaceState_t CO_CANerror_txMsg(CO_CANinterfaceErrorhandler_t* CANerrorhandler);
/**
* Error message received event
*
* This handles all received error messages.
*
* @param CANerrorhandler CAN error object.
* @param msg received error message
* @return #CO_CANinterfaceState_t
*/
CO_CANinterfaceState_t CO_CANerror_rxMsgError(CO_CANinterfaceErrorhandler_t* CANerrorhandler,
const struct can_frame* msg);
/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* CO_ERROR_H */