Orocos Real-Time Toolkit  2.8.3
fosi.h
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Wed Jan 18 14:11:39 CET 2006 fosi.h
3 
4  fosi.h - description
5  -------------------
6  begin : Wed January 18 2006
7  copyright : (C) 2006 Peter Soetens
8  email : peter.soetens@mech.kuleuven.be
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * Lesser General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 
39 #ifndef _XENO_FOSI_H
40 #define _XENO_FOSI_H
41 
42 #ifndef _XOPEN_SOURCE
43 #define _XOPEN_SOURCE 600 // use all Posix features.
44 #endif
45 
46 #define HAVE_FOSI_API
47 
48 #ifdef __cplusplus
49 extern "C" {
50 #endif
51 
52 #include "../../rtt-config.h"
53 
54  //Xenomai headers
55  //#include <linux/types.h>
56  // xenomai assumes presence of u_long
57 #ifndef _GNU_SOURCE
58 #define _GNU_SOURCE
59 #endif
60 #include <sys/mman.h>
61 #include <sys/time.h>
62 #include <unistd.h>
63 #include <stdlib.h>
64 #include <math.h>
65 #include <stdio.h>
66 #include <stdarg.h>
67 #include <string.h>
68 #include <signal.h>
69 #include <getopt.h>
70 #include <time.h>
71 #include <limits.h>
72 #include <float.h>
73 #include "../oro_limits.h"
74 
75 #include <xeno_config.h> // version number
76 #include <native/task.h>
77 #include <native/timer.h>
78 #include <native/mutex.h>
79 #include <native/sem.h>
80 #include <native/cond.h>
81 
82 // BC: support Xenomai < 2.3.0
83 #if ((CONFIG_XENO_VERSION_MAJOR*1000)+(CONFIG_XENO_VERSION_MINOR*100)+CONFIG_XENO_REVISION_LEVEL) < 2300
84 #define rt_mutex_acquire rt_mutex_lock
85 #define rt_mutex_release rt_mutex_unlock
86 #endif
87 // BC: support Xenomai < 2.5.0
88 #if ((CONFIG_XENO_VERSION_MAJOR*1000)+(CONFIG_XENO_VERSION_MINOR*100)+CONFIG_XENO_REVISION_LEVEL) >= 2500
89 #define ORO_XENO_HAS_ACQUIRE_UNTIL
90 #endif
91 
92 
93  typedef RT_MUTEX rt_mutex_t;
94  typedef RT_MUTEX rt_rec_mutex_t;
95  typedef RT_SEM rt_sem_t;
96  typedef RT_COND rt_cond_t;
97 
98  // Time Related
99  // 'S' -> Signed long long
100  typedef SRTIME NANO_TIME;
101  typedef SRTIME TICK_TIME;
102  typedef struct timespec TIME_SPEC;
103  typedef RT_TASK RTOS_XENO_TASK;
104 
105  // Thread/Task related.
106  typedef struct {
107  char * name;
108  RTOS_XENO_TASK xenotask;
109  RTOS_XENO_TASK* xenoptr;
110  int sched_type;
111  } RTOS_TASK;
112 
113  static const TICK_TIME InfiniteTicks = LONG_LONG_MAX;
114  static const NANO_TIME InfiniteNSecs = LONG_LONG_MAX;
115  static const double InfiniteSeconds = DBL_MAX;
116 
117 #define SCHED_XENOMAI_HARD 0
118 #define SCHED_XENOMAI_SOFT 1
119 #define ORO_SCHED_RT 0
120 #define ORO_SCHED_OTHER 1
122 #define ORO_WAIT_ABS 0
123 #define ORO_WAIT_REL 1
125  // hrt is in ticks
126 static inline TIME_SPEC ticks2timespec(TICK_TIME hrt)
127 {
128  TIME_SPEC timevl;
129  timevl.tv_sec = rt_timer_tsc2ns(hrt) / 1000000000LL;
130  timevl.tv_nsec = rt_timer_tsc2ns(hrt) % 1000000000LL;
131  return timevl;
132 }
133 
134  // hrt is in ticks
135 static inline TICK_TIME timespec2ticks(const TIME_SPEC* ts)
136 {
137  return rt_timer_ns2tsc(ts->tv_nsec + ts->tv_sec*1000000000LL);
138 }
139 
140 // turn this on to have maximum detection of valid system calls.
141 #ifdef OROSEM_OS_XENO_CHECK
142 #define CHK_XENO_CALL() do { if(rt_task_self() == 0) { \
143  printf("RTT: XENO NOT INITIALISED IN THIS THREAD pid=%d,\n\
144  BUT TRIES TO INVOKE XENO FUNCTION >>%s<< ANYWAY\n", getpid(), __FUNCTION__ );\
145  assert( rt_task_self() != 0 ); }\
146  } while(0)
147 #define CHK_XENO_PTR(ptr) do { if(ptr == 0) { \
148  printf("RTT: TRIED TO PASS NULL POINTER TO XENO IN THREAD pid=%d,\n\
149  IN TRYING TO INVOKE XENO FUNCTION >>%s<<\n", getpid(), __FUNCTION__ );\
150  assert( ptr != 0 ); }\
151  } while(0)
152 #else
153 #define CHK_XENO_CALL()
154 #define CHK_XENO_PTR( a )
155 #endif
156 
157 static inline NANO_TIME rtos_get_time_ns(void) { return rt_timer_ticks2ns(rt_timer_read()); }
158 
159 static inline TICK_TIME rtos_get_time_ticks(void) { return rt_timer_tsc(); }
160 
161 static inline TICK_TIME ticksPerSec(void) { return rt_timer_ns2tsc( 1000 * 1000 * 1000 ); }
162 
163 // WARNING: Orocos 'ticks' are 'Xenomai tsc' and Xenomai `ticks' are not
164 // used in the Orocos API. Thus Orocos uses `Xenomai tsc' and `Xenomai ns',
165 // yet Xenomai requires `Xenomai ticks' at the interface
166 // ==> do not use nano2ticks to convert to `Xenomai ticks' because it
167 // converts to `Xenomai tsc'.
168 static inline TICK_TIME nano2ticks(NANO_TIME t) { return rt_timer_ns2tsc(t); }
169 static inline NANO_TIME ticks2nano(TICK_TIME t) { return rt_timer_tsc2ns(t); }
170 
171 static inline int rtos_nanosleep(const TIME_SPEC *rqtp, TIME_SPEC *rmtp)
172  {
173  CHK_XENO_CALL();
174  RTIME ticks = rqtp->tv_sec * 1000000000LL + rqtp->tv_nsec;
175  rt_task_sleep( rt_timer_ns2ticks(ticks) );
176  return 0;
177  }
178 
179  static inline int rtos_sem_init(rt_sem_t* m, int value )
180  {
181  CHK_XENO_CALL();
182  return rt_sem_create( m, 0, value, S_PRIO);
183  }
184 
185  static inline int rtos_sem_destroy(rt_sem_t* m )
186  {
187  CHK_XENO_CALL();
188  return rt_sem_delete( m );
189  }
190 
191  static inline int rtos_sem_signal(rt_sem_t* m )
192  {
193  CHK_XENO_CALL();
194  return rt_sem_v( m );
195  }
196 
197  static inline int rtos_sem_wait(rt_sem_t* m )
198  {
199  CHK_XENO_CALL();
200  return rt_sem_p( m, TM_INFINITE );
201  }
202 
203  static inline int rtos_sem_trywait(rt_sem_t* m )
204  {
205  CHK_XENO_CALL();
206  return rt_sem_p( m, TM_NONBLOCK);
207  }
208 
209  static inline int rtos_sem_value(rt_sem_t* m )
210  {
211  CHK_XENO_CALL();
212  RT_SEM_INFO sinfo;
213  if (rt_sem_inquire(m, &sinfo) == 0 ) {
214  return sinfo.count;
215  }
216  return -1;
217  }
218 
219  static inline int rtos_sem_wait_timed(rt_sem_t* m, NANO_TIME delay )
220  {
221  CHK_XENO_CALL();
222  return rt_sem_p(m, rt_timer_ns2ticks(delay) ) == 0 ? 0 : -1;
223  }
224 
225  static inline int rtos_sem_wait_until(rt_sem_t* m, NANO_TIME when )
226  {
227  CHK_XENO_CALL();
228  return rt_sem_p(m, rt_timer_ns2ticks(when) - rt_timer_read() ) == 0 ? 0 : -1;
229  }
230 
231  static inline int rtos_mutex_init(rt_mutex_t* m)
232  {
233  CHK_XENO_CALL();
234  // a Xenomai mutex is always recursive
235  return rt_mutex_create(m, 0);
236  }
237 
238  static inline int rtos_mutex_destroy(rt_mutex_t* m )
239  {
240  CHK_XENO_CALL();
241  return rt_mutex_delete(m);
242  }
243 
244  static inline int rtos_mutex_rec_init(rt_rec_mutex_t* m)
245  {
246  CHK_XENO_CALL();
247  // a Xenomai mutex is always recursive
248  return rt_mutex_create(m, 0);
249  }
250 
251  static inline int rtos_mutex_rec_destroy(rt_rec_mutex_t* m )
252  {
253  CHK_XENO_CALL();
254  return rt_mutex_delete(m);
255  }
256 
257  static inline int rtos_mutex_lock( rt_mutex_t* m)
258  {
259  CHK_XENO_CALL();
260  return rt_mutex_acquire(m, TM_INFINITE );
261  }
262 
263  static inline int rtos_mutex_trylock( rt_mutex_t* m)
264  {
265  CHK_XENO_CALL();
266  struct rt_mutex_info info;
267  rt_mutex_inquire(m, &info );
268 #if ((CONFIG_XENO_VERSION_MAJOR*1000)+(CONFIG_XENO_VERSION_MINOR*100)+CONFIG_XENO_REVISION_LEVEL) >= 2500
269  if (info.locked)
270  return 0;
271 #else
272  if (info.lockcnt)
273  return 0;
274 #endif
275  // from here on: we're sure our thread didn't lock it
276  // now check if any other thread locked it:
277  return rt_mutex_acquire(m, TM_NONBLOCK);
278  }
279 
280  static inline int rtos_mutex_lock_until( rt_mutex_t* m, NANO_TIME abs_time)
281  {
282  CHK_XENO_CALL();
283 #if !defined(ORO_XENO_HAS_ACQUIRE_UNTIL) // see top of this file
284  // calling the old style API
285  return rt_mutex_acquire(m, rt_timer_ns2ticks(abs_time) - rt_timer_read() );
286 #else
287  // new style API > 2.5.0
288  return rt_mutex_acquire_until(m, rt_timer_ns2ticks(abs_time) );
289 #endif
290  }
291 
292  static inline int rtos_mutex_trylock_for( rt_mutex_t* m, NANO_TIME relative_time)
293  {
294  CHK_XENO_CALL();
295  return rt_mutex_acquire(m, rt_timer_ns2ticks(relative_time) );
296  }
297 
298  static inline int rtos_mutex_unlock( rt_mutex_t* m)
299  {
300  CHK_XENO_CALL();
301  return rt_mutex_release(m);
302  }
303 
304  static inline int rtos_mutex_rec_lock( rt_rec_mutex_t* m)
305  {
306  return rtos_mutex_lock(m);
307  }
308 
309  static inline int rtos_mutex_rec_trylock( rt_rec_mutex_t* m)
310  {
311  return rtos_mutex_trylock(m);
312  }
313 
314  static inline int rtos_mutex_rec_lock_until( rt_rec_mutex_t* m, NANO_TIME abs_time)
315  {
316  return rtos_mutex_lock_until(m, abs_time);
317  }
318 
319  static inline int rtos_mutex_rec_trylock_for( rt_rec_mutex_t* m, NANO_TIME relative_time)
320  {
321  return rtos_mutex_trylock_for(m, relative_time);
322  }
323 
324  static inline int rtos_mutex_rec_unlock( rt_rec_mutex_t* m)
325  {
326  return rtos_mutex_unlock(m);
327  }
328 
329  static inline void rtos_enable_rt_warning()
330  {
331  CHK_XENO_CALL();
332  rt_task_set_mode(0, T_WARNSW, NULL);
333  }
334 
335  static inline void rtos_disable_rt_warning()
336  {
337  CHK_XENO_CALL();
338  rt_task_set_mode(T_WARNSW, 0, NULL);
339  }
340 
341  static inline int rtos_cond_init(rt_cond_t *cond)
342  {
343  CHK_XENO_CALL();
344  return rt_cond_create(cond, 0);
345  }
346 
347  static inline int rtos_cond_destroy(rt_cond_t *cond)
348  {
349  CHK_XENO_CALL();
350  return rt_cond_delete(cond);
351  }
352 
353  static inline int rtos_cond_wait(rt_cond_t *cond, rt_mutex_t *mutex)
354  {
355  CHK_XENO_CALL();
356  int ret = rt_cond_wait(cond, mutex, TM_INFINITE);
357  if (ret == 0)
358  return 0;
359  return -1;
360  }
361 
362  static inline int rtos_cond_timedwait(rt_cond_t *cond, rt_mutex_t *mutex, NANO_TIME abs_time)
363  {
364  CHK_XENO_CALL();
365  // BC: support Xenomai < 2.5.0
366 #if ((CONFIG_XENO_VERSION_MAJOR*1000)+(CONFIG_XENO_VERSION_MINOR*100)+CONFIG_XENO_REVISION_LEVEL) < 2500
367  return rt_cond_wait(cond, mutex, rt_timer_ns2ticks(abs_time) - rt_timer_read() );
368 #else
369  return rt_cond_wait_until(cond, mutex, rt_timer_ns2ticks(abs_time) );
370 #endif
371  }
372 
373  static inline int rtos_cond_broadcast(rt_cond_t *cond)
374  {
375  CHK_XENO_CALL();
376  return rt_cond_broadcast(cond);
377  }
378 
379 
380 #define rtos_printf printf
381 
382 #ifdef __cplusplus
383 }
384 #endif
385 
386 #endif
int rtos_mutex_init(rt_mutex_t *m)
long long NANO_TIME
Definition: fosi.h:55
const double InfiniteSeconds
Definition: fosi.h:60
int rtos_mutex_rec_lock(rt_rec_mutex_t *m)
const TICK_TIME InfiniteTicks
Definition: fosi.h:58
int rtos_cond_destroy(rt_cond_t *cond)
NANO_TIME rtos_get_time_ns(void)
Get "system" time in nanoseconds.
Definition: fosi.h:113
int rtos_nanosleep(const TIME_SPEC *rqtp, TIME_SPEC *rmtp)
Definition: fosi.h:180
const NANO_TIME InfiniteNSecs
Definition: fosi.h:59
int rtos_mutex_rec_init(rt_rec_mutex_t *m)
int rtos_sem_trywait(rt_sem_t *m)
int rtos_mutex_rec_trylock(rt_rec_mutex_t *m)
int rtos_sem_signal(rt_sem_t *m)
int rtos_mutex_rec_trylock_for(rt_rec_mutex_t *m, NANO_TIME relative_time)
int rtos_cond_timedwait(rt_cond_t *cond, rt_mutex_t *mutex, NANO_TIME abs_time)
RTOS_XENO_TASK xenotask
Definition: fosi.h:108
int rtos_cond_wait(rt_cond_t *cond, rt_mutex_t *mutex)
TIME_SPEC ticks2timespec(TICK_TIME hrt)
Definition: fosi.h:146
RTOS_XENO_TASK * xenoptr
Definition: fosi.h:109
cyg_tick_count_t TICK_TIME
Definition: fosi.h:56
int rtos_mutex_unlock(rt_mutex_t *m)
#define rt_mutex_acquire
Definition: fosi.h:84
int rtos_mutex_rec_unlock(rt_rec_mutex_t *m)
RT_TASK RTOS_XENO_TASK
Definition: fosi.h:103
void rtos_disable_rt_warning()
Disallows the RTOS to print a warning when we violate real-time constraints.
#define CHK_XENO_CALL()
Definition: fosi.h:153
int rtos_sem_destroy(rt_sem_t *m)
pthread_cond_t rt_cond_t
Definition: fosi.h:296
int rtos_mutex_lock_until(rt_mutex_t *m, NANO_TIME abs_time)
int rtos_mutex_rec_lock_until(rt_rec_mutex_t *m, NANO_TIME abs_time)
int rtos_mutex_lock(rt_mutex_t *m)
TICK_TIME rtos_get_time_ticks(void)
Get "system" time in ticks FIXME see https://proj.fmtc.be/orocos-bugzilla/show_bug.cgi?id=60
Definition: fosi.h:118
TICK_TIME ticksPerSec(void)
Definition: fosi.h:175
int rtos_mutex_trylock(rt_mutex_t *m)
NANO_TIME ticks2nano(TICK_TIME count)
Time conversions from system ticks to nano seconds.
Definition: fosi.h:107
cyg_recursive_mutex_t rt_rec_mutex_t
Definition: fosi.h:186
int rtos_sem_init(rt_sem_t *m, int value)
All these should return zero in case of succes.
TICK_TIME nano2ticks(NANO_TIME nano)
Time conversions from nano seconds to system ticks.
Definition: fosi.h:100
int rtos_mutex_destroy(rt_mutex_t *m)
int rtos_sem_value(rt_sem_t *m)
int rtos_mutex_trylock_for(rt_mutex_t *m, NANO_TIME relative_time)
#define rt_mutex_release
Definition: fosi.h:85
struct MyTask RTOS_TASK
void rtos_enable_rt_warning()
Allows the RTOS to print a warning when we violate real-time constraints.
struct timespec TIME_SPEC
Definition: fosi.h:97
int rtos_cond_init(rt_cond_t *cond)
int rtos_sem_wait(rt_sem_t *m)
int rtos_cond_broadcast(rt_cond_t *cond)
cyg_sem_t rt_sem_t
Definition: fosi.h:131
int rtos_mutex_rec_destroy(rt_rec_mutex_t *m)
cyg_mutex_t rt_mutex_t
Definition: fosi.h:185