Orocos Real-Time Toolkit
2.5.0
|
00001 /*************************************************************************** 00002 tag: Peter Soetens Mon Jun 10 14:43:39 CEST 2002 fosi.h 00003 00004 fosi.h - description 00005 ------------------- 00006 begin : Mon June 10 2002 00007 copyright : (C) 2002 Peter Soetens 00008 email : peter.soetens@mech.kuleuven.ac.be 00009 00010 *************************************************************************** 00011 * * 00012 * This program is free software; you can redistribute it and/or modify * 00013 * it under the terms of the GNU General Public License as published by * 00014 * the Free Software Foundation; either version 2 of the License, or * 00015 * (at your option) any later version. * 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 // force inlining if internal and internal to avoid an extra indirection. 00058 // otherwise, the inlining is selected by the user in his rtai configuration 00059 #if defined(OROBLD_OS_LXRT_INTERNAL) 00060 #define CONFIG_RTAI_LXRT_INLINE 1 00061 #endif 00062 00063 // include custom redirect-like include 00064 #include <rtai_config.h> 00065 #include <rtai_lxrt.h> 00066 #include <rtai_sem.h> 00067 00068 // Finally, define the types we use : 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 // For PeriodicTask.cxx : 00076 // we need to define the types without the headers, 00077 // this is RTAI version dependent. 00078 // v3.x : 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 // this is required because the rtos_sem_init function takes a pointer to RTOS_SEM, 00089 // which contains a pointer to the real RTAI sem. 00090 typedef struct oro_rtai_sem_t { 00091 RTOS_RTAI_SEM* sem; 00092 } rt_sem_t; 00093 00094 // this is required because the rtos_cond_init function takes a pointer to RTOS_COND, 00095 // which contains a pointer to the real RTAI cond 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 // Time Related 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 // hrt is in ticks 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 // turn this on to have maximum detection of valid system calls. 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); // rtai 24.1.9 00182 return 0; 00183 } 00184 00185 static inline int rtos_sem_init(rt_sem_t* m, int value ) 00186 { 00187 CHK_LXRT_CALL(); 00188 // store the pointer in m->opaque... 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 // RES_SEM is PRIO_Q anyhow. 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 // XXX revert to print to screen when debugging is over 00379 return rtai_print_to_screen(printkbuf); 00380 //return printf(printkbuf); 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