Orocos Real-Time Toolkit  2.8.3
fosi.h
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Mon Jun 10 14:43:39 CEST 2002 fosi.h
3 
4  fosi.h - description
5  -------------------
6  begin : Mon June 10 2002
7  copyright : (C) 2002 Peter Soetens
8  email : peter.soetens@mech.kuleuven.ac.be
9 
10  ***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 
19 
26 #ifndef __FOSI_H
27 #define __FOSI_H
28 
29 #ifndef _GNU_SOURCE
30 #define _GNU_SOURCE // use all Posix features (and then some).
31 #endif
32 
33 
34 #ifndef _XOPEN_SOURCE
35 #define _XOPEN_SOURCE 600 // use all Posix98 features.
36 #endif
37 
38 #define HAVE_FOSI_API
39 
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <stdarg.h>
43 #include <sys/types.h>
44 #include <sched.h>
45 #include <assert.h>
46 #include <limits.h>
47 #include <float.h>
48 #include "../oro_limits.h"
49 
50 #ifdef __cplusplus
51 extern "C" {
52 #endif
53 
54 #include "../../rtt-config.h"
55 #if !defined(OROBLD_OS_AGNOSTIC) || defined(OROBLD_OS_LXRT_INTERNAL) // define the latter to include nevertheless the RTAI header files
56 
57  // force inlining if internal and internal to avoid an extra indirection.
58  // otherwise, the inlining is selected by the user in his rtai configuration
59 #if defined(OROBLD_OS_LXRT_INTERNAL)
60 #define CONFIG_RTAI_LXRT_INLINE 1
61 #endif
62 
63 // include custom redirect-like include
64 #include <rtai_config.h>
65 #include <rtai_lxrt.h>
66 #include <rtai_sem.h>
67 
68  // Finally, define the types we use :
69  typedef RT_TASK RTOS_RTAI_TASK;
70  typedef SEM RTOS_RTAI_SEM;
71  typedef CND RTOS_RTAI_CND;
72 
73 #else // AGNOSTIC
74 
75  // For PeriodicTask.cxx :
76  // we need to define the types without the headers,
77  // this is RTAI version dependent.
78  // v3.x :
79  typedef struct oro_lxrt_t {
80  int opaque;
81  } __LXRT_HANDLE_STRUCT;
82 
83  typedef __LXRT_HANDLE_STRUCT RTOS_RTAI_TASK;
84  typedef __LXRT_HANDLE_STRUCT RTOS_RTAI_SEM;
85  typedef __LXRT_HANDLE_STRUCT RTOS_RTAI_CND;
86 #endif // OROBLD_OS_AGNOSTIC // for RTAI header files.
87 
88  // this is required because the rtos_sem_init function takes a pointer to RTOS_SEM,
89  // which contains a pointer to the real RTAI sem.
90  typedef struct oro_rtai_sem_t {
91  RTOS_RTAI_SEM* sem;
92  } rt_sem_t;
93 
94  // this is required because the rtos_cond_init function takes a pointer to RTOS_COND,
95  // which contains a pointer to the real RTAI cond
96  typedef struct oro_rtai_cond_t {
97  RTOS_RTAI_CND* cond;
98  } rt_cond_t;
99 
100 #define __LXRT_USERSPACE__
101 
102 
105 
106  // Time Related
107 
108  typedef long long NANO_TIME;
109  typedef long long TICK_TIME;
110  typedef struct timespec TIME_SPEC;
111 
112  typedef struct {
113  pthread_t thread;
114  char * name;
115  int priority;
116 
117  RTOS_RTAI_TASK* rtaitask;
118  } RTOS_TASK;
119 
120  static const TICK_TIME InfiniteTicks = LLONG_MAX;
121  static const NANO_TIME InfiniteNSecs = LLONG_MAX;
122  static const double InfiniteSeconds = DBL_MAX;
123 
124 #define SCHED_LXRT_HARD 0
125 #define SCHED_LXRT_SOFT 1
126 #define ORO_SCHED_RT 0
127 #define ORO_SCHED_OTHER 1
129 #define ORO_WAIT_ABS 0
130 #define ORO_WAIT_REL 1
134 // rtai undef cfr boost::graph library adjacency_list.hpp:443
135 #undef DS
136 #undef OEL
137 #undef VL
138 #undef VP
139 #undef EP
140 #undef GP
141 #undef EL
142 
143 #ifndef OROBLD_OS_AGNOSTIC
144 
145  // hrt is in ticks
146 inline TIME_SPEC ticks2timespec(TICK_TIME hrt)
147 {
148  TIME_SPEC timevl;
149  timevl.tv_sec = nano2count(hrt) / 1000000000LL;
150  timevl.tv_nsec = nano2count(hrt) % 1000000000LL;
151  return timevl;
152 }
153 
154 // turn this on to have maximum detection of valid system calls.
155 #ifdef OROSEM_OS_LXRT_CHECK
156 #define CHK_LXRT_CALL() do { if(rt_buddy() == 0) { \
157  printf("LXRT NOT INITIALISED IN THIS THREAD pid=%d,\n\
158  BUT TRIES TO INVOKE LXRT FUNCTION >>%s<< ANYWAY\n", getpid(), __FUNCTION__ );\
159  assert( rt_buddy() != 0 ); }\
160  } while(0)
161 #define CHK_LXRT_PTR(ptr) do { if(ptr == 0) { \
162  printf("TRIED TO PASS NULL POINTER TO LXRT IN THREAD pid=%d,\n\
163  IN TRYING TO INVOKE LXRT FUNCTION >>%s<<\n", getpid(), __FUNCTION__ );\
164  assert( ptr != 0 ); }\
165  } while(0)
166 #else
167 #define CHK_LXRT_CALL()
168 #define CHK_LXRT_PTR( a )
169 #endif
170 
171 inline NANO_TIME rtos_get_time_ns(void) { return rt_get_time_ns(); }
172 
173 inline TICK_TIME rtos_get_time_ticks(void) { return rt_get_time(); }
174 
175 inline TICK_TIME ticksPerSec(void) { return nano2count( 1000 * 1000 * 1000 ); }
176 
177  inline TICK_TIME nano2ticks(NANO_TIME t) { return nano2count(t); }
178  inline NANO_TIME ticks2nano(TICK_TIME t) { return count2nano(t); }
179 
180 inline int rtos_nanosleep(const TIME_SPEC *rqtp, TIME_SPEC *rmtp)
181 {
182  CHK_LXRT_CALL();
183  nanosleep(rqtp,rmtp); // rtai 24.1.9
184  return 0;
185 }
186 
187  static inline int rtos_sem_init(rt_sem_t* m, int value )
188  {
189  CHK_LXRT_CALL();
190  // store the pointer in m->opaque...
191  m->sem = rt_sem_init( rt_get_name(0) , value);
192  return m->sem == 0 ? -1 : 0;
193  }
194 
195  static inline int rtos_sem_destroy(rt_sem_t* m )
196  {
197  CHK_LXRT_CALL();
198  return rt_sem_delete( m->sem );
199  }
200 
201  static inline int rtos_sem_signal(rt_sem_t* m )
202  {
203  CHK_LXRT_CALL();
204  return rt_sem_signal( m->sem );
205  }
206 
207  static inline int rtos_sem_wait(rt_sem_t* m )
208  {
209  CHK_LXRT_CALL();
210  return rt_sem_wait( m->sem );
211  }
212 
213  static inline int rtos_sem_trywait(rt_sem_t* m )
214  {
215  CHK_LXRT_CALL();
216  return rt_sem_wait_if(m->sem);
217  }
218 
219  static inline int rtos_sem_value(rt_sem_t* m )
220  {
221  CHK_LXRT_CALL();
222  return rt_sem_count(m->sem);
223  }
224 
225  static inline int rtos_sem_wait_timed(rt_sem_t* m, NANO_TIME delay )
226  {
227  int ret;
228  CHK_LXRT_CALL();
229  ret = rt_sem_wait_timed(m->sem, nano2count(delay) ) ;
230 #if defined(CONFIG_RTAI_VERSION_MINOR) && defined(CONFIG_RTAI_VERSION_MAJOR)
231 # if CONFIG_RTAI_VERSION_MAJOR == 3 && CONFIG_RTAI_VERSION_MINOR > 3
232  return (ret == RTE_TIMOUT) ? -1 : 0;
233 # else
234  return (ret == SEM_TIMOUT) ? -1 : 0;
235 # endif
236 #else
237  return (ret == SEM_TIMOUT) ? -1 : 0;
238 #endif
239  }
240 
241  static inline int rtos_sem_wait_until(rt_sem_t* m, NANO_TIME when )
242  {
243  int ret;
244  CHK_LXRT_CALL();
245  ret = rt_sem_wait_until(m->sem, nano2count(when) ) ;
246 #if defined(CONFIG_RTAI_VERSION_MINOR) && defined(CONFIG_RTAI_VERSION_MAJOR)
247 # if CONFIG_RTAI_VERSION_MAJOR == 3 && CONFIG_RTAI_VERSION_MINOR > 3
248  return (ret == RTE_TIMOUT) ? -1 : 0;
249 # else
250  return (ret == SEM_TIMOUT) ? -1 : 0;
251 # endif
252 #else
253  return (ret == SEM_TIMOUT) ? -1 : 0;
254 #endif
255  }
256 
257  static inline int rtos_mutex_init(rt_mutex_t* m)
258  {
259  CHK_LXRT_CALL();
260  m->sem = rt_typed_sem_init( rt_get_name(0),1, BIN_SEM | PRIO_Q);
261  return m->sem == 0 ? -1 : 0;
262  }
263 
264  static inline int rtos_mutex_destroy(rt_mutex_t* m )
265  {
266  CHK_LXRT_CALL();
267  return rt_sem_delete(m->sem);
268  }
269 
270  static inline int rtos_mutex_rec_init(rt_rec_mutex_t* m)
271  {
272  CHK_LXRT_CALL();
273  // RES_SEM is PRIO_Q anyhow.
274  m->sem = rt_typed_sem_init( rt_get_name(0), 1, RES_SEM);
275  return m->sem == 0 ? -1 : 0;
276  }
277 
278  static inline int rtos_mutex_rec_destroy(rt_rec_mutex_t* m )
279  {
280  CHK_LXRT_CALL();
281  return rt_sem_delete(m->sem);
282  }
283 
284  static inline int rtos_mutex_lock( rt_mutex_t* m)
285  {
286  CHK_LXRT_CALL();
287  return rt_sem_wait(m->sem);
288  }
289 
290  static inline int rtos_mutex_rec_lock( rt_rec_mutex_t* m)
291  {
292  CHK_LXRT_CALL();
293  return rt_sem_wait(m->sem);
294  }
295 
296  static inline int rtos_mutex_trylock( rt_mutex_t* m)
297  {
298  CHK_LXRT_CALL();
299  return rt_sem_wait_if(m->sem) > 0 ? 0 : -EAGAIN;
300  }
301 
302  static inline int rtos_mutex_rec_trylock( rt_rec_mutex_t* m)
303  {
304  CHK_LXRT_CALL();
305  return rt_sem_wait_if(m->sem) > 0 ? 0 : -EAGAIN;
306  }
307 
308  static inline int rtos_mutex_lock_until( rt_mutex_t* m, NANO_TIME abs_time)
309  {
310  CHK_LXRT_CALL();
311  return rt_sem_wait_until(m->sem, nano2count(abs_time)) < SEM_TIMOUT ? 0 : -EAGAIN;
312  }
313 
314  static inline int rtos_mutex_rec_lock_until( rt_rec_mutex_t* m, NANO_TIME abs_time)
315  {
316  CHK_LXRT_CALL();
317  return rt_sem_wait_until(m->sem, nano2count(abs_time)) < SEM_TIMOUT ? 0 : -EAGAIN;
318  }
319 
320 
321  static inline int rtos_mutex_unlock( rt_mutex_t* m)
322  {
323  CHK_LXRT_CALL();
324  return rt_sem_signal(m->sem);
325  }
326 
327  static inline int rtos_mutex_rec_unlock( rt_rec_mutex_t* m)
328  {
329  CHK_LXRT_CALL();
330  return rt_sem_signal(m->sem);
331  }
332 
333  static inline int rtos_cond_init(rt_cond_t *cond)
334  {
335  CHK_LXRT_CALL();
336  cond->cond = rt_cond_init(0);
337  return cond->cond == 0 ? -1 : 0;
338  }
339 
340  static inline int rtos_cond_destroy(rt_cond_t *cond)
341  {
342  CHK_LXRT_CALL();
343  return rt_cond_delete(cond->cond);
344  }
345 
346  static inline int rtos_cond_wait(rt_cond_t *cond, rt_mutex_t *mutex)
347  {
348  CHK_LXRT_CALL();
349  int ret = rt_cond_wait(cond->cond, mutex->sem );
350  if (ret == 0)
351  return 0;
352  return -1;
353  }
354 
355  static inline int rtos_cond_timedwait(rt_cond_t *cond, rt_mutex_t *mutex, NANO_TIME abstime)
356  {
357  CHK_LXRT_CALL();
358  int ret = rt_cond_wait_until(cond->cond, mutex->sem, nano2count(abs_time) );
359  if (ret == 0)
360  return 0;
361  if ( ret == SEM_TIMOUT )
362  return ETIMEOUT;
363  return -1;
364  }
365 
366  static inline int rtos_cond_broadcast(rt_cond_t *cond)
367  {
368  CHK_LXRT_CALL();
369  return rt_cond_broadcast(cond->cond);
370  }
371 inline
372 int rtos_printf(const char *fmt, ...)
373 {
374  va_list list;
375  char printkbuf [2000];
376  printkbuf[0] = '\0';
377  va_start (list, fmt);
378  vsprintf(printkbuf, fmt, list);
379  va_end (list);
380  // XXX revert to print to screen when debugging is over
381  return rtai_print_to_screen(printkbuf);
382  //return printf(printkbuf);
383 }
384 
385 #else // OSBLD_OS_AGNOSTIC
386 
391 TIME_SPEC ticks2timespec(TICK_TIME hrt);
392 
393 NANO_TIME rtos_get_time_ns(void);
394 
395 TICK_TIME rtos_get_time_ticks(void);
396 
397 TICK_TIME ticksPerSec(void);
398 
399 TICK_TIME nano2ticks(NANO_TIME t);
400 
401 NANO_TIME ticks2nano(TICK_TIME t);
402 
403 int rtos_nanosleep(const TIME_SPEC *rqtp, TIME_SPEC *rmtp) ;
404 
405 int rtos_mutex_init(rt_mutex_t* m);
406 
407 int rtos_mutex_destroy(rt_mutex_t* m );
408 
409 int rtos_mutex_rec_init(rt_mutex_t* m);
410 
411 int rtos_mutex_rec_destroy(rt_mutex_t* m );
412 
413 int rtos_mutex_lock( rt_mutex_t* m);
414 
415 int rtos_mutex_trylock( rt_mutex_t* m);
416 
417 int rtos_mutex_lock_until( rt_mutex_t* m, NANO_TIME abs_time);
418 
419 int rtos_mutex_rec_lock_until( rt_mutex_t* m, NANO_TIME abs_time);
420 
421 int rtos_mutex_unlock( rt_mutex_t* m);
422 
423 int rtos_mutex_rec_lock( rt_rec_mutex_t* m);
424 
425 int rtos_mutex_rec_trylock( rt_rec_mutex_t* m);
426 
427 int rtos_mutex_rec_unlock( rt_rec_mutex_t* m);
428 
429 int rtos_printf(const char *fmt, ...);
430 
431 int rtos_sem_init(rt_sem_t* m, int value );
432 int rtos_sem_destroy(rt_sem_t* m );
433 int rtos_sem_signal(rt_sem_t* m );
434 int rtos_sem_wait(rt_sem_t* m );
435 int rtos_sem_trywait(rt_sem_t* m );
436 int rtos_sem_value(rt_sem_t* m );
437 int rtos_sem_wait_timed(rt_sem_t* m, NANO_TIME delay );
438 int rtos_sem_wait_until(rt_sem_t* m, NANO_TIME when );
439 
440 int rtos_cond_init(rt_cond_t *cond);
441 int rtos_cond_destroy(rt_cond_t *cond);
442 int rtos_cond_wait(rt_cond_t *cond, rt_mutex_t *mutex);
443 int rtos_cond_timedwait(rt_cond_t *cond, rt_mutex_t *mutex, NANO_TIME abs_time);
444 int rtos_cond_broadcast(rt_cond_t *cond);
445 
446 #endif // OSBLD_OS_AGNOSTIC
447 
448 static inline void rtos_enable_rt_warning()
449 {
450 }
451 
452 static inline void rtos_disable_rt_warning()
453 {
454 }
455 
456 #ifdef __cplusplus
457 }
458 #endif
459 
460 #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_printf(const char *fmt,...)
&#39;real-time&#39; print function.
Definition: fosi.h:372
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
RTOS_RTAI_CND * cond
Definition: fosi.h:97
#define LLONG_MAX
Definition: oro_limits.h:47
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)
SEM RTOS_RTAI_SEM
Definition: fosi.h:70
int rtos_cond_timedwait(rt_cond_t *cond, rt_mutex_t *mutex, NANO_TIME abs_time)
int rtos_cond_wait(rt_cond_t *cond, rt_mutex_t *mutex)
TIME_SPEC ticks2timespec(TICK_TIME hrt)
Definition: fosi.h:146
cyg_tick_count_t TICK_TIME
Definition: fosi.h:56
int rtos_mutex_unlock(rt_mutex_t *m)
int rtos_mutex_rec_unlock(rt_rec_mutex_t *m)
void rtos_disable_rt_warning()
Disallows the RTOS to print a warning when we violate real-time constraints.
#define CHK_LXRT_CALL()
Definition: fosi.h:167
int rtos_sem_destroy(rt_sem_t *m)
RT_TASK RTOS_RTAI_TASK
Definition: fosi.h:69
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
RTOS_RTAI_SEM * sem
Definition: fosi.h:91
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)
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
CND RTOS_RTAI_CND
Definition: fosi.h:71
int rtos_cond_init(rt_cond_t *cond)
int rtos_sem_wait(rt_sem_t *m)
RTOS_RTAI_TASK * rtaitask
Definition: fosi.h:117
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