iCub-main
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>
32 using 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 
47 class CanPacket
48 {
49 
50 public:
51  enum { everyCANbus = 255 };
52 
53 private:
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 
66 public:
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> ...
94 class iDriver2
95 {
96 public:
97  typedef enum { can_driver2 = 0, eth_driver2 = 1 } iDriver2Type;
98 public:
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 //
114 class cDriver2 : public iDriver2
115 {
116 public:
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);
123  iDriver2Type type() { return can_driver2; }
124 
125 private:
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 
135 private:
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 
145 class CanSocket;
146 
147 class eDriver2 : public iDriver2
148 {
149 public:
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);
156  iDriver2Type type() { return eth_driver2; }
157 
158  void set_verbose(bool v);
159 private:
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 
196 struct CanPkt_t
197 {
199  CanPktFrame_t frames[1];
200 };
201 
202 
203 // - class CanSocket
204 // it is used to transmit / receive a UDP packet for communication with the eUpdater
205 
207 {
208 public:
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 
269 protected:
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 
280 class iDriver
281 {
282 public:
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 
294 class cDriver : public iDriver
295 {
296 private:
297  yarp::dev::PolyDriver dd;
298  yarp::dev::ICanBus *iCanBus;
299  yarp::dev::ICanBufferFactory *iFactory;
300 public:
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 
313 struct ECMSG
314 {
315  unsigned int canbus;
316  int id;
317  unsigned char data[8];
318  int len;
319 };
320 
321 class EthCanMessage : public yarp::dev::CanMessage
322 {
323 public:
325 
326 public:
327  EthCanMessage(){ msg=0; }
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 
352 class eDriver : public yarp::dev::ImplementCanBufferFactory<EthCanMessage,ECMSG>, public iDriver
353 {
354 private:
355  CanSocket mSocket;
356 
357  char mCanBusId;
358  ACE_UINT32 mBoardAddr;
359 
360  double timestart;
361 
362  yarp::dev::ICanBufferFactory *iFactory;
363 public:
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 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
unsigned char * getData()
Definition: driver.h:86
void setLen(unsigned char len)
Definition: driver.h:83
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 const unsigned char * getData() const
Definition: driver.h:341
virtual unsigned char getLen() const
Definition: driver.h:338
virtual void setId(unsigned int id)
Definition: driver.h:340
virtual unsigned char * getData()
Definition: driver.h:342
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 CanMessage & operator=(const CanMessage &l)
Definition: driver.h:330
virtual void setLen(unsigned char len)
Definition: driver.h:339
ECMSG * msg
Definition: driver.h:324
virtual void setBuffer(unsigned char *b)
Definition: driver.h:345
virtual const unsigned char * getPointer() const
Definition: driver.h:344
EthCanMessage()
Definition: driver.h:327
iDriver2Type type()
Definition: driver.h:123
~cDriver2()
Definition: driver.h:118
~cDriver()
Definition: driver.h:302
void set_verbose(bool v)
iDriver2Type type()
Definition: driver.h:156
eDriver()
Definition: driver.h:364
~eDriver()
Definition: driver.h:365
virtual int uninit()=0
iDriver2Type
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 short canId
Definition: driver.h:191
unsigned char canBus
Definition: driver.h:189
unsigned char len
Definition: driver.h:190
unsigned char signature
Definition: driver.h:177
ACE_UINT32 progressive
Definition: driver.h:181
unsigned char canFrameNumOf
Definition: driver.h:178
CanPktHeader_t header
Definition: driver.h:198
Definition: driver.h:314
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