Orocos Real-Time Toolkit  2.9.0
fosi_internal.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag:
3 
4  fosi_internal.hpp - description
5  -------------------
6  begin : Jan 21 2006
7  copyright : (C) 2006 Klaas Gadeyne
8  email : firstname lastname at fmtc be
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU Lesser General Public *
13  * License as published by the Free Software Foundation; either *
14  * version 2.1 of the License, or (at your option) any later version. *
15  * *
16  * This library is distributed in the hope that it will be useful, *
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
19  * Lesser General Public License for more details. *
20  * *
21  * You should have received a copy of the GNU Lesser General Public *
22  * License along with this library; if not, write to the Free Software *
23  * Foundation, Inc., 59 Temple Place, *
24  * Suite 330, Boston, MA 02111-1307 USA *
25  * *
26  ***************************************************************************/
27 
28 
29 #include <pkgconf/kernel.h>
30 #include <pkgconf/os_ecos.h>
31 #include "ThreadInterface.hpp"
32 #include "fosi.h"
33 #include "../fosi_internal_interface.hpp"
34 #include <cyg/kernel/kapi.h>
35 #include <iostream>
36 #include <string>
37 
38 #define INTERNAL_QUAL
39 
40 namespace RTT
41 {
42  namespace os {
44  {
45  const char* name = "main";
46  main_task->name = strcpy( (char*)malloc( (strlen(name) + 1) * sizeof(char)), name);
47  return 0;
48  }
49 
51  {
52  free(main_task->name);
53  main_task->name = NULL;
54  return 0;
55  }
56 
57 
59  int priority,
60  unsigned cpu_affinity,
61  const char * name,
62  int sched_type,
63  size_t stack_size,
64  void * (*start_routine)(void *),
65  ThreadInterface* obj) {
66  /* sched_type is unused in eCos */
67  // Allocate room for threads name
68  if ( strlen(name) == 0 )
69  name = "Thread";
70  task->name = strcpy( (char*)malloc( (strlen(name) + 1) * sizeof(char)), name);
71 
72  // Allocate necessary stack...
73  task->stack = (char *)malloc(stack_size?stack_size:OROSEM_OS_ECOS_STACK_SIZE);
74 
75  // Create the thread
76  cyg_thread_create((cyg_addrword_t) priority, // priority
77  (cyg_thread_entry_t *) start_routine, // Entry point
78  (cyg_addrword_t) obj, // Entry point data
79  task->name, // Name
80  task->stack, // the stack
81  OROSEM_OS_ECOS_STACK_SIZE, // stacksize
82  &(task->handle),
83  &(task->thread));
84  // Start in fake Soft Real-Time mode
85  task->hrt = false;
86  // initialize the rest to zero
87  task->periodMark = 0;
88  task->period = 0;
89  task->counter_hdl = 0;
90  task->alarm_hdl = 0;
91  // Resume (start) thread
92  cyg_thread_resume(task->handle);
93  return 0;
94  }
95 
97  cyg_thread_yield();
98  }
99 
100  INTERNAL_QUAL void wakeup_handler(cyg_handle_t alarm_handle,cyg_addrword_t data)
101  {
102  cyg_sem_t * wakeup_sem = (cyg_sem_t *) data;
103  cyg_semaphore_post(wakeup_sem);
104  }
105 
107  {
108  if (nanosecs != 0)
109  { // Init stuff (fixme, better check if only called once?)
110  // diag_printf("fosi_internal.hpp rtos_task_make_periodic() ticks = %d...\n",nano2ticks(nanosecs));
111  // Get handle to system clock
112  mytask->sys_clk_hdl = cyg_real_time_clock();
113  // Convert clock to counter handle
114  cyg_clock_to_counter(mytask->sys_clk_hdl,&(mytask->counter_hdl));
115  // Initialise semaphore
116  cyg_semaphore_init(&(mytask->wakeup_sem),0);
117  cyg_alarm_create(mytask->counter_hdl,
119  (cyg_addrword_t) (&(mytask->wakeup_sem)),
120  &(mytask->alarm_hdl),
121  &(mytask->alarm_obj));
122  // set next wake-up time.
123  cyg_alarm_initialize(mytask->alarm_hdl,
124  rtos_get_time_ticks() + nano2ticks(nanosecs),
125  nano2ticks(nanosecs));
126  } else /* period is zero */ {
127  // Check if alarm already created...
128  if (mytask->alarm_hdl != 0) {
129  // diag_printf("fosi_internal.hpp rtos_task_set_period() WARNING: Disabling alarm...\n");
130  cyg_alarm_disable(mytask->alarm_hdl);
131  }
132 
133  // set period
134  mytask->period = nanosecs;
135  }
136 
137  INTERNAL_QUAL void rtos_task_set_period( RTOS_TASK* mytask, NANO_TIME nanosecs )
138  {
139  mytask->period = nanosecs;
140  // FIXME:: Can one reinitialize an alarm??
141  // diag_printf("fosi_internal.hpp WARNING: Can one reinitialize an alarm??\n");
142  if (nanosecs != 0){
143  // Check if alarm already created...
144  if (mytask->alarm_hdl == 0){
145  // diag_printf("fosi_internal.hpp rtos_task_set_period() WARNING: Alarm not yet initialized, doing this now...\n");
146  rtos_task_make_periodic(mytask,nanosecs);
147  }
148  else {
149  cyg_alarm_initialize(mytask->alarm_hdl,
150  rtos_get_time_ticks() + nano2ticks(nanosecs),
151  nano2ticks(nanosecs));
152  // diag_printf("fosi_internal.hpp rtos_task_set_period() Setting period to %d ticks...\n",nano2ticks(nanosecs));
153  // FIXME need call to cyg_alarm_enable here, or is this
154  // "included" in initialize??
155  }
156  }
157  else /* period is zero */ {
158  // Check if alarm already created...
159  if (mytask->alarm_hdl != 0) {
160  // diag_printf("fosi_internal.hpp rtos_task_set_period() WARNING: Disabling alarm...\n");
161  cyg_alarm_disable(mytask->alarm_hdl);
162  }
163  }
164  }
165 
167  {
168  // Do nothing
169  }
170 
172  {
173  cyg_semaphore_wait(&(task->wakeup_sem));
174  // should be used to detect overruns
175  return 0;
176  }
177 
179  // Free name
180  free(mytask->name);
181  mytask->name = NULL;
182  // KG: Peter does not check return values, it appears...
183  bool succeed = cyg_thread_delete(mytask->handle);
184  if (succeed == false)
185  diag_printf("cyg_thread_delete: Error deleting task\n");
186  // Free stack space
187  free(mytask->stack);
188  }
189 
190  // for both SingleTread and PeriodicThread
191  INTERNAL_QUAL const char * rtos_task_get_name(const RTOS_TASK* t)
192  {
193  cyg_thread_info info;
194  bool succeed = cyg_thread_get_info(t->handle,cyg_thread_get_id(t->handle),&info);
195  if (succeed == false) {
196  diag_printf("fosi_internal.hpp rtos_task_get_name() WARNING: cyg_thread_get_info returned false...\n");
197  return "(destroyed)";
198  }
199  return info.name;
200  }
201 
202  INTERNAL_QUAL int rtos_task_set_priority(RTOS_TASK *t, int priority)
203  {
204  cyg_thread_set_priority(t->handle,(cyg_priority_t) priority);
205  return int(cyg_thread_get_priority(t->handle)) == priority ? 0 : 1;
206  }
207 
209  {
210  return (int) cyg_thread_get_priority(t->handle);
211  }
212 
213  INTERNAL_QUAL int rtos_task_set_cpu_affinity(RTOS_TASK * task, unsigned cpu_affinity)
214  {
215  return -1;
216  }
217 
219  {
220  return ~0;
221  }
222 
223  INTERNAL_QUAL unsigned int rtos_task_get_pid(const RTOS_TASK* task)
224  {
225  return 0;
226  }
227 
228  INTERNAL_QUAL int rtos_task_set_scheduler(RTOS_TASK* t, int sched_type) {
229  if (sched_type == SCHED_ECOS_FIFO )
230  return 0;
231  return -1;
232  }
233 
234  INTERNAL_QUAL int rtos_task_get_scheduler(const RTOS_TASK* mytask) {
235  return SCHED_ECOS_FIFO;
236  }
237 
238  INTERNAL_QUAL int rtos_task_check_scheduler(int* scheduler)
239  {
240  if (*scheduler != SCHED_ECOS_FIFO )
241  log(Error) << "Unknown scheduler type." <<endlog();
242  *scheduler = SCHED_ECOS_FIFO;
243  return -1;
244  }
245  return 0;
246  }
247 
248  INTERNAL_QUAL int rtos_task_check_priority(int* scheduler, int* priority)
249  {
250  int ret = 0;
251  ret = rtos_task_check_scheduler(&scheduler);
252 
253  // FIXME: what are the valid priority ranges ???
254 
255  return ret;
256  }
257 
258 
259 
260 
261 
262 
263  }
264 }
265 #undef INTERNAL_QUAL
266 
long long NANO_TIME
Definition: fosi.h:55
int rtos_task_get_priority(const RTOS_TASK *task)
Return the priority of a thread.
INTERNAL_QUAL void rtos_task_make_periodic(RTOS_TASK *mytask, NANO_TIME nanosecs)
This function is to inform the RTOS that a thread is switching between periodic or non-periodic execu...
INTERNAL_QUAL int rtos_task_check_priority(int *scheduler, int *priority)
This function checks (and corrects) a given priority within a given scheduler type.
#define INTERNAL_QUAL
cyg_handle_t handle
Definition: fosi.h:69
unsigned int rtos_task_get_pid(const RTOS_TASK *task)
Returns the process ID the OS gave to the task task.
bool hrt
Definition: fosi.h:77
cyg_handle_t sys_clk_hdl
Definition: fosi.h:86
char * name
Definition: fosi.h:66
INTERNAL_QUAL int rtos_task_delete_main(RTOS_TASK *main_task)
Cleanup the main thread.
int rtos_task_set_scheduler(RTOS_TASK *t, int sched_type)
Set the scheduler of a given task t to a the type sched_type.
cyg_sem_t wakeup_sem
Definition: fosi.h:89
int rtos_task_set_cpu_affinity(RTOS_TASK *task, unsigned cpu_affinity)
Set the cpu affinity of a thread.
unsigned rtos_task_get_cpu_affinity(const RTOS_TASK *task)
Return the cpu affinity of a thread.
cyg_thread thread
Definition: fosi.h:64
#define OROSEM_OS_ECOS_STACK_SIZE
Definition: os_ecos.h:43
#define SCHED_ECOS_FIFO
Definition: fosi.h:48
NANO_TIME periodMark
Definition: fosi.h:82
A thread which is being run.
cyg_alarm alarm_obj
Definition: fosi.h:88
void rtos_task_set_wait_period_policy(RTOS_TASK *task, int policy)
Set the wait policy of a thread.
void rtos_task_delete(RTOS_TASK *mytask)
This function must join the thread created with rtos_task_create and then clean up the RTOS_TASK stru...
int rtos_task_set_priority(RTOS_TASK *task, int priority)
Set the priority of a thread.
const char * rtos_task_get_name(const RTOS_TASK *task)
Returns the name by which a task is known in the RTOS.
int rtos_task_check_scheduler(int *sched_type)
This function checks (and corrects) if the given sched_type is valid for this RTOS.
int rtos_task_wait_period(RTOS_TASK *task)
This function is called by a periodic thread which wants to go to sleep and wake up the next period...
TICK_TIME rtos_get_time_ticks(void)
Get "system" time in ticks FIXME see https://proj.fmtc.be/orocos-bugzilla/show_bug.cgi?id=60
Definition: fosi.h:118
char * stack
Definition: fosi.h:72
INTERNAL_QUAL void rtos_task_yield(RTOS_TASK *)
Yields the current thread.
TICK_TIME nano2ticks(NANO_TIME nano)
Time conversions from nano seconds to system ticks.
Definition: fosi.h:100
cyg_handle_t alarm_hdl
Definition: fosi.h:87
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:52
INTERNAL_QUAL int rtos_task_create_main(RTOS_TASK *main_task)
Initialise the main thread.
NANO_TIME period
Definition: fosi.h:84
void rtos_task_set_period(RTOS_TASK *mytask, NANO_TIME nanosecs)
Change the period of a periodic RTOS task.
cyg_handle_t counter_hdl
Definition: fosi.h:85
Definition: fosi.h:62
INTERNAL_QUAL int rtos_task_create(RTOS_TASK *task, int priority, unsigned cpu_affinity, const char *name, int sched_type, size_t stack_size, void *(*start_routine)(void *), ThreadInterface *obj)
Create a thread.
INTERNAL_QUAL void wakeup_handler(cyg_handle_t alarm_handle, cyg_addrword_t data)
int rtos_task_get_scheduler(const RTOS_TASK *t)
Returns the current scheduler set for task t.