Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00026 #ifndef __FOSI_H
00027 #define __FOSI_H
00028
00029 #ifndef _GNU_SOURCE
00030 #define _GNU_SOURCE // use all Posix features (and then some).
00031 #endif
00032
00033
00034 #ifndef _XOPEN_SOURCE
00035 #define _XOPEN_SOURCE 600 // use all Posix98 features.
00036 #endif
00037
00038 #define HAVE_FOSI_API
00039
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <stdarg.h>
00043 #include <sys/types.h>
00044 #include <sched.h>
00045 #include <assert.h>
00046 #include <limits.h>
00047 #include <float.h>
00048 #include "../oro_limits.h"
00049
00050 #ifdef __cplusplus
00051 extern "C" {
00052 #endif
00053
00054 #include "../../rtt-config.h"
00055 #if !defined(OROBLD_OS_AGNOSTIC) || defined(OROBLD_OS_LXRT_INTERNAL) // define the latter to include nevertheless the RTAI header files
00056
00057
00058
00059 #if defined(OROBLD_OS_LXRT_INTERNAL)
00060 #define CONFIG_RTAI_LXRT_INLINE 1
00061 #endif
00062
00063
00064 #include <rtai_config.h>
00065 #include <rtai_lxrt.h>
00066 #include <rtai_sem.h>
00067
00068
00069 typedef RT_TASK RTOS_RTAI_TASK;
00070 typedef SEM RTOS_RTAI_SEM;
00071 typedef CND RTOS_RTAI_CND;
00072
00073 #else // AGNOSTIC
00074
00075
00076
00077
00078
00079 typedef struct oro_lxrt_t {
00080 int opaque;
00081 } __LXRT_HANDLE_STRUCT;
00082
00083 typedef __LXRT_HANDLE_STRUCT RTOS_RTAI_TASK;
00084 typedef __LXRT_HANDLE_STRUCT RTOS_RTAI_SEM;
00085 typedef __LXRT_HANDLE_STRUCT RTOS_RTAI_CND;
00086 #endif // OROBLD_OS_AGNOSTIC // for RTAI header files.
00087
00088
00089
00090 typedef struct oro_rtai_sem_t {
00091 RTOS_RTAI_SEM* sem;
00092 } rt_sem_t;
00093
00094
00095
00096 typedef struct oro_rtai_cond_t {
00097 RTOS_RTAI_CND* cond;
00098 } rt_cond_t;
00099
00100 #define __LXRT_USERSPACE__
00101
00102
00103 typedef rt_sem_t rt_mutex_t;
00104 typedef rt_sem_t rt_rec_mutex_t;
00105
00106
00107
00108 typedef long long NANO_TIME;
00109 typedef long long TICK_TIME;
00110 typedef struct timespec TIME_SPEC;
00111
00112 typedef struct {
00113 pthread_t thread;
00114 char * name;
00115 int priority;
00116
00117 RTOS_RTAI_TASK* rtaitask;
00118 } RTOS_TASK;
00119
00120 static const TICK_TIME InfiniteTicks = LLONG_MAX;
00121 static const NANO_TIME InfiniteNSecs = LLONG_MAX;
00122 static const double InfiniteSeconds = DBL_MAX;
00123
00124 #define SCHED_LXRT_HARD 0
00125 #define SCHED_LXRT_SOFT 1
00126 #define ORO_SCHED_RT 0
00127 #define ORO_SCHED_OTHER 1
00129 #define ORO_WAIT_ABS 0
00130 #define ORO_WAIT_REL 1
00134 // rtai undef cfr boost::graph library adjacency_list.hpp:443
00135 #undef DS
00136 #undef OEL
00137 #undef VL
00138 #undef VP
00139 #undef EP
00140 #undef GP
00141 #undef EL
00142
00143 #ifndef OROBLD_OS_AGNOSTIC
00144
00145
00146 inline TIME_SPEC ticks2timespec(TICK_TIME hrt)
00147 {
00148 TIME_SPEC timevl;
00149 timevl.tv_sec = nano2count(hrt) / 1000000000LL;
00150 timevl.tv_nsec = nano2count(hrt) % 1000000000LL;
00151 return timevl;
00152 }
00153
00154
00155 #ifdef OROSEM_OS_LXRT_CHECK
00156 #define CHK_LXRT_CALL() do { if(rt_buddy() == 0) { \
00157 printf("LXRT NOT INITIALISED IN THIS THREAD pid=%d,\n\
00158 BUT TRIES TO INVOKE LXRT FUNCTION >>%s<< ANYWAY\n", getpid(), __FUNCTION__ );\
00159 assert( rt_buddy() != 0 ); }\
00160 } while(0)
00161 #define CHK_LXRT_PTR(ptr) do { if(ptr == 0) { \
00162 printf("TRIED TO PASS NULL POINTER TO LXRT IN THREAD pid=%d,\n\
00163 IN TRYING TO INVOKE LXRT FUNCTION >>%s<<\n", getpid(), __FUNCTION__ );\
00164 assert( ptr != 0 ); }\
00165 } while(0)
00166 #else
00167 #define CHK_LXRT_CALL()
00168 #define CHK_LXRT_PTR( a )
00169 #endif
00170
00171 inline NANO_TIME rtos_get_time_ns(void) { return rt_get_time_ns(); }
00172
00173 inline TICK_TIME rtos_get_time_ticks(void) { return rt_get_time(); }
00174
00175 inline TICK_TIME ticksPerSec(void) { return nano2count( 1000 * 1000 * 1000 ); }
00176
00177 inline TICK_TIME nano2ticks(NANO_TIME t) { return nano2count(t); }
00178 inline NANO_TIME ticks2nano(TICK_TIME t) { return count2nano(t); }
00179
00180 inline int rtos_nanosleep(const TIME_SPEC *rqtp, TIME_SPEC *rmtp)
00181 {
00182 CHK_LXRT_CALL();
00183 nanosleep(rqtp,rmtp);
00184 return 0;
00185 }
00186
00187 static inline int rtos_sem_init(rt_sem_t* m, int value )
00188 {
00189 CHK_LXRT_CALL();
00190
00191 m->sem = rt_sem_init( rt_get_name(0) , value);
00192 return m->sem == 0 ? -1 : 0;
00193 }
00194
00195 static inline int rtos_sem_destroy(rt_sem_t* m )
00196 {
00197 CHK_LXRT_CALL();
00198 return rt_sem_delete( m->sem );
00199 }
00200
00201 static inline int rtos_sem_signal(rt_sem_t* m )
00202 {
00203 CHK_LXRT_CALL();
00204 return rt_sem_signal( m->sem );
00205 }
00206
00207 static inline int rtos_sem_wait(rt_sem_t* m )
00208 {
00209 CHK_LXRT_CALL();
00210 return rt_sem_wait( m->sem );
00211 }
00212
00213 static inline int rtos_sem_trywait(rt_sem_t* m )
00214 {
00215 CHK_LXRT_CALL();
00216 return rt_sem_wait_if(m->sem);
00217 }
00218
00219 static inline int rtos_sem_value(rt_sem_t* m )
00220 {
00221 CHK_LXRT_CALL();
00222 return rt_sem_count(m->sem);
00223 }
00224
00225 static inline int rtos_sem_wait_timed(rt_sem_t* m, NANO_TIME delay )
00226 {
00227 int ret;
00228 CHK_LXRT_CALL();
00229 ret = rt_sem_wait_timed(m->sem, nano2count(delay) ) ;
00230 #if defined(CONFIG_RTAI_VERSION_MINOR) && defined(CONFIG_RTAI_VERSION_MAJOR)
00231 # if CONFIG_RTAI_VERSION_MAJOR == 3 && CONFIG_RTAI_VERSION_MINOR > 3
00232 return (ret == RTE_TIMOUT) ? -1 : 0;
00233 # else
00234 return (ret == SEM_TIMOUT) ? -1 : 0;
00235 # endif
00236 #else
00237 return (ret == SEM_TIMOUT) ? -1 : 0;
00238 #endif
00239 }
00240
00241 static inline int rtos_sem_wait_until(rt_sem_t* m, NANO_TIME when )
00242 {
00243 int ret;
00244 CHK_LXRT_CALL();
00245 ret = rt_sem_wait_until(m->sem, nano2count(when) ) ;
00246 #if defined(CONFIG_RTAI_VERSION_MINOR) && defined(CONFIG_RTAI_VERSION_MAJOR)
00247 # if CONFIG_RTAI_VERSION_MAJOR == 3 && CONFIG_RTAI_VERSION_MINOR > 3
00248 return (ret == RTE_TIMOUT) ? -1 : 0;
00249 # else
00250 return (ret == SEM_TIMOUT) ? -1 : 0;
00251 # endif
00252 #else
00253 return (ret == SEM_TIMOUT) ? -1 : 0;
00254 #endif
00255 }
00256
00257 static inline int rtos_mutex_init(rt_mutex_t* m)
00258 {
00259 CHK_LXRT_CALL();
00260 m->sem = rt_typed_sem_init( rt_get_name(0),1, BIN_SEM | PRIO_Q);
00261 return m->sem == 0 ? -1 : 0;
00262 }
00263
00264 static inline int rtos_mutex_destroy(rt_mutex_t* m )
00265 {
00266 CHK_LXRT_CALL();
00267 return rt_sem_delete(m->sem);
00268 }
00269
00270 static inline int rtos_mutex_rec_init(rt_rec_mutex_t* m)
00271 {
00272 CHK_LXRT_CALL();
00273
00274 m->sem = rt_typed_sem_init( rt_get_name(0), 1, RES_SEM);
00275 return m->sem == 0 ? -1 : 0;
00276 }
00277
00278 static inline int rtos_mutex_rec_destroy(rt_rec_mutex_t* m )
00279 {
00280 CHK_LXRT_CALL();
00281 return rt_sem_delete(m->sem);
00282 }
00283
00284 static inline int rtos_mutex_lock( rt_mutex_t* m)
00285 {
00286 CHK_LXRT_CALL();
00287 return rt_sem_wait(m->sem);
00288 }
00289
00290 static inline int rtos_mutex_rec_lock( rt_rec_mutex_t* m)
00291 {
00292 CHK_LXRT_CALL();
00293 return rt_sem_wait(m->sem);
00294 }
00295
00296 static inline int rtos_mutex_trylock( rt_mutex_t* m)
00297 {
00298 CHK_LXRT_CALL();
00299 return rt_sem_wait_if(m->sem) > 0 ? 0 : -EAGAIN;
00300 }
00301
00302 static inline int rtos_mutex_rec_trylock( rt_rec_mutex_t* m)
00303 {
00304 CHK_LXRT_CALL();
00305 return rt_sem_wait_if(m->sem) > 0 ? 0 : -EAGAIN;
00306 }
00307
00308 static inline int rtos_mutex_lock_until( rt_mutex_t* m, NANO_TIME abs_time)
00309 {
00310 CHK_LXRT_CALL();
00311 return rt_sem_wait_until(m->sem, nano2count(abs_time)) < SEM_TIMOUT ? 0 : -EAGAIN;
00312 }
00313
00314 static inline int rtos_mutex_rec_lock_until( rt_rec_mutex_t* m, NANO_TIME abs_time)
00315 {
00316 CHK_LXRT_CALL();
00317 return rt_sem_wait_until(m->sem, nano2count(abs_time)) < SEM_TIMOUT ? 0 : -EAGAIN;
00318 }
00319
00320
00321 static inline int rtos_mutex_unlock( rt_mutex_t* m)
00322 {
00323 CHK_LXRT_CALL();
00324 return rt_sem_signal(m->sem);
00325 }
00326
00327 static inline int rtos_mutex_rec_unlock( rt_rec_mutex_t* m)
00328 {
00329 CHK_LXRT_CALL();
00330 return rt_sem_signal(m->sem);
00331 }
00332
00333 static inline int rtos_cond_init(rt_cond_t *cond)
00334 {
00335 CHK_LXRT_CALL();
00336 cond->cond = rt_cond_init(0);
00337 return cond->cond == 0 ? -1 : 0;
00338 }
00339
00340 static inline int rtos_cond_destroy(rt_cond_t *cond)
00341 {
00342 CHK_LXRT_CALL();
00343 return rt_cond_delete(cond->cond);
00344 }
00345
00346 static inline int rtos_cond_wait(rt_cond_t *cond, rt_mutex_t *mutex)
00347 {
00348 CHK_LXRT_CALL();
00349 int ret = rt_cond_wait(cond->cond, mutex->sem );
00350 if (ret == 0)
00351 return 0;
00352 return -1;
00353 }
00354
00355 static inline int rtos_cond_timedwait(rt_cond_t *cond, rt_mutex_t *mutex, NANO_TIME abstime)
00356 {
00357 CHK_LXRT_CALL();
00358 int ret = rt_cond_wait_until(cond->cond, mutex->sem, nano2count(abs_time) );
00359 if (ret == 0)
00360 return 0;
00361 if ( ret == SEM_TIMOUT )
00362 return ETIMEOUT;
00363 return -1;
00364 }
00365
00366 static inline int rtos_cond_broadcast(rt_cond_t *cond)
00367 {
00368 CHK_LXRT_CALL();
00369 return rt_cond_broadcast(cond->cond);
00370 }
00371 inline
00372 int rtos_printf(const char *fmt, ...)
00373 {
00374 va_list list;
00375 char printkbuf [2000];
00376 printkbuf[0] = '\0';
00377 va_start (list, fmt);
00378 vsprintf(printkbuf, fmt, list);
00379 va_end (list);
00380
00381 return rtai_print_to_screen(printkbuf);
00382
00383 }
00384
00385 #else // OSBLD_OS_AGNOSTIC
00386
00391 TIME_SPEC ticks2timespec(TICK_TIME hrt);
00392
00393 NANO_TIME rtos_get_time_ns(void);
00394
00395 TICK_TIME rtos_get_time_ticks(void);
00396
00397 TICK_TIME ticksPerSec(void);
00398
00399 TICK_TIME nano2ticks(NANO_TIME t);
00400
00401 NANO_TIME ticks2nano(TICK_TIME t);
00402
00403 int rtos_nanosleep(const TIME_SPEC *rqtp, TIME_SPEC *rmtp) ;
00404
00405 int rtos_mutex_init(rt_mutex_t* m);
00406
00407 int rtos_mutex_destroy(rt_mutex_t* m );
00408
00409 int rtos_mutex_rec_init(rt_mutex_t* m);
00410
00411 int rtos_mutex_rec_destroy(rt_mutex_t* m );
00412
00413 int rtos_mutex_lock( rt_mutex_t* m);
00414
00415 int rtos_mutex_trylock( rt_mutex_t* m);
00416
00417 int rtos_mutex_lock_until( rt_mutex_t* m, NANO_TIME abs_time);
00418
00419 int rtos_mutex_rec_lock_until( rt_mutex_t* m, NANO_TIME abs_time);
00420
00421 int rtos_mutex_unlock( rt_mutex_t* m);
00422
00423 int rtos_mutex_rec_lock( rt_rec_mutex_t* m);
00424
00425 int rtos_mutex_rec_trylock( rt_rec_mutex_t* m);
00426
00427 int rtos_mutex_rec_unlock( rt_rec_mutex_t* m);
00428
00429 int rtos_printf(const char *fmt, ...);
00430
00431 int rtos_sem_init(rt_sem_t* m, int value );
00432 int rtos_sem_destroy(rt_sem_t* m );
00433 int rtos_sem_signal(rt_sem_t* m );
00434 int rtos_sem_wait(rt_sem_t* m );
00435 int rtos_sem_trywait(rt_sem_t* m );
00436 int rtos_sem_value(rt_sem_t* m );
00437 int rtos_sem_wait_timed(rt_sem_t* m, NANO_TIME delay );
00438 int rtos_sem_wait_until(rt_sem_t* m, NANO_TIME when );
00439
00440 int rtos_cond_init(rt_cond_t *cond);
00441 int rtos_cond_destroy(rt_cond_t *cond);
00442 int rtos_cond_wait(rt_cond_t *cond, rt_mutex_t *mutex);
00443 int rtos_cond_timedwait(rt_cond_t *cond, rt_mutex_t *mutex, NANO_TIME abs_time);
00444 int rtos_cond_broadcast(rt_cond_t *cond);
00445
00446 #endif // OSBLD_OS_AGNOSTIC
00447
00448 static inline void rtos_enable_rt_warning()
00449 {
00450 }
00451
00452 static inline void rtos_disable_rt_warning()
00453 {
00454 }
00455
00456 #ifdef __cplusplus
00457 }
00458 #endif
00459
00460 #endif