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 #include "../ThreadInterface.hpp"
00035 #include "fosi.h"
00036 #include "../fosi_internal_interface.hpp"
00037 #include "../../Logger.hpp"
00038 #include <cassert>
00039 #include "../Mutex.hpp"
00040
00041 #define INTERNAL_QUAL
00042
00043 namespace RTT
00044 { namespace os {
00045
00046 INTERNAL_QUAL int rtos_task_create_main(RTOS_TASK* main_task)
00047 {
00048 const char* name = "main";
00049 main_task->name = strcpy( (char*)malloc( (strlen(name) + 1) * sizeof(char)), name);
00050 main_task->thread = pthread_self();
00051 pthread_attr_init( &(main_task->attr) );
00052 struct sched_param sp;
00053 sp.sched_priority=0;
00054
00055
00056 pthread_attr_setschedparam(&(main_task->attr), &sp);
00057 main_task->priority = sp.sched_priority;
00058 main_task->wait_policy = ORO_WAIT_ABS;
00059 return 0;
00060 }
00061
00062 INTERNAL_QUAL int rtos_task_delete_main(RTOS_TASK* main_task)
00063 {
00064 pthread_attr_destroy( &(main_task->attr) );
00065 free( main_task->name );
00066 return 0;
00067 }
00068
00069 INTERNAL_QUAL int rtos_task_create(RTOS_TASK* task,
00070 int priority,
00071 unsigned cpu_affinity,
00072 const char * name,
00073 int sched_type,
00074 size_t stack_size,
00075 void * (*start_routine)(void *),
00076 ThreadInterface* obj)
00077 {
00078 int rv;
00079 rtos_task_check_priority( &sched_type, &priority );
00080
00081
00082 task->priority = priority;
00083 task->wait_policy = ORO_WAIT_ABS;
00084
00085
00086 if ( strlen(name) == 0 )
00087 name = "Thread";
00088 task->name = strcpy( (char*)malloc( (strlen(name) + 1) * sizeof(char)), name);
00089
00090 if ( (rv = pthread_attr_init(&(task->attr))) != 0 ){
00091 return rv;
00092 }
00093
00094 if ( (rv = pthread_attr_setschedpolicy(&(task->attr), sched_type)) != 0){
00095 return rv;
00096 }
00097 pthread_attr_getschedpolicy(&(task->attr), &rv );
00098 assert( rv == sched_type );
00099
00100 struct sched_param sp;
00101 sp.sched_priority=priority;
00102
00103 if ( (rv = pthread_attr_setschedparam(&(task->attr), &sp)) != 0 ){
00104 return rv;
00105 }
00106 rv = pthread_create(&(task->thread), &(task->attr), start_routine, obj);
00107 log(Debug) <<"Created Posix thread "<< task->thread <<endlog();
00108 return rv;
00109 }
00110
00111 INTERNAL_QUAL void rtos_task_yield(RTOS_TASK* t)
00112 {
00113 int ret = sched_yield();
00114 if ( ret != 0)
00115 perror("rtos_task_yield");
00116 }
00117
00118 INTERNAL_QUAL int rtos_task_is_self(const RTOS_TASK* task) {
00119 pthread_t self = pthread_self();
00120 if ( pthread_equal(self, task->thread) == 0 )
00121 return 0;
00122 return 1;
00123 }
00124
00125
00126 INTERNAL_QUAL int rtos_task_set_scheduler(RTOS_TASK* task, int sched_type)
00127 {
00128 int policy = -1;
00129 struct sched_param param;
00130
00131 if ( task && task->thread != 0 && rtos_task_check_scheduler( &sched_type) == -1 )
00132 return -1;
00133
00134 if (pthread_getschedparam(task->thread, &policy, ¶m) == 0) {
00135
00136 param.sched_priority = task->priority;
00137 rtos_task_check_priority( &sched_type, ¶m.sched_priority );
00138
00139 return pthread_setschedparam( task->thread, sched_type, ¶m);
00140 }
00141 return -1;
00142 }
00143
00144 INTERNAL_QUAL int rtos_task_get_scheduler(const RTOS_TASK* task)
00145 {
00146 int policy = -1;
00147 struct sched_param param;
00148
00149 if ( task && task->thread != 0 && pthread_getschedparam(task->thread, &policy, ¶m) == 0)
00150 return policy;
00151 return -1;
00152 }
00153
00154 INTERNAL_QUAL void rtos_task_make_periodic(RTOS_TASK* mytask, NANO_TIME nanosecs )
00155 {
00156
00157 mytask->period = nanosecs;
00158
00159 mytask->periodMark = rtos_get_time_ns() + nanosecs;
00160 }
00161
00162 INTERNAL_QUAL void rtos_task_set_period( RTOS_TASK* mytask, NANO_TIME nanosecs )
00163 {
00164 mytask->period = nanosecs;
00165 mytask->periodMark = rtos_get_time_ns() + nanosecs;
00166 }
00167
00168 INTERNAL_QUAL void rtos_task_set_wait_period_policy( RTOS_TASK* task, int policy )
00169 {
00170 task->wait_policy = policy;
00171 }
00172
00173 INTERNAL_QUAL int rtos_task_wait_period( RTOS_TASK* task )
00174 {
00175 if ( task->period == 0 )
00176 return 0;
00177
00178
00179
00180 NANO_TIME timeRemaining = task->periodMark - rtos_get_time_ns();
00181
00182
00183 if (task->wait_policy == ORO_WAIT_ABS)
00184 {
00185 task->periodMark += task->period;
00186 }
00187 else
00188 {
00189 task->periodMark = rtos_get_time_ns() + task->period;
00190 }
00191
00192 if ( timeRemaining > 0 ) {
00193
00194 TIME_SPEC ts( ticks2timespec( timeRemaining ) );
00195 rtos_nanosleep( &ts , NULL );
00196 return 0;
00197 }
00198
00199 return -1;
00200 }
00201
00202 INTERNAL_QUAL void rtos_task_delete(RTOS_TASK* mytask)
00203 {
00204 pthread_join( mytask->thread, 0);
00205 pthread_attr_destroy( &(mytask->attr) );
00206 free(mytask->name);
00207 }
00208
00209 INTERNAL_QUAL int rtos_task_check_scheduler(int* scheduler)
00210 {
00211 if (*scheduler != SCHED_OTHER && *scheduler != SCHED_FIFO && *scheduler != SCHED_RR ) {
00212 log(Error) << "Unknown scheduler type." <<endlog();
00213 *scheduler = SCHED_OTHER;
00214 return -1;
00215 }
00216 return 0;
00217 }
00218
00219 INTERNAL_QUAL int rtos_task_check_priority(int* scheduler, int* priority)
00220 {
00221 int ret = 0;
00222
00223 ret = rtos_task_check_scheduler(scheduler);
00224
00225 if (*priority < 0){
00226 log(Warning) << "Forcing priority ("<<*priority<<") of thread to 0." <<endlog();
00227 *priority = 0;
00228 ret = -1;
00229 }
00230 if (*priority > 63){
00231 log(Warning) << "Forcing priority ("<<*priority<<") of thread to 63." <<endlog();
00232 *priority = 63;
00233 ret = -1;
00234 }
00235 return ret;
00236 }
00237
00238 INTERNAL_QUAL int rtos_task_set_priority(RTOS_TASK * task, int priority)
00239 {
00240 int policy = 0;
00241 struct sched_param param;
00242
00243 if( task && task->thread != 0 && pthread_getschedparam(task->thread, &policy, ¶m) == 0) {
00244 if ( rtos_task_check_priority( &policy, &priority ) != 0 )
00245 return -1;
00246 param.sched_priority = priority;
00247 task->priority = priority;
00248
00249 return pthread_setschedparam( task->thread, policy, ¶m);
00250 }
00251 return -1;
00252 }
00253
00254 INTERNAL_QUAL int rtos_task_get_priority(const RTOS_TASK *task)
00255 {
00256
00257 int policy = 0;
00258 struct sched_param param;
00259
00260 if ( task == 0 )
00261 return -1;
00262 if ( task->thread == 0 || pthread_getschedparam(task->thread, &policy, ¶m) != 0)
00263 return task->priority;
00264 return param.sched_priority;
00265 }
00266
00267 INTERNAL_QUAL int rtos_task_set_cpu_affinity(RTOS_TASK * task, unsigned cpu_affinity)
00268 {
00269 return -1;
00270 }
00271
00272 INTERNAL_QUAL unsigned rtos_task_get_cpu_affinity(const RTOS_TASK *task)
00273 {
00274 return ~0;
00275 }
00276
00277 INTERNAL_QUAL const char * rtos_task_get_name(const RTOS_TASK* task)
00278 {
00279 return task->name;
00280 }
00281
00282 }
00283 }
00284
00285
00286 typedef struct rt_mutex_impl_t
00287 {
00288 RTT::os::Mutex mutex;
00289 };
00290
00291 int rtos_mutex_init(rt_mutex_t* m)
00292 {
00293 assert(m);
00294 *m = new rt_mutex_impl_t;
00295 return (0 != (*m));
00296 }
00297
00298 int rtos_mutex_destroy(rt_mutex_t* m )
00299 {
00300 assert(m);
00301 assert(*m);
00302 delete (*m);
00303 (*m) = 0;
00304 return 0;
00305 }
00306
00307 int rtos_mutex_lock( rt_mutex_t* m)
00308 {
00309 assert(m);
00310 assert(*m);
00311 (*m)->mutex.lock();
00312 return 0;
00313 }
00314
00315 int rtos_mutex_unlock( rt_mutex_t* m)
00316 {
00317 assert(m);
00318 assert(*m);
00319 (*m)->mutex.unlock();
00320 return 0;
00321 }
00322
00323 #undef INTERNAL_QUAL