blmc_drivers
os_interface.hpp
Go to the documentation of this file.
1 
13 #pragma once
14 
18 #ifdef __XENO__
19 
20 #include <native/task.h>
21 #include <native/timer.h>
22 #include <native/mutex.h>
23 #include <native/cond.h>
24 #include <rtdk.h>
25 #include <rtdm/rtcan.h>
26 
30 #else
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <stdint.h>
36 #include <string.h>
37 
38 #include <net/if.h>
39 #include <sys/types.h>
40 #include <sys/socket.h>
41 #include <sys/ioctl.h>
42 
43 #include <linux/can.h>
44 #include <linux/can/raw.h>
45 
46 #include <limits.h>
47 
48 #include <real_time_tools/timer.hpp>
49 
50 #include <iostream>
51 
59 typedef struct can_frame can_frame_t;
63 typedef canid_t can_id_t;
67 typedef uint64_t nanosecs_abs_t;
68 
72 #define rt_fprintf fprintf
73 
76 #define rt_printf printf
77 
81 #define rt_dev_socket socket
82 
85 #define rt_dev_ioctl ioctl
86 
89 #define rt_dev_close close
90 
93 #define rt_dev_setsockopt setsockopt
94 
97 #define rt_dev_bind bind
98 
101 #define rt_dev_recvmsg recvmsg
102 
105 #define rt_dev_sendto sendto
106 
110 #endif
111 
112 #include <sstream>
113 #include <mutex>
114 #include <condition_variable>
115 
116 #include <sys/mman.h>
117 
123 namespace osi
124 {
125 
126 #ifdef __XENO__
127 
131 namespace xenomai
132 {
137 class mutex
138 {
139 public:
143  RT_MUTEX rt_mutex_;
144 
148  mutex()
149  {
150  rt_mutex_create(&rt_mutex_, NULL);
151  }
152 
156  void lock()
157  {
158  rt_mutex_acquire(&rt_mutex_, TM_INFINITE);
159  }
160 
164  void unlock()
165  {
166  rt_mutex_release(&rt_mutex_);
167  }
168 };
169 
173 class condition_variable
174 {
175 public:
179  RT_COND rt_condition_variable_;
180 
184  condition_variable()
185  {
186  rt_cond_create(&rt_condition_variable_, NULL);
187  }
188 
194  void wait(std::unique_lock<mutex> &lock)
195  {
196  rt_cond_wait(&rt_condition_variable_,
197  &lock.mutex()->rt_mutex_, TM_INFINITE);
198  }
199 
203  void notify_all()
204  {
205  rt_cond_broadcast(&rt_condition_variable_);
206  }
207 };
208 } // namespace xenomai
212 typedef xenomai::mutex Mutex;
213 
218 typedef xenomai::condition_variable ConditionVariable;
219 
220 #else
221 
224 typedef std::mutex Mutex;
225 
230 typedef std::condition_variable ConditionVariable;
231 #endif
232 
243 inline void send_to_can_device(int fd, const void *buf, size_t len,
244  int flags, const struct sockaddr *to,
245  socklen_t tolen)
246 {
247  // int ret = rt_dev_sendto(fd, buf, len, flags, to, tolen);
248 
249  // if (ret < 0)
250  // {
251  // std::ostringstream oss;
252  // oss << "something went wrong with sending "
253  // << "CAN frame, error code: "
254  // << ret << ", errno=" << errno << std::endl;
255  // throw std::runtime_error(oss.str());
256  // }
257 
258  for (size_t i = 0; true; i++)
259  {
260  int ret = rt_dev_sendto(fd, buf, len, flags, to, tolen);
261  if (ret >= 0)
262  {
263  if (i > 0)
264  {
265  std::cout << " Managed to send after "
266  << i << " attempts." << std::endl;
267  }
268  return;
269  }
270 
271  if (i == 0)
272  {
273  std::cout << "WARNING: Something went wrong with sending "
274  << "CAN frame, error code: "
275  << ret << ", errno: " << errno << ". Possibly you have "
276  << "been attempting to send at a rate which is too "
277  << "high. We keep trying" << std::flush;
278  }
279 
281  }
282 }
283 
290 inline void close_can_device(int socket)
291 {
292  int ret = rt_dev_close(socket);
293  if (ret)
294  {
295  rt_fprintf(stderr, "rt_dev_close: %s\n", strerror(-ret));
296  exit(-1);
297  }
298 }
299 
308 inline void receive_message_from_can_device(int fd, struct msghdr *msg, int flags)
309 {
310  int ret = rt_dev_recvmsg(fd, msg, flags);
311  if (ret < 0)
312  {
313  std::ostringstream oss;
314  oss << "something went wrong with receiving "
315  << "CAN frame, error code: "
316  << ret << ", errno=" << errno << std::endl;
317  throw std::runtime_error(oss.str());
318  }
319 }
320 
326 {
327 #ifdef __XENO__
328  rt_print_auto_init(1);
329 #endif
330 }
331 
337 inline void sleep_ms(const double &sleep_time_ms)
338 {
339 #ifdef __XENO__
340  rt_task_sleep(int(sleep_time_ms * 1000000.));
341 #else
342  usleep(sleep_time_ms * 1000.); // nano_sleep
343 #endif
344 }
345 
352 inline double get_current_time_ms()
353 {
354 #ifdef __XENO__
355  return double(rt_timer_read()) / 1000000.;
356 #else
357  struct timespec now;
358  clock_gettime(CLOCK_REALTIME, &now);
359  double current_time_ms = (double)(now.tv_sec * 1e3) + (now.tv_nsec / 1e6);
360 
361  return current_time_ms;
362 #endif
363 }
364 
369 {
370 #ifdef __XENO__
371 
372  rt_task_shadow(NULL, NULL, 0, 0);
373 #endif
374 }
375 
376 } // namespace osi
std::mutex Mutex
Wrapper around the posix specific Mutex implementation.
Definition: os_interface.hpp:224
struct can_frame can_frame_t
xeno specific include
Definition: os_interface.hpp:59
void make_this_thread_realtime()
This methd is requiered in xenomai to create a real time thread.
Definition: os_interface.hpp:368
void sleep_ms(const double &sleep_time_ms)
This function uses eather the xenomai API or the posix one.
Definition: os_interface.hpp:337
canid_t can_id_t
Create a common type_def to wrap xenomai and posix.
Definition: os_interface.hpp:63
double get_current_time_ms()
Get the current time in millisecond.
Definition: os_interface.hpp:352
#define rt_fprintf
Create a common type_def to wrap xenomai and posix.
Definition: os_interface.hpp:72
#define rt_dev_close
Create a common type_def to wrap xenomai and posix.
Definition: os_interface.hpp:89
Common include.
Definition: os_interface.hpp:123
std::condition_variable ConditionVariable
Wrapper around the posix specific ConditionVariable implementation.
Definition: os_interface.hpp:230
void close_can_device(int socket)
This function is closing a socket on the Can device.
Definition: os_interface.hpp:290
#define rt_dev_recvmsg
Create a common type_def to wrap xenomai and posix.
Definition: os_interface.hpp:101
#define rt_dev_sendto
Create a common type_def to wrap xenomai and posix.
Definition: os_interface.hpp:105
uint64_t nanosecs_abs_t
Create a common type_def to wrap xenomai and posix.
Definition: os_interface.hpp:67
void send_to_can_device(int fd, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
Use the osi workspace API to communicate with the can bus.
Definition: os_interface.hpp:243
void receive_message_from_can_device(int fd, struct msghdr *msg, int flags)
Poll? a message from the CAN device.
Definition: os_interface.hpp:308
void initialize_realtime_printing()
This function is needed in xenomai to initialize the real time console display of text...
Definition: os_interface.hpp:325