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
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef _XENO_FOSI_H
00040 #define _XENO_FOSI_H
00041
00042 #ifndef _XOPEN_SOURCE
00043 #define _XOPEN_SOURCE 600 // use all Posix features.
00044 #endif
00045
00046 #define HAVE_FOSI_API
00047
00048 #ifdef __cplusplus
00049 extern "C" {
00050 #endif
00051
00052 #include "../../rtt-config.h"
00053
00054
00055
00056
00057 #ifndef _GNU_SOURCE
00058 #define _GNU_SOURCE
00059 #endif
00060 #include <sys/mman.h>
00061 #include <sys/time.h>
00062 #include <unistd.h>
00063 #include <stdlib.h>
00064 #include <math.h>
00065 #include <stdio.h>
00066 #include <stdarg.h>
00067 #include <string.h>
00068 #include <signal.h>
00069 #include <getopt.h>
00070 #include <time.h>
00071 #include <limits.h>
00072 #include <float.h>
00073 #include "../oro_limits.h"
00074
00075 #include <xeno_config.h>
00076 #include <native/task.h>
00077 #include <native/timer.h>
00078 #include <native/mutex.h>
00079 #include <native/sem.h>
00080 #include <native/cond.h>
00081
00082
00083 #if ((CONFIG_XENO_VERSION_MAJOR*1000)+(CONFIG_XENO_VERSION_MINOR*100)+CONFIG_XENO_REVISION_LEVEL) < 2300
00084 #define rt_mutex_acquire rt_mutex_lock
00085 #define rt_mutex_release rt_mutex_unlock
00086 #endif
00087
00088 #if ((CONFIG_XENO_VERSION_MAJOR*1000)+(CONFIG_XENO_VERSION_MINOR*100)+CONFIG_XENO_REVISION_LEVEL) >= 2500
00089 #define ORO_XENO_HAS_ACQUIRE_UNTIL
00090 #endif
00091
00092
00093 typedef RT_MUTEX rt_mutex_t;
00094 typedef RT_MUTEX rt_rec_mutex_t;
00095 typedef RT_SEM rt_sem_t;
00096 typedef RT_COND rt_cond_t;
00097
00098
00099
00100 typedef SRTIME NANO_TIME;
00101 typedef SRTIME TICK_TIME;
00102 typedef struct timespec TIME_SPEC;
00103 typedef RT_TASK RTOS_XENO_TASK;
00104
00105
00106 typedef struct {
00107 char * name;
00108 RTOS_XENO_TASK xenotask;
00109 RTOS_XENO_TASK* xenoptr;
00110 int sched_type;
00111 } RTOS_TASK;
00112
00113 static const TICK_TIME InfiniteTicks = LONG_LONG_MAX;
00114 static const NANO_TIME InfiniteNSecs = LONG_LONG_MAX;
00115 static const double InfiniteSeconds = DBL_MAX;
00116
00117 #define SCHED_XENOMAI_HARD 0
00118 #define SCHED_XENOMAI_SOFT 1
00119 #define ORO_SCHED_RT 0
00120 #define ORO_SCHED_OTHER 1
00122 // hrt is in ticks
00123 static inline TIME_SPEC ticks2timespec(TICK_TIME hrt)
00124 {
00125 TIME_SPEC timevl;
00126 timevl.tv_sec = rt_timer_tsc2ns(hrt) / 1000000000LL;
00127 timevl.tv_nsec = rt_timer_tsc2ns(hrt) % 1000000000LL;
00128 return timevl;
00129 }
00130
00131
00132 static inline TICK_TIME timespec2ticks(const TIME_SPEC* ts)
00133 {
00134 return rt_timer_ns2tsc(ts->tv_nsec + ts->tv_sec*1000000000LL);
00135 }
00136
00137
00138 #ifdef OROSEM_OS_XENO_CHECK
00139 #define CHK_XENO_CALL() do { if(rt_task_self() == 0) { \
00140 printf("RTT: XENO NOT INITIALISED IN THIS THREAD pid=%d,\n\
00141 BUT TRIES TO INVOKE XENO FUNCTION >>%s<< ANYWAY\n", getpid(), __FUNCTION__ );\
00142 assert( rt_task_self() != 0 ); }\
00143 } while(0)
00144 #define CHK_XENO_PTR(ptr) do { if(ptr == 0) { \
00145 printf("RTT: TRIED TO PASS NULL POINTER TO XENO IN THREAD pid=%d,\n\
00146 IN TRYING TO INVOKE XENO FUNCTION >>%s<<\n", getpid(), __FUNCTION__ );\
00147 assert( ptr != 0 ); }\
00148 } while(0)
00149 #else
00150 #define CHK_XENO_CALL()
00151 #define CHK_XENO_PTR( a )
00152 #endif
00153
00154 static inline NANO_TIME rtos_get_time_ns(void) { return rt_timer_ticks2ns(rt_timer_read()); }
00155
00156 static inline TICK_TIME rtos_get_time_ticks(void) { return rt_timer_tsc(); }
00157
00158 static inline TICK_TIME ticksPerSec(void) { return rt_timer_ns2tsc( 1000 * 1000 * 1000 ); }
00159
00160
00161
00162
00163
00164
00165 static inline TICK_TIME nano2ticks(NANO_TIME t) { return rt_timer_ns2tsc(t); }
00166 static inline NANO_TIME ticks2nano(TICK_TIME t) { return rt_timer_tsc2ns(t); }
00167
00168 static inline int rtos_nanosleep(const TIME_SPEC *rqtp, TIME_SPEC *rmtp)
00169 {
00170 CHK_XENO_CALL();
00171 RTIME ticks = rqtp->tv_sec * 1000000000LL + rqtp->tv_nsec;
00172 rt_task_sleep( rt_timer_ns2ticks(ticks) );
00173 return 0;
00174 }
00175
00176 static inline int rtos_sem_init(rt_sem_t* m, int value )
00177 {
00178 CHK_XENO_CALL();
00179 return rt_sem_create( m, 0, value, S_PRIO);
00180 }
00181
00182 static inline int rtos_sem_destroy(rt_sem_t* m )
00183 {
00184 CHK_XENO_CALL();
00185 return rt_sem_delete( m );
00186 }
00187
00188 static inline int rtos_sem_signal(rt_sem_t* m )
00189 {
00190 CHK_XENO_CALL();
00191 return rt_sem_v( m );
00192 }
00193
00194 static inline int rtos_sem_wait(rt_sem_t* m )
00195 {
00196 CHK_XENO_CALL();
00197 return rt_sem_p( m, TM_INFINITE );
00198 }
00199
00200 static inline int rtos_sem_trywait(rt_sem_t* m )
00201 {
00202 CHK_XENO_CALL();
00203 return rt_sem_p( m, TM_NONBLOCK);
00204 }
00205
00206 static inline int rtos_sem_value(rt_sem_t* m )
00207 {
00208 CHK_XENO_CALL();
00209 RT_SEM_INFO sinfo;
00210 if (rt_sem_inquire(m, &sinfo) == 0 ) {
00211 return sinfo.count;
00212 }
00213 return -1;
00214 }
00215
00216 static inline int rtos_sem_wait_timed(rt_sem_t* m, NANO_TIME delay )
00217 {
00218 CHK_XENO_CALL();
00219 return rt_sem_p(m, rt_timer_ns2ticks(delay) ) == 0 ? 0 : -1;
00220 }
00221
00222 static inline int rtos_sem_wait_until(rt_sem_t* m, NANO_TIME when )
00223 {
00224 CHK_XENO_CALL();
00225 return rt_sem_p(m, rt_timer_ns2ticks(when) - rt_timer_read() ) == 0 ? 0 : -1;
00226 }
00227
00228 static inline int rtos_mutex_init(rt_mutex_t* m)
00229 {
00230 CHK_XENO_CALL();
00231
00232 return rt_mutex_create(m, 0);
00233 }
00234
00235 static inline int rtos_mutex_destroy(rt_mutex_t* m )
00236 {
00237 CHK_XENO_CALL();
00238 return rt_mutex_delete(m);
00239 }
00240
00241 static inline int rtos_mutex_rec_init(rt_mutex_t* m)
00242 {
00243 CHK_XENO_CALL();
00244
00245 return rt_mutex_create(m, 0);
00246 }
00247
00248 static inline int rtos_mutex_rec_destroy(rt_mutex_t* m )
00249 {
00250 CHK_XENO_CALL();
00251 return rt_mutex_delete(m);
00252 }
00253
00254 static inline int rtos_mutex_lock( rt_mutex_t* m)
00255 {
00256 CHK_XENO_CALL();
00257 return rt_mutex_acquire(m, TM_INFINITE );
00258 }
00259
00260 static inline int rtos_mutex_trylock( rt_mutex_t* m)
00261 {
00262 CHK_XENO_CALL();
00263 struct rt_mutex_info info;
00264 rt_mutex_inquire(m, &info );
00265 #if ((CONFIG_XENO_VERSION_MAJOR*1000)+(CONFIG_XENO_VERSION_MINOR*100)+CONFIG_XENO_REVISION_LEVEL) >= 2500
00266 if (info.locked)
00267 return 0;
00268 #else
00269 if (info.lockcnt)
00270 return 0;
00271 #endif
00272
00273
00274 return rt_mutex_acquire(m, TM_NONBLOCK);
00275 }
00276
00277 static inline int rtos_mutex_lock_until( rt_mutex_t* m, NANO_TIME abs_time)
00278 {
00279 CHK_XENO_CALL();
00280 #if !defined(ORO_XENO_HAS_ACQUIRE_UNTIL) // see top of this file
00281
00282 return rt_mutex_acquire(m, rt_timer_ns2ticks(abs_time) - rt_timer_read() );
00283 #else
00284
00285 return rt_mutex_acquire_until(m, rt_timer_ns2ticks(abs_time) );
00286 #endif
00287 }
00288
00289 static inline int rtos_mutex_unlock( rt_mutex_t* m)
00290 {
00291 CHK_XENO_CALL();
00292 return rt_mutex_release(m);
00293 }
00294
00295 static inline int rtos_mutex_rec_lock( rt_rec_mutex_t* m)
00296 {
00297 CHK_XENO_CALL();
00298 return rt_mutex_acquire(m, TM_INFINITE );
00299 }
00300
00301 static inline int rtos_mutex_rec_trylock( rt_rec_mutex_t* m)
00302 {
00303 CHK_XENO_CALL();
00304 return rtos_mutex_trylock(m);
00305 }
00306
00307 static inline int rtos_mutex_rec_lock_until( rt_rec_mutex_t* m, NANO_TIME abs_time)
00308 {
00309 CHK_XENO_CALL();
00310 return rtos_mutex_lock_until(m, abs_time);
00311 }
00312
00313 static inline int rtos_mutex_rec_unlock( rt_rec_mutex_t* m)
00314 {
00315 CHK_XENO_CALL();
00316 return rt_mutex_release(m);
00317 }
00318
00319 static inline void rtos_enable_rt_warning()
00320 {
00321 CHK_XENO_CALL();
00322 rt_task_set_mode(0, T_WARNSW, NULL);
00323 }
00324
00325 static inline void rtos_disable_rt_warning()
00326 {
00327 CHK_XENO_CALL();
00328 rt_task_set_mode(T_WARNSW, 0, NULL);
00329 }
00330
00331 static inline int rtos_cond_init(rt_cond_t *cond)
00332 {
00333 CHK_XENO_CALL();
00334 return rt_cond_create(cond, 0);
00335 }
00336
00337 static inline int rtos_cond_destroy(rt_cond_t *cond)
00338 {
00339 CHK_XENO_CALL();
00340 return rt_cond_delete(cond);
00341 }
00342
00343 static inline int rtos_cond_wait(rt_cond_t *cond, rt_mutex_t *mutex)
00344 {
00345 CHK_XENO_CALL();
00346 int ret = rt_cond_wait(cond, mutex, TM_INFINITE);
00347 if (ret == 0)
00348 return 0;
00349 return -1;
00350 }
00351
00352 static inline int rtos_cond_timedwait(rt_cond_t *cond, rt_mutex_t *mutex, NANO_TIME abs_time)
00353 {
00354 CHK_XENO_CALL();
00355
00356 #if ((CONFIG_XENO_VERSION_MAJOR*1000)+(CONFIG_XENO_VERSION_MINOR*100)+CONFIG_XENO_REVISION_LEVEL) < 2500
00357 return rt_cond_wait(cond, mutex, rt_timer_ns2ticks(abs_time) - rt_timer_read() );
00358 #else
00359 return rt_cond_wait_until(cond, mutex, rt_timer_ns2ticks(abs_time) );
00360 #endif
00361 }
00362
00363 static inline int rtos_cond_broadcast(rt_cond_t *cond)
00364 {
00365 CHK_XENO_CALL();
00366 return rt_cond_broadcast(cond);
00367 }
00368
00369
00370 #define rtos_printf printf
00371
00372 #ifdef __cplusplus
00373 }
00374 #endif
00375
00376 #endif