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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
|
/*
* Copyright (C) 2015, 2016 "IoT.bzh"
* Author "Romain Forlot" <romain.forlot@iot.bzh>
*
* 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.
*/
#pragma once
#include <vector>
#include <string>
#include <cstdint>
#include <linux/can.h>
#include "timer.hpp"
#define CAN_MESSAGE_SIZE 8
/**
* @enum CanMessageFormat
* @brief The ID format for a CAN message.
*/
enum CanMessageFormat {
STANDARD, /*!< STANDARD - standard 11-bit CAN arbitration ID. */
EXTENDED, /*!< EXTENDED - an extended frame, with a 29-bit arbitration ID. */
ERROR, /*!< ERROR - ERROR code used at initialization to signify that it isn't usable'*/
};
typedef enum CanMessageFormat CanMessageFormat;
/**
* @class can_message_t
*
* @brief A compact representation of a single CAN message, meant to be used in in/out
* buffers.
*/
/*************************
* old CanMessage struct *
*************************
struct CanMessage {
uint32_t id;
CanMessageFormat format;
uint8_t data[CAN_MESSAGE_SIZE];
uint8_t length;
};
typedef struct CanMessage CanMessage;
*/
class can_message_t {
private:
uint32_t id_; /*!< uint32_t id - The ID of the message. */
bool rtr_flag_; /*!< bool rtr_flag - Telling if the frame has RTR flag positionned. Then frame hasn't data field*/
uint8_t length_; /*!< uint8_t length - the length of the data array (max 8). */
uint8_t flags_; /*!< unint8_t flags of a CAN FD frame. Needed if we catch FD frames.*/
CanMessageFormat format_; /*!< CanMessageFormat format - the format of the message's ID.*/
std::vector<uint8_t> data_; /*!< uint8_t data - The message's data field with a size of 8 which is the standard about CAN bus messages.*/
uint8_t maxdlen_;
public:
/**
* @brief Class constructor
*
* Constructor about can_message_t class.
*/
can_message_t();
/**
* @brief Retrieve id_ member value.
*
* @return uint32_t id_ class member
*/
uint32_t get_id() const;
/**
* @brief Retrieve RTR flag member.
*
* @return bool rtr_flags_ class member
*/
bool get_rtr_flag_() const;
/**
* @brief Retrieve format_ member value.
*
* @return CanMessageFormat format_ class member
*/
int get_format() const;
/**
* @brief Retrieve format_ member value.
*
* @return CanMessageFormat format_ class member
*/
uint8_t get_flags() const;
/**
* @brief Retrieve data_ member value.
*
* @return uint8_t data_ pointer to the first element
* of class member data_
*/
const uint8_t* get_data() const;
/**
* @brief Retrieve length_ member value.
*
* @return uint8_t length_ class member
*/
uint8_t get_length() const;
void set_max_data_length(const struct canfd_frame& frame);
/**
* @brief Control whether the object is correctly initialized
* to be sent over the CAN bus
*
* @return true if object correctly initialized and false if not...
*/
bool is_correct_to_send();
/**
* @brief Set id_ member value.
*
* Preferred way to initialize these members by using
* convert_from_canfd_frame method.
*
* @param uint32_t id_ class member
*/
void set_id_and_format(const uint32_t new_id);
/**
* @brief Set format_ member value.
*
* Preferred way to initialize these members by using
* convert_from_canfd_frame method.
*
* @param CanMessageFormat format_ class member
*/
void set_format(const CanMessageFormat new_format);
/**
* @brief Set format_ member value. Deducing from the can_id
* of a canfd_frame.
*
* Preferred way to initialize these members by using
* convert_from_canfd_frame method.
*
* @param uint32_t can_id integer from a canfd_frame
*/
void set_format(const uint32_t can_id);
/**
* @brief Set format_ member value.
*
* Preferred way to initialize these members by using
* convert_from_canfd_frame method.
*
* @param CanMessageFormat format_ class member
*/
void set_flags(const uint8_t flags);
/**
* @brief Set data_ member value.
*
* Preferred way to initialize these members by using
* convert_from_canfd_frame method.
*
* @param uint8_t data_ array with a max size of 8 elements.
*/
void set_data(const __u8 new_data[], size_t dlen);
/**
* @brief Set length_ member value.
*
* Preferred way to initialize these members by using
* convert_from_canfd_frame method.
*
* @param uint8_t length_ array with a max size of 8 elements.
*/
void set_length(const uint8_t new_length);
/**
* @brief Take a canfd_frame struct to initialize class members
*
* This is the preferred way to initialize class members.
*
* @param canfd_frame struct read from can bus device.
*/
void convert_from_canfd_frame(const struct canfd_frame& frame);
/**
* @brief Take all initialized class's members and build an
* canfd_frame struct that can be use to send a CAN message over
* the bus.
*
* @return canfd_frame struct built from class members.
*/
canfd_frame convert_to_canfd_frame();
};
/**
* @struct CanMessageDefinition
*
* @brief The definition of a CAN message. This includes a lot of metadata, so
* to save memory this struct should not be used for storing incoming and
* outgoing CAN messages.
*/
struct CanMessageDefinition {
//can_bus_dev_t bus; /*!< bus - A pointer to the bus this message is on. */
uint32_t id; /*!< id - The ID of the message.*/
CanMessageFormat format; /*!< format - the format of the message's ID.*/
FrequencyClock frequencyClock; /*!< clock - an optional frequency clock to control the output of this
* message, if sent raw, or simply to mark the max frequency for custom
* handlers to retriec++ if ? syntaxve.*/
bool forceSendChanged; /*!< forceSendChanged - If true, regardless of the frequency, it will send CAN
* message if it has changed when using raw passthrough.*/
uint8_t lastValue[CAN_MESSAGE_SIZE]; /*!< lastValue - The last received value of the message. Defaults to undefined.
* This is required for the forceSendChanged functionality, as the stack
* needs to compare an incoming CAN message with the previous frame.*/
};
typedef struct CanMessageDefinition CanMessageDefinition;
/**
* @struct CanMessageSet
*
* @brief A parent wrapper for a particular set of CAN messages and associated
* CAN buses(e.g. a vehicle or program).
*/
typedef struct {
uint8_t index; /*!<index - A numerical ID for the message set, ideally the index in an array
* for fast lookup*/
const std::string name; /*!< name - The name of the message set.*/
uint8_t busCount; /*!< busCount - The number of CAN buses defined for this message set.*/
unsigned short messageCount; /*!< messageCount - The number of CAN messages (across all buses) defined for
* this message set.*/
unsigned short signalCount; /*!< signalCount - The number of CAN signals (across all messages) defined for
* this message set.*/
unsigned short commandCount; /*!< commandCount - The number of CanCommmands defined for this message set.*/
} CanMessageSet;
/** Public: Return the currently active CAN configuration. */
CanMessageSet* getActiveMessageSet();
/** Public: Retrive a list of all possible CAN configurations.
*
* Returns a pointer to an array of all configurations.
*/
CanMessageSet* getMessageSets();
/** Public: Return the length of the array returned by getMessageSets() */
int getMessageSetCount();
/* Public: Return an array of all CAN messages to be processed in the active
* configuration.
*/
CanMessageDefinition* getMessages();
/* Public: Return the length of the array returned by getMessages(). */
int getMessageCount();
|