00001 /*************************************************************************** 00002 tag: 00003 00004 fosi.hpp - description 00005 ------------------- 00006 begin : Jan 21 2006 00007 copyright : (C) 2006 Klaas Gadeyne 00008 email : firstname lastname at fmtc be 00009 00010 *************************************************************************** 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU Lesser General Public * 00013 * License as published by the Free Software Foundation; either * 00014 * version 2.1 of the License, or (at your option) any later version. * 00015 * * 00016 * This library is distributed in the hope that it will be useful, * 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00019 * Lesser General Public License for more details. * 00020 * * 00021 * You should have received a copy of the GNU Lesser General Public * 00022 * License along with this library; if not, write to the Free Software * 00023 * Foundation, Inc., 59 Temple Place, * 00024 * Suite 330, Boston, MA 02111-1307 USA * 00025 * * 00026 ***************************************************************************/ 00027 00028 #ifndef RTT_ECOS__FOSI_H 00029 #define RTT_ECOS__FOSI_H 00030 00031 #define HAVE_FOSI_API 00032 00033 #ifdef __cplusplus 00034 extern "C" 00035 { 00036 #endif 00037 00038 #include <stdio.h> 00039 #include <cyg/kernel/kapi.h> 00040 // #include <errno.h> 00041 #include "os_ecos.h" 00042 #include <pkgconf/kernel.h> 00043 #include <cyg/infra/diag.h> // for diag_printf 00044 00045 // Own implementation of recursive mutexes 00046 #include "ecos_rec_mutex.h" 00047 00048 #define SCHED_ECOS_FIFO 0 00049 #define ORO_SCHED_RT 0 00050 #define ORO_SCHED_OTHER 0 00051 00052 typedef long long NANO_TIME; 00053 typedef cyg_tick_count_t TICK_TIME; 00054 00055 const TICK_TIME InfiniteTicks = ULONG_LONG_MAX; 00056 const NANO_TIME InfiniteNSecs = LONG_LONG_MAX; 00057 const double InfiniteSeconds = DBL_MAX; 00058 00059 typedef struct { 00060 // the thread 00061 cyg_thread thread; 00062 // its name 00063 char * name; 00064 00065 // And its handle 00066 cyg_handle_t handle; 00067 00068 // Stack pointer 00069 char * stack; 00070 00071 /* bool to fake soft or hard RT behaviour (ecos does not 00072 differentiate between hard and soft realtime) 00073 */ 00074 bool hrt; 00075 00076 // STUFF for periodic threads (ecos has no native API for creating 00077 // periodic threads) 00078 // Next firetime 00079 NANO_TIME periodMark; 00080 // the period 00081 NANO_TIME period; 00082 cyg_handle_t counter_hdl; 00083 cyg_handle_t sys_clk_hdl; 00084 cyg_handle_t alarm_hdl; 00085 cyg_alarm alarm_obj; 00086 cyg_sem_t wakeup_sem; 00087 } RTOS_TASK; 00088 00089 00090 // Time Related 00091 #include <time.h> 00092 #include <unistd.h> 00093 00094 typedef struct timespec TIME_SPEC; 00095 00096 inline 00097 TICK_TIME nano2ticks( NANO_TIME nano ) 00098 { 00099 // FIXME need more efficient calculation... 00100 return (CYGNUM_HAL_RTC_DENOMINATOR*nano)/CYGNUM_HAL_RTC_NUMERATOR; 00101 } 00102 00103 inline 00104 NANO_TIME ticks2nano( TICK_TIME count ) 00105 { 00106 // FIXME need more efficient calculation... 00107 return CYGNUM_HAL_RTC_NUMERATOR/CYGNUM_HAL_RTC_DENOMINATOR*count; 00108 } 00109 00110 inline NANO_TIME rtos_get_time_ns( void ) 00111 { 00112 return ticks2nano(cyg_current_time()); 00113 } 00114 00115 inline TICK_TIME rtos_get_time_ticks( void ) 00116 { 00117 return cyg_current_time(); 00118 } 00119 00120 /* 00121 inline int rtos_nanosleep( const TIME_SPEC * rqtp, TIME_SPEC * rmtp ) 00122 { 00123 // return usleep(rqtp->tv_nsec/1000L); 00124 return nanosleep( rqtp, rmtp ); 00125 } 00126 */ 00127 00128 typedef cyg_sem_t rt_sem_t; 00129 00130 static inline int rtos_sem_init(rt_sem_t* m, int value ) 00131 { 00132 cyg_semaphore_init(m, value); 00133 return 0; 00134 } 00135 00136 static inline int rtos_sem_destroy(rt_sem_t* m ) 00137 { 00138 cyg_semaphore_destroy(m); 00139 return 0; 00140 } 00141 00142 static inline int rtos_sem_signal(rt_sem_t* m ) 00143 { 00144 cyg_semaphore_post(m); 00145 return 0; 00146 } 00147 00148 static inline int rtos_sem_wait(rt_sem_t* m ) 00149 { 00150 cyg_semaphore_wait(m); 00151 return 0; 00152 } 00153 00154 // Should return 0 if no timeout occurs 00155 static inline int rtos_sem_trywait(rt_sem_t* m ) 00156 { 00157 if (cyg_semaphore_trywait(m) == true) 00158 return 0; 00159 else 00160 return -1; 00161 } 00162 00163 // Should return 0 if no timeout occurs 00164 static inline int rtos_sem_wait_timed(rt_sem_t* m, NANO_TIME delay ) 00165 { 00166 // cyg_semaphore_timed_wait returns true if no timeout occurs 00167 if (cyg_semaphore_timed_wait(m,cyg_current_time()+nano2ticks(delay)) == true) 00168 return 0; 00169 else 00170 return -1; 00171 } 00172 00173 static inline int rtos_sem_value(rt_sem_t* m ) 00174 { 00175 int val = 0; 00176 cyg_semaphore_peek(m, &val); 00177 return val; 00178 } 00179 00180 // Mutex functions 00181 00182 typedef cyg_mutex_t rt_mutex_t; 00183 typedef cyg_recursive_mutex_t rt_rec_mutex_t; 00184 00185 // 00186 static inline int rtos_mutex_init(rt_mutex_t* m) 00187 { 00188 cyg_mutex_init(m); 00189 return 0; 00190 } 00191 00192 static inline int rtos_mutex_destroy(rt_mutex_t* m ) 00193 { 00194 cyg_mutex_release(m); 00195 cyg_mutex_destroy(m); 00196 return 0; 00197 } 00198 00199 static inline int rtos_mutex_rec_init(rt_rec_mutex_t* m) 00200 { 00201 cyg_recursive_mutex_init(m); 00202 return 0; 00203 } 00204 00205 static inline int rtos_mutex_rec_destroy(rt_rec_mutex_t* m ) 00206 { 00207 cyg_recursive_mutex_destroy(m); 00208 return 0; 00209 } 00210 00211 static inline int rtos_mutex_lock( rt_mutex_t* m) 00212 { 00213 return cyg_mutex_lock(m); 00214 } 00215 00216 static inline int rtos_mutex_rec_lock( rt_rec_mutex_t* m) 00217 { 00218 return cyg_recursive_mutex_lock(m); 00219 } 00220 00221 static inline int rtos_mutex_trylock( rt_mutex_t* m) 00222 { 00223 if (cyg_mutex_trylock(m) == true) 00224 return 0; 00225 else 00226 return -1; 00227 } 00228 00229 static inline int rtos_mutex_rec_trylock( rt_rec_mutex_t* m) 00230 { 00231 if (cyg_recursive_mutex_trylock(m) == true) 00232 return 0; 00233 else 00234 return -1; 00235 } 00236 00237 static inline int rtos_mutex_unlock( rt_mutex_t* m) 00238 { 00239 cyg_mutex_unlock(m); 00240 return 0; 00241 } 00242 00243 static inline int rtos_mutex_rec_unlock( rt_rec_mutex_t* m) 00244 { 00245 cyg_recursive_mutex_unlock(m); 00246 return 0; 00247 } 00248 00249 static inline void rtos_enable_rt_warning() 00250 { 00251 } 00252 00253 static inline void rtos_disable_rt_warning() 00254 { 00255 } 00256 00257 #define rtos_printf diag_printf 00258 00259 #ifdef __cplusplus 00260 } 00261 00262 #endif 00263 #endif