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
00132 // rtai undef cfr boost::graph library adjacency_list.hpp:443
00133 #undef DS
00134 #undef OEL
00135 #undef VL
00136 #undef VP
00137 #undef EP
00138 #undef GP
00139 #undef EL
00140
00141 #ifndef OROBLD_OS_AGNOSTIC
00142
00143
00144 inline TIME_SPEC ticks2timespec(TICK_TIME hrt)
00145 {
00146 TIME_SPEC timevl;
00147 timevl.tv_sec = nano2count(hrt) / 1000000000LL;
00148 timevl.tv_nsec = nano2count(hrt) % 1000000000LL;
00149 return timevl;
00150 }
00151
00152
00153 #ifdef OROSEM_OS_LXRT_CHECK
00154 #define CHK_LXRT_CALL() do { if(rt_buddy() == 0) { \
00155 printf("LXRT NOT INITIALISED IN THIS THREAD pid=%d,\n\
00156 BUT TRIES TO INVOKE LXRT FUNCTION >>%s<< ANYWAY\n", getpid(), __FUNCTION__ );\
00157 assert( rt_buddy() != 0 ); }\
00158 } while(0)
00159 #define CHK_LXRT_PTR(ptr) do { if(ptr == 0) { \
00160 printf("TRIED TO PASS NULL POINTER TO LXRT IN THREAD pid=%d,\n\
00161 IN TRYING TO INVOKE LXRT FUNCTION >>%s<<\n", getpid(), __FUNCTION__ );\
00162 assert( ptr != 0 ); }\
00163 } while(0)
00164 #else
00165 #define CHK_LXRT_CALL()
00166 #define CHK_LXRT_PTR( a )
00167 #endif
00168
00169 inline NANO_TIME rtos_get_time_ns(void) { return rt_get_time_ns(); }
00170
00171 inline TICK_TIME rtos_get_time_ticks(void) { return rt_get_time(); }
00172
00173 inline TICK_TIME ticksPerSec(void) { return nano2count( 1000 * 1000 * 1000 ); }
00174
00175 inline TICK_TIME nano2ticks(NANO_TIME t) { return nano2count(t); }
00176 inline NANO_TIME ticks2nano(TICK_TIME t) { return count2nano(t); }
00177
00178 inline int rtos_nanosleep(const TIME_SPEC *rqtp, TIME_SPEC *rmtp)
00179 {
00180 CHK_LXRT_CALL();
00181 nanosleep(rqtp,rmtp);
00182 return 0;
00183 }
00184
00185 static inline int rtos_sem_init(rt_sem_t* m, int value )
00186 {
00187 CHK_LXRT_CALL();
00188
00189 m->sem = rt_sem_init( rt_get_name(0) , value);
00190 return m->sem == 0 ? -1 : 0;
00191 }
00192
00193 static inline int rtos_sem_destroy(rt_sem_t* m )
00194 {
00195 CHK_LXRT_CALL();
00196 return rt_sem_delete( m->sem );
00197 }
00198
00199 static inline int rtos_sem_signal(rt_sem_t* m )
00200 {
00201 CHK_LXRT_CALL();
00202 return rt_sem_signal( m->sem );
00203 }
00204
00205 static inline int rtos_sem_wait(rt_sem_t* m )
00206 {
00207 CHK_LXRT_CALL();
00208 return rt_sem_wait( m->sem );
00209 }
00210
00211 static inline int rtos_sem_trywait(rt_sem_t* m )
00212 {
00213 CHK_LXRT_CALL();
00214 return rt_sem_wait_if(m->sem);
00215 }
00216
00217 static inline int rtos_sem_value(rt_sem_t* m )
00218 {
00219 CHK_LXRT_CALL();
00220 return rt_sem_count(m->sem);
00221 }
00222
00223 static inline int rtos_sem_wait_timed(rt_sem_t* m, NANO_TIME delay )
00224 {
00225 int ret;
00226 CHK_LXRT_CALL();
00227 ret = rt_sem_wait_timed(m->sem, nano2count(delay) ) ;
00228 #if defined(CONFIG_RTAI_VERSION_MINOR) && defined(CONFIG_RTAI_VERSION_MAJOR)
00229 # if CONFIG_RTAI_VERSION_MAJOR == 3 && CONFIG_RTAI_VERSION_MINOR > 3
00230 return (ret == RTE_TIMOUT) ? -1 : 0;
00231 # else
00232 return (ret == SEM_TIMOUT) ? -1 : 0;
00233 # endif
00234 #else
00235 return (ret == SEM_TIMOUT) ? -1 : 0;
00236 #endif
00237 }
00238
00239 static inline int rtos_sem_wait_until(rt_sem_t* m, NANO_TIME when )
00240 {
00241 int ret;
00242 CHK_LXRT_CALL();
00243 ret = rt_sem_wait_until(m->sem, nano2count(when) ) ;
00244 #if defined(CONFIG_RTAI_VERSION_MINOR) && defined(CONFIG_RTAI_VERSION_MAJOR)
00245 # if CONFIG_RTAI_VERSION_MAJOR == 3 && CONFIG_RTAI_VERSION_MINOR > 3
00246 return (ret == RTE_TIMOUT) ? -1 : 0;
00247 # else
00248 return (ret == SEM_TIMOUT) ? -1 : 0;
00249 # endif
00250 #else
00251 return (ret == SEM_TIMOUT) ? -1 : 0;
00252 #endif
00253 }
00254
00255 static inline int rtos_mutex_init(rt_mutex_t* m)
00256 {
00257 CHK_LXRT_CALL();
00258 m->sem = rt_typed_sem_init( rt_get_name(0),1, BIN_SEM | PRIO_Q);
00259 return m->sem == 0 ? -1 : 0;
00260 }
00261
00262 static inline int rtos_mutex_destroy(rt_mutex_t* m )
00263 {
00264 CHK_LXRT_CALL();
00265 return rt_sem_delete(m->sem);
00266 }
00267
00268 static inline int rtos_mutex_rec_init(rt_rec_mutex_t* m)
00269 {
00270 CHK_LXRT_CALL();
00271
00272 m->sem = rt_typed_sem_init( rt_get_name(0), 1, RES_SEM);
00273 return m->sem == 0 ? -1 : 0;
00274 }
00275
00276 static inline int rtos_mutex_rec_destroy(rt_rec_mutex_t* m )
00277 {
00278 CHK_LXRT_CALL();
00279 return rt_sem_delete(m->sem);
00280 }
00281
00282 static inline int rtos_mutex_lock( rt_mutex_t* m)
00283 {
00284 CHK_LXRT_CALL();
00285 return rt_sem_wait(m->sem);
00286 }
00287
00288 static inline int rtos_mutex_rec_lock( rt_rec_mutex_t* m)
00289 {
00290 CHK_LXRT_CALL();
00291 return rt_sem_wait(m->sem);
00292 }
00293
00294 static inline int rtos_mutex_trylock( rt_mutex_t* m)
00295 {
00296 CHK_LXRT_CALL();
00297 return rt_sem_wait_if(m->sem) > 0 ? 0 : -EAGAIN;
00298 }
00299
00300 static inline int rtos_mutex_rec_trylock( rt_rec_mutex_t* m)
00301 {
00302 CHK_LXRT_CALL();
00303 return rt_sem_wait_if(m->sem) > 0 ? 0 : -EAGAIN;
00304 }
00305
00306 static inline int rtos_mutex_lock_until( rt_mutex_t* m, NANO_TIME abs_time)
00307 {
00308 CHK_LXRT_CALL();
00309 return rt_sem_wait_until(m->sem, nano2count(abs_time)) < SEM_TIMOUT ? 0 : -EAGAIN;
00310 }
00311
00312 static inline int rtos_mutex_rec_lock_until( rt_rec_mutex_t* m, NANO_TIME abs_time)
00313 {
00314 CHK_LXRT_CALL();
00315 return rt_sem_wait_until(m->sem, nano2count(abs_time)) < SEM_TIMOUT ? 0 : -EAGAIN;
00316 }
00317
00318
00319 static inline int rtos_mutex_unlock( rt_mutex_t* m)
00320 {
00321 CHK_LXRT_CALL();
00322 return rt_sem_signal(m->sem);
00323 }
00324
00325 static inline int rtos_mutex_rec_unlock( rt_rec_mutex_t* m)
00326 {
00327 CHK_LXRT_CALL();
00328 return rt_sem_signal(m->sem);
00329 }
00330
00331 static inline int rtos_cond_init(rt_cond_t *cond)
00332 {
00333 CHK_LXRT_CALL();
00334 cond->cond = rt_cond_init(0);
00335 return cond->cond == 0 ? -1 : 0;
00336 }
00337
00338 static inline int rtos_cond_destroy(rt_cond_t *cond)
00339 {
00340 CHK_LXRT_CALL();
00341 return rt_cond_delete(cond->cond);
00342 }
00343
00344 static inline int rtos_cond_wait(rt_cond_t *cond, rt_mutex_t *mutex)
00345 {
00346 CHK_LXRT_CALL();
00347 int ret = rt_cond_wait(cond->cond, mutex->sem );
00348 if (ret == 0)
00349 return 0;
00350 return -1;
00351 }
00352
00353 static inline int rtos_cond_timedwait(rt_cond_t *cond, rt_mutex_t *mutex, NANO_TIME abstime)
00354 {
00355 CHK_LXRT_CALL();
00356 int ret = rt_cond_wait_until(cond->cond, mutex->sem, nano2count(abs_time) );
00357 if (ret == 0)
00358 return 0;
00359 if ( ret == SEM_TIMOUT )
00360 return ETIMEOUT;
00361 return -1;
00362 }
00363
00364 static inline int rtos_cond_broadcast(rt_cond_t *cond)
00365 {
00366 CHK_LXRT_CALL();
00367 return rt_cond_broadcast(cond->cond);
00368 }
00369 inline
00370 int rtos_printf(const char *fmt, ...)
00371 {
00372 va_list list;
00373 char printkbuf [2000];
00374 printkbuf[0] = '\0';
00375 va_start (list, fmt);
00376 vsprintf(printkbuf, fmt, list);
00377 va_end (list);
00378
00379 return rtai_print_to_screen(printkbuf);
00380
00381 }
00382
00383 #else // OSBLD_OS_AGNOSTIC
00384
00389 TIME_SPEC ticks2timespec(TICK_TIME hrt);
00390
00391 NANO_TIME rtos_get_time_ns(void);
00392
00393 TICK_TIME rtos_get_time_ticks(void);
00394
00395 TICK_TIME ticksPerSec(void);
00396
00397 TICK_TIME nano2ticks(NANO_TIME t);
00398
00399 NANO_TIME ticks2nano(TICK_TIME t);
00400
00401 int rtos_nanosleep(const TIME_SPEC *rqtp, TIME_SPEC *rmtp) ;
00402
00403 int rtos_mutex_init(rt_mutex_t* m);
00404
00405 int rtos_mutex_destroy(rt_mutex_t* m );
00406
00407 int rtos_mutex_rec_init(rt_mutex_t* m);
00408
00409 int rtos_mutex_rec_destroy(rt_mutex_t* m );
00410
00411 int rtos_mutex_lock( rt_mutex_t* m);
00412
00413 int rtos_mutex_trylock( rt_mutex_t* m);
00414
00415 int rtos_mutex_lock_until( rt_mutex_t* m, NANO_TIME abs_time);
00416
00417 int rtos_mutex_rec_lock_until( rt_mutex_t* m, NANO_TIME abs_time);
00418
00419 int rtos_mutex_unlock( rt_mutex_t* m);
00420
00421 int rtos_mutex_rec_lock( rt_rec_mutex_t* m);
00422
00423 int rtos_mutex_rec_trylock( rt_rec_mutex_t* m);
00424
00425 int rtos_mutex_rec_unlock( rt_rec_mutex_t* m);
00426
00427 int rtos_printf(const char *fmt, ...);
00428
00429 int rtos_sem_init(rt_sem_t* m, int value );
00430 int rtos_sem_destroy(rt_sem_t* m );
00431 int rtos_sem_signal(rt_sem_t* m );
00432 int rtos_sem_wait(rt_sem_t* m );
00433 int rtos_sem_trywait(rt_sem_t* m );
00434 int rtos_sem_value(rt_sem_t* m );
00435 int rtos_sem_wait_timed(rt_sem_t* m, NANO_TIME delay );
00436 int rtos_sem_wait_until(rt_sem_t* m, NANO_TIME when );
00437
00438 int rtos_cond_init(rt_cond_t *cond);
00439 int rtos_cond_destroy(rt_cond_t *cond);
00440 int rtos_cond_wait(rt_cond_t *cond, rt_mutex_t *mutex);
00441 int rtos_cond_timedwait(rt_cond_t *cond, rt_mutex_t *mutex, NANO_TIME abs_time);
00442 int rtos_cond_broadcast(rt_cond_t *cond);
00443
00444 #endif // OSBLD_OS_AGNOSTIC
00445
00446 static inline void rtos_enable_rt_warning()
00447 {
00448 }
00449
00450 static inline void rtos_disable_rt_warning()
00451 {
00452 }
00453
00454 #ifdef __cplusplus
00455 }
00456 #endif
00457
00458 #endif