iCub-main
Loading...
Searching...
No Matches
driver.h
Go to the documentation of this file.
1
2// -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
3
4/*
5 * Copyright (C) 2008 RobotCub Consortium
6 * Author: Marco Maggiali, Marco Randazzo, Alessandro Scalzo, Marco Accame
7 * CopyPolicy: Released under the terms of the GNU GPL v2.0.
8 *
9 */
10
11#ifndef DRIVER_H
12#define DRIVER_H
13
14
15
16#include <yarp/dev/PolyDriver.h>
17#include <yarp/dev/CanBusInterface.h>
18#include <yarp/os/Searchable.h>
19#include <yarp/os/Time.h>
20#include <yarp/os/Log.h>
21#include <yarp/os/LogStream.h>
22
23#include <ace/ACE.h>
24#include <ace/SOCK_Dgram_Bcast.h>
25#include <ace/Time_Value.h>
26#include <ace/OS_NS_sys_socket.h>
27
28#include "stdint.h"
29
30#include <cstring>
31#include <vector>
32using namespace std;
33
34
35// if defined: it keeps the definition of the legacy driver for backward compatibility use (and tests).
36// if undefined: it removes the code from compilation
37#define DRIVER_KEEP_LEGACY_IDRIVER
38
39
40#define MAX_READ_MSG 64
41#define MAX_WRITE_MSG 8
42
43// - class CanPacket contains a CAN packet as yarp::dev::CanMessage does but with additional info of the canbus.
44// it is used by all interfaces. as such it needs conversion capabilities to/from formats which are specific
45// of the interface.
46
48{
49
50public:
51 enum { everyCANbus = 255 };
52
53private:
54
55 // the complete definition of a can packet
56 typedef struct
57 {
58 int canbus;
59 int id;
60 int len;
61 unsigned char data[8];
62 } CANpkt_t;
63
64 CANpkt_t canpkt;
65
66public:
67 CanPacket(){ canpkt.canbus = 0; canpkt.id = 0; canpkt.len = 0; memset(canpkt.data, 0, sizeof(canpkt.data)); }
69
70
71 CanPacket operator = (const yarp::dev::CanMessage &canmsg)
72 {
73 CanPacket pkt;
74 pkt.canpkt.id = canmsg.getId();
75 pkt.canpkt.len = canmsg.getLen();
76 memcpy(pkt.canpkt.data, canmsg.getData(), sizeof(pkt.canpkt.data));
77
78 return pkt;
79 }
80
81 unsigned int getId() const { return canpkt.id; }
82 unsigned char getLen() const { return canpkt.len; }
83 void setLen(unsigned char len) { canpkt.len=len; }
84 void setId(unsigned int id){ canpkt.id=id; }
85 const unsigned char *getData() const { return canpkt.data; }
86 unsigned char *getData(){ return canpkt.data; }
87 int getCanBus() const { return canpkt.canbus; }
88 void setCanBus(unsigned int bus){ canpkt.canbus=bus; }
89};
90
91
92// - class iDriver2 offers interface to sending and receiving CAN packets over many media.
93// we use vector<CanPacket> ...
95{
96public:
97 typedef enum { can_driver2 = 0, eth_driver2 = 1 } iDriver2Type;
98public:
99 virtual ~iDriver2(){}
100 virtual int init(yarp::os::Searchable &config, bool verbose = true)=0;
101 virtual int uninit()=0;
102 // using legacy rule: canpackets must be of size able to keep howMany messages. however, i put inside the vector up to howmany. returns the numer of read.
103 // much better: howMany keeps the max messages and canpackets can be resized with the read ones.
104 virtual int receive_message(vector<CanPacket> &canpackets, int howMany = MAX_READ_MSG, double TIMEOUT = 1)=0;
105 // using legacy rule: only n are sent. canpackets must be of size able to keep n messages. returns number of sent
106 // much better: remove n and use canpackets.size() instead.
107 virtual int send_message(vector<CanPacket> &canpackets, int n)=0;
108 virtual iDriver2Type type()=0;
109};
110
111
112// - class cDriver2 is the specific class for sending CAN packet with YARP.
113//
114class cDriver2 : public iDriver2
115{
116public:
117 cDriver2();
119 int init(yarp::os::Searchable &config, bool verbose = true);
120 int uninit();
121 int receive_message(vector<CanPacket> &canpackets, int howMany = MAX_READ_MSG, double TIMEOUT = 1);
122 int send_message(vector<CanPacket> &canpackets, int n);
124
125private:
126 yarp::dev::PolyDriver dd;
127 yarp::dev::ICanBus *iCanBus;
128 yarp::dev::ICanBufferFactory *iFactory;
129
130 yarp::dev::CanBuffer canTXbuffer;
131 yarp::dev::CanBuffer canRXbuffer;
132
133 bool _verbose;
134
135private:
136 // used to create buffers for tx/rx with YARP
137 yarp::dev::CanBuffer createCanBuffer(int m);
138 void destroyCanBuffer(yarp::dev::CanBuffer &buff);
139};
140
141
142// - class eDriver2 is the specific class for sending CAN packets over UDP
143//
144
145class CanSocket;
146
147class eDriver2 : public iDriver2
148{
149public:
150 eDriver2();
151 ~eDriver2();
152 int init(yarp::os::Searchable &config, bool verbose = true);
153 int uninit();
154 int receive_message(vector<CanPacket> &canpackets, int howMany = MAX_READ_MSG, double TIMEOUT = 1);
155 int send_message(vector<CanPacket> &canpackets, int n);
157
158 void set_verbose(bool v);
159private:
160 CanSocket *mSocket;
161 ACE_UINT32 mBoardAddr;
162 double timestart;
163 bool _verbose;
164};
165
166
167// - definition of the UDP packet used to transport CAN frames to/from the eUpdater (see specs in TSD-ICUBUNIT-arm-system-behaviour.docx)
168
169// marco.accame
170// actually the use of a progressive id is not in the specs (but does not harm).
171// the data structure used by the eUpdater is defined in eupdater_cangtw.h of icub-firmware. TODO: move it to icub-firmware-shared
172
173#define USE_PROG_ID
174
176{
177 unsigned char signature;
178 unsigned char canFrameNumOf;
179#ifdef USE_PROG_ID
180 ACE_UINT8 dummy[2];
181 ACE_UINT32 progressive;
182#else
183 ACE_UINT8 dummy[6];
184#endif
185};
186
188{
189 unsigned char canBus;
190 unsigned char len;
191 unsigned short canId;
192 unsigned char dummy[4];
193 unsigned char data[8];
194};
195
201
202
203// - class CanSocket
204// it is used to transmit / receive a UDP packet for communication with the eUpdater
205
207{
208public:
210 {
211 ACE_OS::socket_init(2,2);
212 mSocket=NULL;
213 }
214
216 {
217 close();
218 ACE_OS::socket_fini();
219 }
220
221 bool create(ACE_UINT16 port,ACE_UINT32 address)
222 {
223 mSocket=new ACE_SOCK_Dgram_Bcast(ACE_INET_Addr(port,address));
224 return mSocket!=NULL;
225 }
226
227 void sendTo(void* data,size_t len, ACE_UINT16 port, ACE_UINT32 address)
228 {
229 // uncomment until yDebug() for printing
230 //CanPkt_t * pkt = (CanPkt_t*) data;
231 //uint8_t * dd = (uint8_t*)data;
232 //yDebug ("sending UDP pkt of %d bytes to port %d adr %d with data[0] = %d and opc = %x\n", (int) len, port, address, dd[0], pkt->frames[0].data[0]);
233 mSocket->send(data,len,ACE_INET_Addr(port,address));
234 }
235
236 ssize_t receiveFrom(void* data, size_t len, ACE_UINT32 &address, ACE_UINT16 &port, int wait_msec)
237 {
238 ACE_Time_Value tv(wait_msec/1000,(wait_msec%1000)*1000);
239 ACE_INET_Addr ace_addr;
240 ssize_t nrec=mSocket->recv(data,len,ace_addr,0,&tv);
241
242 if (nrec>0)
243 {
244 // uncomment until yDebug() for printing
245 //CanPkt_t * pkt = (CanPkt_t*) data;
246 //yDebug ("received pkt w/ %d bytes. the pkt has opc = %x\n", (int) nrec, pkt->frames[0].data[0]);
247 address=ace_addr.get_ip_address();
248 port=ace_addr.get_port_number();
249 }
250 else
251 {
252 address=0;
253 port=0;
254 }
255
256 return nrec;
257 }
258
259 void close()
260 {
261 if (mSocket)
262 {
263 mSocket->close();
264 delete mSocket;
265 mSocket=NULL;
266 }
267 }
268
269protected:
270 ACE_SOCK_Dgram_Bcast* mSocket;
271};
272
273
274
275// - old classes cDriver and iDriver, kept for backward compatibility in case someone needs them.
276// canLoader and canLoader-console dont use them
277
278#if defined(DRIVER_KEEP_LEGACY_IDRIVER)
279
281{
282public:
283 virtual ~iDriver(){}
284 virtual int init(yarp::os::Searchable &config)=0;
285 virtual int uninit()=0;
286 virtual int receive_message(yarp::dev::CanBuffer &messages, int howMany = MAX_READ_MSG, double TIMEOUT = 1)=0;
287 virtual int send_message(yarp::dev::CanBuffer &message, int n)=0;
288
289 virtual yarp::dev::CanBuffer createBuffer(int m)=0;
290 virtual void destroyBuffer(yarp::dev::CanBuffer &buff)=0;
291};
292
293
294class cDriver : public iDriver
295{
296private:
297 yarp::dev::PolyDriver dd;
298 yarp::dev::ICanBus *iCanBus;
299 yarp::dev::ICanBufferFactory *iFactory;
300public:
301 cDriver();
303 int init(yarp::os::Searchable &config);
304 int uninit();
305 int receive_message(yarp::dev::CanBuffer &messages, int howMany = MAX_READ_MSG, double TIMEOUT = 1);
306 int send_message(yarp::dev::CanBuffer &message, int n);
307
308 yarp::dev::CanBuffer createBuffer(int m);
309 void destroyBuffer(yarp::dev::CanBuffer &buff);
310};
311
312
313struct ECMSG
314{
315 unsigned int canbus;
316 int id;
317 unsigned char data[8];
318 int len;
319};
320
321class EthCanMessage : public yarp::dev::CanMessage
322{
323public:
325
326public:
328 virtual ~EthCanMessage(){}
329
330 virtual CanMessage &operator=(const CanMessage &l)
331 {
332 const EthCanMessage &tmp=dynamic_cast<const EthCanMessage &>(l);
333 memcpy(msg, tmp.msg, sizeof(ECMSG));
334 return *this;
335 }
336
337 virtual unsigned int getId() const { return msg->id; }
338 virtual unsigned char getLen() const { return msg->len; }
339 virtual void setLen(unsigned char len) { msg->len=len; }
340 virtual void setId(unsigned int id){ msg->id=id; }
341 virtual const unsigned char *getData() const { return msg->data; }
342 virtual unsigned char *getData(){ return msg->data; }
343 virtual unsigned char *getPointer(){ return (unsigned char *) msg; }
344 virtual const unsigned char *getPointer() const { return (const unsigned char *) msg; }
345 virtual void setBuffer(unsigned char *b){ if (b) msg=(ECMSG *)(b); }
346 unsigned int getCanBus() const { return msg->canbus; }
347 void setCanBus(unsigned int bus){ msg->canbus=bus; }
348};
349
350
351
352class eDriver : public yarp::dev::ImplementCanBufferFactory<EthCanMessage,ECMSG>, public iDriver
353{
354private:
355 CanSocket mSocket;
356
357 char mCanBusId;
358 ACE_UINT32 mBoardAddr;
359
360 double timestart;
361
362 yarp::dev::ICanBufferFactory *iFactory;
363public:
366
367 int init(yarp::os::Searchable &config);
368 int uninit();
369 int receive_message(yarp::dev::CanBuffer &messages, int howMany = MAX_READ_MSG, double TIMEOUT = 1.0);
370 int send_message(yarp::dev::CanBuffer &message, int n);
371 yarp::dev::CanBuffer createBuffer(int m);
372 void destroyBuffer(yarp::dev::CanBuffer &buff);
373};
374
375#endif//defined(KEEP_LEGACY_DRIVER)
376
377#endif
@ data
unsigned char * getData()
Definition driver.h:86
@ everyCANbus
Definition driver.h:51
unsigned int getId() const
Definition driver.h:81
void setCanBus(unsigned int bus)
Definition driver.h:88
const unsigned char * getData() const
Definition driver.h:85
void setId(unsigned int id)
Definition driver.h:84
~CanPacket()
Definition driver.h:68
unsigned char getLen() const
Definition driver.h:82
CanPacket()
Definition driver.h:67
int getCanBus() const
Definition driver.h:87
void setLen(unsigned char len)
Definition driver.h:83
CanPacket operator=(const yarp::dev::CanMessage &canmsg)
Definition driver.h:71
void close()
Definition driver.h:259
CanSocket()
Definition driver.h:209
bool create(ACE_UINT16 port, ACE_UINT32 address)
Definition driver.h:221
void sendTo(void *data, size_t len, ACE_UINT16 port, ACE_UINT32 address)
Definition driver.h:227
~CanSocket()
Definition driver.h:215
ssize_t receiveFrom(void *data, size_t len, ACE_UINT32 &address, ACE_UINT16 &port, int wait_msec)
Definition driver.h:236
ACE_SOCK_Dgram_Bcast * mSocket
Definition driver.h:270
unsigned int getCanBus() const
Definition driver.h:346
virtual unsigned char getLen() const
Definition driver.h:338
virtual CanMessage & operator=(const CanMessage &l)
Definition driver.h:330
virtual void setId(unsigned int id)
Definition driver.h:340
void setCanBus(unsigned int bus)
Definition driver.h:347
virtual unsigned int getId() const
Definition driver.h:337
virtual unsigned char * getPointer()
Definition driver.h:343
virtual ~EthCanMessage()
Definition driver.h:328
virtual const unsigned char * getPointer() const
Definition driver.h:344
virtual void setLen(unsigned char len)
Definition driver.h:339
virtual const unsigned char * getData() const
Definition driver.h:341
ECMSG * msg
Definition driver.h:324
virtual void setBuffer(unsigned char *b)
Definition driver.h:345
virtual unsigned char * getData()
Definition driver.h:342
iDriver2Type type()
Definition driver.h:123
int receive_message(vector< CanPacket > &canpackets, int howMany=MAX_READ_MSG, double TIMEOUT=1)
Definition driver.cpp:75
int init(yarp::os::Searchable &config, bool verbose=true)
Definition driver.cpp:29
int send_message(vector< CanPacket > &canpackets, int n)
Definition driver.cpp:138
~cDriver2()
Definition driver.h:118
cDriver2()
Definition driver.cpp:23
int uninit()
Definition driver.cpp:64
int receive_message(yarp::dev::CanBuffer &messages, int howMany=MAX_READ_MSG, double TIMEOUT=1)
Definition driver.cpp:525
int send_message(yarp::dev::CanBuffer &message, int n)
Definition driver.cpp:580
~cDriver()
Definition driver.h:302
int init(yarp::os::Searchable &config)
Definition driver.cpp:490
cDriver()
Definition driver.cpp:485
void destroyBuffer(yarp::dev::CanBuffer &buff)
Definition driver.cpp:599
int uninit()
Definition driver.cpp:518
yarp::dev::CanBuffer createBuffer(int m)
Definition driver.cpp:593
int init(yarp::os::Searchable &config, bool verbose=true)
Definition driver.cpp:206
int uninit()
Definition driver.cpp:366
void set_verbose(bool v)
int receive_message(vector< CanPacket > &canpackets, int howMany=MAX_READ_MSG, double TIMEOUT=1)
Definition driver.cpp:378
~eDriver2()
Definition driver.cpp:199
int send_message(vector< CanPacket > &canpackets, int n)
Definition driver.cpp:429
iDriver2Type type()
Definition driver.h:156
int init(yarp::os::Searchable &config)
Definition driver.cpp:609
void destroyBuffer(yarp::dev::CanBuffer &buff)
Definition driver.cpp:755
eDriver()
Definition driver.h:364
int receive_message(yarp::dev::CanBuffer &messages, int howMany=MAX_READ_MSG, double TIMEOUT=1.0)
Definition driver.cpp:670
int send_message(yarp::dev::CanBuffer &message, int n)
Definition driver.cpp:714
yarp::dev::CanBuffer createBuffer(int m)
Definition driver.cpp:750
int uninit()
Definition driver.cpp:659
~eDriver()
Definition driver.h:365
virtual int uninit()=0
iDriver2Type
Definition driver.h:97
@ can_driver2
Definition driver.h:97
@ eth_driver2
Definition driver.h:97
virtual int send_message(vector< CanPacket > &canpackets, int n)=0
virtual iDriver2Type type()=0
virtual ~iDriver2()
Definition driver.h:99
virtual int init(yarp::os::Searchable &config, bool verbose=true)=0
virtual int receive_message(vector< CanPacket > &canpackets, int howMany=MAX_READ_MSG, double TIMEOUT=1)=0
virtual void destroyBuffer(yarp::dev::CanBuffer &buff)=0
virtual int uninit()=0
virtual ~iDriver()
Definition driver.h:283
virtual int send_message(yarp::dev::CanBuffer &message, int n)=0
virtual yarp::dev::CanBuffer createBuffer(int m)=0
virtual int init(yarp::os::Searchable &config)=0
virtual int receive_message(yarp::dev::CanBuffer &messages, int howMany=MAX_READ_MSG, double TIMEOUT=1)=0
int n
#define MAX_READ_MSG
Definition driver.h:40
unsigned char dummy[4]
Definition driver.h:192
unsigned short canId
Definition driver.h:191
unsigned char canBus
Definition driver.h:189
unsigned char len
Definition driver.h:190
unsigned char data[8]
Definition driver.h:193
unsigned char signature
Definition driver.h:177
ACE_UINT8 dummy[2]
Definition driver.h:180
ACE_UINT32 progressive
Definition driver.h:181
unsigned char canFrameNumOf
Definition driver.h:178
CanPktFrame_t frames[1]
Definition driver.h:199
CanPktHeader_t header
Definition driver.h:198
int len
Definition driver.h:318
unsigned int canbus
Definition driver.h:315
int id
Definition driver.h:316
unsigned char data[8]
Definition driver.h:317