00001
00026 #ifndef _RTAI_TASKLETS_H
00027 #define _RTAI_TASKLETS_H
00028
00033 #include <rtai_types.h>
00034
00035 #define TSKIDX 1
00036
00037 #define INIT 0
00038 #define DELETE 1
00039 #define TASK_INSERT 2
00040 #define TASK_REMOVE 3
00041 #define USE_FPU 4
00042 #define TIMER_INSERT 5
00043 #define TIMER_REMOVE 6
00044 #define SET_TASKLETS_PRI 7
00045 #define SET_FIR_TIM 8
00046 #define SET_PER 9
00047 #define SET_HDL 10
00048 #define SET_DAT 11
00049 #define EXEC_TASKLET 12
00050 #define WAIT_IS_HARD 13
00051 #define SET_TSK_PRI 14
00052 #define REG_TASK 15
00053
00054 struct rt_task_struct;
00055
00056 struct rt_tasklet_struct {
00057
00058 struct rt_tasklet_struct *next, *prev;
00059 int priority, uses_fpu;
00060 RTIME firing_time, period;
00061 void (*handler)(unsigned long);
00062 unsigned long data, id;
00063 int thread;
00064 struct rt_task_struct *task;
00065 struct rt_tasklet_struct *usptasklet;
00066 };
00067
00068 #ifdef __KERNEL__
00069
00070 #define STACK_SIZE 8196
00071
00072 #ifdef __cplusplus
00073 extern "C" {
00074 #endif
00075
00076 int __rtai_tasklets_init(void);
00077
00078 void __rtai_tasklets_exit(void);
00079
00080 struct rt_tasklet_struct *rt_init_tasklet(void);
00081
00082 int rt_delete_tasklet(struct rt_tasklet_struct *tasklet);
00083
00084 int rt_insert_tasklet(struct rt_tasklet_struct *tasklet,
00085 int priority,
00086 void (*handler)(unsigned long),
00087 unsigned long data,
00088 unsigned long id,
00089 int pid);
00090
00091 void rt_remove_tasklet(struct rt_tasklet_struct *tasklet);
00092
00093 struct rt_tasklet_struct *rt_find_tasklet_by_id(unsigned long id);
00094
00095 int rt_exec_tasklet(struct rt_tasklet_struct *tasklet);
00096
00097 void rt_set_tasklet_priority(struct rt_tasklet_struct *tasklet,
00098 int priority);
00099
00100 int rt_set_tasklet_handler(struct rt_tasklet_struct *tasklet,
00101 void (*handler)(unsigned long));
00102
00103 #define rt_fast_set_tasklet_handler(t, h) do { (t)->handler = (h); } while (0)
00104
00105 void rt_set_tasklet_data(struct rt_tasklet_struct *tasklet,
00106 unsigned long data);
00107
00108 #define rt_fast_set_tasklet_data(t, d) \
00109 do { \
00110 (t)->data = (d); \
00111 } while (0)
00112
00135 struct rt_task_struct *rt_tasklet_use_fpu(struct rt_tasklet_struct *tasklet,
00136 int use_fpu);
00137
00154 #define rt_init_timer rt_init_tasklet
00155
00172 #define rt_delete_timer rt_delete_tasklet
00173
00174 int rt_insert_timer(struct rt_tasklet_struct *timer,
00175 int priority,
00176 RTIME firing_time,
00177 RTIME period,
00178 void (*handler)(unsigned long),
00179 unsigned long data,
00180 int pid);
00181
00182 void rt_remove_timer(struct rt_tasklet_struct *timer);
00183
00184 void rt_set_timer_priority(struct rt_tasklet_struct *timer,
00185 int priority);
00186
00187 void rt_set_timer_firing_time(struct rt_tasklet_struct *timer,
00188 RTIME firing_time);
00189
00190 void rt_set_timer_period(struct rt_tasklet_struct *timer,
00191 RTIME period);
00192
00193 #define rt_fast_set_timer_period(t, p) \
00194 do { \
00195 (t)->period = (p); \
00196 } while (0)
00197
00221 #define rt_set_timer_handler rt_set_tasklet_handler
00222
00223 #define rt_fast_set_timer_handler(t, h) do { (t)->handler = (h); } while (0)
00224
00247 #define rt_set_timer_data rt_set_tasklet_data
00248
00249 #define rt_fast_set_timer_data(t, d) do { (t)->data = (d); } while (0)
00250
00251 #define rt_timer_use_fpu rt_tasklet_use_fpu
00252
00253 void rt_wait_tasklet_is_hard(struct rt_tasklet_struct *tasklet,
00254 int thread);
00255
00256 void rt_register_task(struct rt_tasklet_struct *tasklet,
00257 struct rt_tasklet_struct *usptasklet,
00258 struct rt_task_struct *task);
00259
00260 #ifdef __cplusplus
00261 }
00262 #endif
00263
00264 #else
00265
00266 #include <sys/types.h>
00267 #include <sys/mman.h>
00268 #include <stdarg.h>
00269 #include <pthread.h>
00270 #include <rtai_lxrt.h>
00271
00272 #ifndef __SUPPORT_TASKLET__
00273 #define __SUPPORT_TASKLET__
00274
00275 static void *support_tasklet(void *arg)
00276 {
00277 RT_TASK *task;
00278 struct rt_tasklet_struct *tasklet, usptasklet;
00279 struct { void *tasklet; void *handler; } upd;
00280
00281 upd.tasklet = tasklet = ((struct rt_tasklet_struct **)arg)[0];
00282 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
00283 if (!(task = rt_task_init_schmod((unsigned long)tasklet, 98, 0, 0, SCHED_FIFO, 0xF))) {
00284 printf("CANNOT INIT SUPPORT TASKLET\n");
00285 return (void *)1;
00286 }
00287
00288 {
00289 struct { struct rt_tasklet_struct *tasklet, *usptasklet; RT_TASK *task; } arg = { tasklet, &usptasklet, task };
00290 rtai_lxrt(TSKIDX, SIZARG, REG_TASK, &arg);
00291 }
00292
00293 mlockall(MCL_CURRENT | MCL_FUTURE);
00294
00295 rt_make_hard_real_time();
00296 while (1) {
00297 rt_task_suspend(task);
00298 if ((upd.handler = (void*)usptasklet.handler)) {
00299 rtai_lxrt(TSKIDX, SIZARG, SET_HDL, &upd);
00300 usptasklet.handler(usptasklet.data);
00301 } else {
00302 break;
00303 }
00304 }
00305 rt_make_soft_real_time();
00306
00307 rt_task_delete(task);
00308 return (void *)0;
00309 }
00310 #endif
00311
00312 #ifdef __cplusplus
00313 extern "C" {
00314 #endif
00315
00316 RTAI_PROTO(struct rt_tasklet_struct *, rt_init_tasklet,(void))
00317 {
00318 pthread_t thread;
00319 struct rt_tasklet_struct *tasklet;
00320
00321 {
00322 struct { int dummy; } arg = { 0 };
00323 tasklet = (struct rt_tasklet_struct*)rtai_lxrt(TSKIDX, SIZARG, INIT, &arg).v[LOW];
00324 }
00325
00326 pthread_create(&thread, NULL, support_tasklet, &tasklet);
00327
00328 {
00329 struct { struct rt_tasklet_struct *tasklet; pthread_t thread; } arg = { tasklet, thread };
00330 rtai_lxrt(TSKIDX, SIZARG, WAIT_IS_HARD, &arg);
00331 }
00332
00333 return tasklet;
00334 }
00335
00336 #define rt_init_timer rt_init_tasklet
00337
00338 RTAI_PROTO(void, rt_delete_tasklet,(struct rt_tasklet_struct *tasklet))
00339 {
00340 pthread_t thread;
00341 struct { struct rt_tasklet_struct *tasklet; } arg = { tasklet };
00342 if ((thread = (pthread_t)rtai_lxrt(TSKIDX, SIZARG, DELETE, &arg).i[LOW])) {
00343 pthread_join(thread, NULL);
00344 }
00345 }
00346
00347 #define rt_delete_timer rt_delete_tasklet
00348
00349 RTAI_PROTO(int, rt_insert_timer,(struct rt_tasklet_struct *timer,
00350 int priority,
00351 RTIME firing_time,
00352 RTIME period,
00353 void (*handler)(unsigned long),
00354 unsigned long data,
00355 int pid))
00356 {
00357 struct { struct rt_tasklet_struct *timer; int priority; RTIME firing_time;
00358 RTIME period; void (*handler)(unsigned long); unsigned long data; int pid; } arg =
00359 { timer, priority, firing_time, period, handler, data, pid };
00360 return rtai_lxrt(TSKIDX, SIZARG, TIMER_INSERT, &arg).i[LOW];
00361 }
00362
00363 RTAI_PROTO(void, rt_remove_timer,(struct rt_tasklet_struct *timer))
00364 {
00365 struct { struct rt_tasklet_struct *timer; } arg = { timer };
00366 rtai_lxrt(TSKIDX, SIZARG, TIMER_REMOVE, &arg);
00367 }
00368
00369 RTAI_PROTO(void, rt_set_timer_priority,(struct rt_tasklet_struct *timer, int priority))
00370 {
00371 struct { struct rt_tasklet_struct *timer; int priority; } arg = { timer, priority };
00372 rtai_lxrt(TSKIDX, SIZARG, SET_TASKLETS_PRI, &arg);
00373 }
00374
00375 RTAI_PROTO(void, rt_set_timer_firing_time,(struct rt_tasklet_struct *timer, RTIME firing_time))
00376 {
00377 struct { struct rt_tasklet_struct *timer; RTIME firing_time; } arg = { timer, firing_time };
00378 rtai_lxrt(TSKIDX, SIZARG, SET_FIR_TIM, &arg);
00379 }
00380
00381 RTAI_PROTO(void, rt_set_timer_period,(struct rt_tasklet_struct *timer, RTIME period))
00382 {
00383 struct { struct rt_tasklet_struct *timer; RTIME period; } arg = { timer, period };
00384 rtai_lxrt(TSKIDX, SIZARG, SET_PER, &arg);
00385 }
00386
00387 RTAI_PROTO(int, rt_set_tasklet_handler,(struct rt_tasklet_struct *tasklet, void (*handler)(unsigned long)))
00388 {
00389 struct { struct rt_tasklet_struct *tasklet; void (*handler)(unsigned long); } arg = { tasklet, handler };
00390 return rtai_lxrt(TSKIDX, SIZARG, SET_HDL, &arg).i[LOW];
00391 }
00392
00393 #define rt_set_timer_handler rt_set_tasklet_handler
00394
00395 RTAI_PROTO(void, rt_set_tasklet_data,(struct rt_tasklet_struct *tasklet, unsigned long data))
00396 {
00397 struct { struct rt_tasklet_struct *tasklet; unsigned long data; } arg = { tasklet, data };
00398 rtai_lxrt(TSKIDX, SIZARG, SET_DAT, &arg);
00399 }
00400
00401 #define rt_set_timer_data rt_set_tasklet_data
00402
00403 RTAI_PROTO(RT_TASK *, rt_tasklet_use_fpu,(struct rt_tasklet_struct *tasklet, int use_fpu))
00404 {
00405 RT_TASK *task;
00406 struct { struct rt_tasklet_struct *tasklet; int use_fpu; } arg = { tasklet, use_fpu };
00407 if ((task = (RT_TASK*)rtai_lxrt(TSKIDX, SIZARG, USE_FPU, &arg).v[LOW])) {
00408 rt_task_use_fpu(task, use_fpu);
00409 }
00410 return task;
00411 }
00412
00413 #define rt_timer_use_fpu rt_tasklet_use_fpu
00414
00415 RTAI_PROTO(int, rt_insert_tasklet,(struct rt_tasklet_struct *tasklet,
00416 int priority,
00417 void (*handler)(unsigned long),
00418 unsigned long data,
00419 unsigned long id,
00420 int pid))
00421 {
00422 struct { struct rt_tasklet_struct *tasklet; int priority; void (*handler)(unsigned long);
00423 unsigned long data; unsigned long id; int pid; } arg = { tasklet, priority, handler, data, id, pid };
00424 return rtai_lxrt(TSKIDX, SIZARG, TASK_INSERT, &arg).i[LOW];
00425 }
00426
00427 RTAI_PROTO(void, rt_set_tasklet_priority,(struct rt_tasklet_struct *tasklet, int priority))
00428 {
00429 struct { struct rt_tasklet_struct *tasklet; int priority; } arg = { tasklet, priority };
00430 rtai_lxrt(TSKIDX, SIZARG, SET_TSK_PRI, &arg);
00431 }
00432
00433 RTAI_PROTO(void, rt_remove_tasklet,(struct rt_tasklet_struct *tasklet))
00434 {
00435 struct { struct rt_tasklet_struct *tasklet; } arg = { tasklet };
00436 rtai_lxrt(TSKIDX, SIZARG, TASK_REMOVE, &arg);
00437 }
00438
00439 RTAI_PROTO(int, rt_exec_tasklet,(struct rt_tasklet_struct *tasklet))
00440 {
00441 struct { struct rt_tasklet_struct *tasklet; } arg = { tasklet };
00442 return rtai_lxrt(TSKIDX, SIZARG, EXEC_TASKLET, &arg).i[LOW];
00443 }
00444
00445 #ifdef __cplusplus
00446 }
00447 #endif
00448
00449 #endif
00450
00453 #endif