$search
00001 /*************************************************************************** 00002 tag: Peter Soetens Mon Jan 10 15:59:15 CET 2005 fosi.c 00003 00004 fosi.c - description 00005 ------------------- 00006 begin : Mon January 10 2005 00007 copyright : (C) 2005 Peter Soetens 00008 email : peter.soetens@mech.kuleuven.ac.be 00009 00010 *************************************************************************** 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU General Public * 00013 * License as published by the Free Software Foundation; * 00014 * version 2 of the License. * 00015 * * 00016 * As a special exception, you may use this file as part of a free * 00017 * software library without restriction. Specifically, if other files * 00018 * instantiate templates or use macros or inline functions from this * 00019 * file, or you compile this file and link it with other files to * 00020 * produce an executable, this file does not by itself cause the * 00021 * resulting executable to be covered by the GNU General Public * 00022 * License. This exception does not however invalidate any other * 00023 * reasons why the executable file might be covered by the GNU General * 00024 * Public License. * 00025 * * 00026 * This library is distributed in the hope that it will be useful, * 00027 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00028 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00029 * Lesser General Public License for more details. * 00030 * * 00031 * You should have received a copy of the GNU General Public * 00032 * License along with this library; if not, write to the Free Software * 00033 * Foundation, Inc., 59 Temple Place, * 00034 * Suite 330, Boston, MA 02111-1307 USA * 00035 * * 00036 ***************************************************************************/ 00037 00038 00039 #define OROBLD_OS_LXRT_INTERNAL 00040 #include "os/fosi.h" 00041 00042 #ifdef OROBLD_OS_AGNOSTIC 00043 // Encapsulate all RTAI/LXRT specific functions 00044 00045 // hrt is in nanoseconds 00046 TIME_SPEC ticks2timespec(RTIME hrt) 00047 { 00048 TIME_SPEC timevl; 00049 timevl.tv_sec = nano2count(hrt) / 1000000000LL; 00050 timevl.tv_nsec = nano2count(hrt) % 1000000000LL; 00051 return timevl; 00052 } 00053 00054 // turn this on to have maximum detection of valid system calls. 00055 #ifdef OROSEM_OS_LXRT_CHECK 00056 #define CHK_LXRT_CALL() do { if(rt_buddy() == 0) { \ 00057 printf("LXRT NOT INITIALISED IN THIS THREAD pid=%d,\n\ 00058 BUT TRIES TO INVOKE LXRT FUNCTION >>%s<< ANYWAY\n", getpid(), __FUNCTION__ );\ 00059 assert( rt_buddy() != 0 ); }\ 00060 } while(0) 00061 #define CHK_LXRT_PTR(ptr) do { if(ptr == 0) { \ 00062 printf("TRIED TO PASS NULL POINTER TO LXRT IN THREAD pid=%d,\n\ 00063 IN TRYING TO INVOKE LXRT FUNCTION >>%s<<\n", getpid(), __FUNCTION__ );\ 00064 assert( ptr != 0 ); }\ 00065 } while(0) 00066 #else 00067 #define CHK_LXRT_CALL() 00068 #define CHK_LXRT_PTR( a ) 00069 #endif 00070 00071 00072 NANO_TIME rtos_get_time_ns(void) { return rt_get_time_ns(); } 00073 00074 TICK_TIME rtos_get_time_ticks(void) { return rt_get_time(); } 00075 00076 TICK_TIME ticksPerSec(void) { return nano2count( 1000 * 1000 * 1000 ); } 00077 00078 TICK_TIME nano2ticks(NANO_TIME t) { return nano2count(t); } 00079 00080 NANO_TIME ticks2nano(TICK_TIME t) { return count2nano(t); } 00081 00082 00083 int rtos_nanosleep(const TIME_SPEC *rqtp, TIME_SPEC *rmtp) 00084 { 00085 CHK_LXRT_CALL(); 00086 nanosleep(rqtp,rmtp); // rtai 24.1.9 00087 return 0; 00088 } 00089 00090 int rtos_sem_init(rt_sem_t* m, int value ) 00091 { 00092 CHK_LXRT_CALL(); 00093 // store the pointer in m->opaque... 00094 m->sem = rt_sem_init( rt_get_name(0) , value); 00095 return m->sem == 0 ? -1 : 0; 00096 } 00097 00098 int rtos_sem_destroy(rt_sem_t* m ) 00099 { 00100 CHK_LXRT_CALL(); 00101 return rt_sem_delete(m->sem); 00102 } 00103 00104 int rtos_sem_signal(rt_sem_t* m ) 00105 { 00106 CHK_LXRT_CALL(); 00107 return rt_sem_signal(m->sem); 00108 } 00109 00110 int rtos_sem_wait(rt_sem_t* m ) 00111 { 00112 CHK_LXRT_CALL(); 00113 return rt_sem_wait(m->sem); 00114 } 00115 00116 int rtos_sem_trywait(rt_sem_t* m ) 00117 { 00118 CHK_LXRT_CALL(); 00119 return rt_sem_wait_if(m->sem); 00120 } 00121 00122 int rtos_sem_value(rt_sem_t* m ) 00123 { 00124 CHK_LXRT_CALL(); 00125 return rt_sem_count(m->sem); 00126 } 00127 00128 int rtos_sem_wait_timed(rt_sem_t* m, NANO_TIME delay ) 00129 { 00130 int ret; 00131 CHK_LXRT_CALL(); 00132 ret = rt_sem_wait_timed(m->sem, nano2count(delay) ); 00133 #if defined(CONFIG_RTAI_VERSION_MINOR) && defined(CONFIG_RTAI_VERSION_MAJOR) 00134 # if CONFIG_RTAI_VERSION_MAJOR == 3 && CONFIG_RTAI_VERSION_MINOR > 3 00135 return (ret == RTE_TIMOUT) ? -1 : 0; 00136 # else 00137 return (ret == SEM_TIMOUT) ? -1 : 0; 00138 # endif 00139 #else 00140 return (ret == SEM_TIMOUT) ? -1 : 0; 00141 #endif 00142 } 00143 00144 int rtos_sem_wait_until(rt_sem_t* m, NANO_TIME when ) 00145 { 00146 int ret; 00147 CHK_LXRT_CALL(); 00148 ret = rt_sem_wait_until(m->sem, nano2count(when) ) ; 00149 #if defined(CONFIG_RTAI_VERSION_MINOR) && defined(CONFIG_RTAI_VERSION_MAJOR) 00150 # if CONFIG_RTAI_VERSION_MAJOR == 3 && CONFIG_RTAI_VERSION_MINOR > 3 00151 return (ret == RTE_TIMOUT) ? -1 : 0; 00152 # else 00153 return (ret == SEM_TIMOUT) ? -1 : 0; 00154 # endif 00155 #else 00156 return (ret == SEM_TIMOUT) ? -1 : 0; 00157 #endif 00158 } 00159 00160 int rtos_mutex_init(rt_mutex_t* m) 00161 { 00162 CHK_LXRT_CALL(); 00163 m->sem = rt_typed_sem_init( rt_get_name(0),1, BIN_SEM | PRIO_Q); 00164 return m->sem == 0 ? -1 : 0; 00165 } 00166 00167 int rtos_mutex_destroy(rt_mutex_t* m ) 00168 { 00169 CHK_LXRT_CALL(); 00170 CHK_LXRT_PTR(m); 00171 return rt_sem_delete(m->sem); 00172 } 00173 00174 int rtos_mutex_rec_init(rt_mutex_t* m) 00175 { 00176 CHK_LXRT_CALL(); 00177 // RES_SEM is PRIO_Q anyhow. 00178 m->sem = rt_typed_sem_init( rt_get_name(0), 1, RES_SEM); 00179 return m->sem == 0 ? -1 : 0; 00180 } 00181 00182 int rtos_mutex_rec_destroy(rt_mutex_t* m ) 00183 { 00184 CHK_LXRT_CALL(); 00185 CHK_LXRT_PTR(m->sem); 00186 return rt_sem_delete(m->sem); 00187 } 00188 00189 int rtos_mutex_rec_lock( rt_rec_mutex_t* m) 00190 { 00191 CHK_LXRT_CALL(); 00192 return rt_sem_wait(m->sem); 00193 } 00194 00195 int rtos_mutex_rec_trylock( rt_rec_mutex_t* m) 00196 { 00197 CHK_LXRT_CALL(); 00198 return rt_sem_wait_if(m->sem) > 0 ? 0 : -EAGAIN; 00199 } 00200 00201 int rtos_mutex_lock_until( rt_mutex_t* m, NANO_TIME abs_time) 00202 { 00203 CHK_LXRT_CALL(); 00204 return rt_sem_wait_until(m->sem, nano2count(abs_time)) < SEM_TIMOUT ? 0 : -EAGAIN; 00205 } 00206 00207 int rtos_mutex_rec_lock_until( rt_rec_mutex_t* m, NANO_TIME abs_time) 00208 { 00209 CHK_LXRT_CALL(); 00210 return rt_sem_wait_until(m->sem, nano2count(abs_time)) < SEM_TIMOUT ? 0 : -EAGAIN; 00211 } 00212 00213 int rtos_mutex_rec_unlock( rt_rec_mutex_t* m) 00214 { 00215 CHK_LXRT_CALL(); 00216 return rt_sem_signal(m->sem); 00217 } 00218 00219 int rtos_mutex_lock( rt_mutex_t* m) 00220 { 00221 CHK_LXRT_CALL(); 00222 CHK_LXRT_PTR(m->sem); 00223 return rt_sem_wait(m->sem); 00224 } 00225 00226 int rtos_mutex_trylock( rt_mutex_t* m) 00227 { 00228 CHK_LXRT_CALL(); 00229 CHK_LXRT_PTR(m->sem); 00230 return rt_sem_wait_if(m->sem) > 0 ? 0 : -EAGAIN; 00231 } 00232 00233 int rtos_mutex_unlock( rt_mutex_t* m) 00234 { 00235 CHK_LXRT_CALL(); 00236 CHK_LXRT_PTR(m->sem); 00237 return rt_sem_signal(m->sem); 00238 } 00239 00240 int rtos_cond_init(rt_cond_t *cond) 00241 { 00242 CHK_LXRT_CALL(); 00243 cond->cond = rt_cond_init(0); 00244 return cond->cond == 0 ? -1 : 0; 00245 } 00246 00247 int rtos_cond_destroy(rt_cond_t *cond) 00248 { 00249 CHK_LXRT_CALL(); 00250 return rt_cond_delete(cond->cond); 00251 } 00252 00253 int rtos_cond_wait(rt_cond_t *cond, rt_mutex_t *mutex) 00254 { 00255 CHK_LXRT_CALL(); 00256 int ret = rt_cond_wait(cond->cond, mutex->sem ); 00257 if (ret == 0) 00258 return 0; 00259 return -1; 00260 } 00261 00262 int rtos_cond_timedwait(rt_cond_t *cond, rt_mutex_t *mutex, NANO_TIME abs_time) 00263 { 00264 CHK_LXRT_CALL(); 00265 int ret = rt_cond_wait_until(cond->cond, mutex->sem, nano2count(abs_time) ); 00266 if (ret == 0) 00267 return 0; 00268 if ( ret == SEM_TIMOUT ) 00269 return ETIMEDOUT; 00270 return -1; 00271 } 00272 00273 int rtos_cond_broadcast(rt_cond_t *cond) 00274 { 00275 CHK_LXRT_CALL(); 00276 return rt_cond_broadcast(cond->cond); 00277 } 00278 00279 int rtos_printf(const char *fmt, ...) 00280 { 00281 va_list list; 00282 char printkbuf [2000]; 00283 printkbuf[0] = '\0'; 00284 va_start (list, fmt); 00285 vsprintf(printkbuf, fmt, list); 00286 va_end (list); 00287 // XXX revert to print to screen when debugging is over 00288 return rtai_print_to_screen(printkbuf); 00289 //return printf(printkbuf); 00290 } 00291 00292 #endif // OROBLD_OS_AGNOSTIC 00293