Orocos Real-Time Toolkit  2.6.0
fosi.h
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