rtai_signal.h
1 /* 2 * Copyright (C) 2006 Paolo Mantegazza <mantegazza@aero.polimi.it> 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 17 * 18 */ 19 20 #ifndef _RTAI_SIGNAL_H_ 21 #define _RTAI_SIGNAL_H_ 22 23 #define RTAI_SIGNALS_IDX BIDX 24 25 #include <rtai_sched.h> 26 27 #define MAXSIGNALS 16 28 29 #define SIGNAL_TASK_INIPRIO 0 30 31 struct rt_signal_t { unsigned long flags; RT_TASK *sigtask; }; 32 33 struct sigsuprt_t { RT_TASK *sigtask; RT_TASK *task; long signal; void (*sighdl)(long, RT_TASK *); unsigned long cpuid; }; 34 35 #ifdef __KERNEL__ 36 37 #define SIGNAL_ENBIT 0 38 #define SIGNAL_PNDBIT 1 39 40 #define SIGNAL_TASK_STACK_SIZE 8192 41 42 RTAI_SYSCALL_MODE int rt_signal_helper(RT_TASK *task); 43 44 int rt_request_signal(long signal, void (*sighdl)(long, RT_TASK *)); 45 46 RTAI_SYSCALL_MODE int rt_request_signal_(RT_TASK *sigtask, RT_TASK *task, long signal); 47 48 RTAI_SYSCALL_MODE int rt_release_signal(long signal, RT_TASK *task); 49 50 RTAI_SYSCALL_MODE void rt_enable_signal(long signal, RT_TASK *task); 51 52 RTAI_SYSCALL_MODE void rt_disable_signal(long signal, RT_TASK *task); 53 54 RTAI_SYSCALL_MODE void rt_trigger_signal(long signal, RT_TASK *task); 55 56 RTAI_SYSCALL_MODE int rt_wait_signal(RT_TASK *sigtask, RT_TASK *task); 57 58 #else /* !__KERNEL__ */ 59 60 #include <sys/mman.h> 61 62 #include <rtai_lxrt.h> 63 64 #define SIGNAL_TASK_STACK_SIZE 64*1024 65 66 #ifndef __SIGNAL_SUPPORT_FUN__ 67 #define __SIGNAL_SUPPORT_FUN__ 68 69 static void signal_suprt_fun(struct sigsuprt_t *funarg) 70 { 71 struct sigtsk_t { RT_TASK *sigtask; RT_TASK *task; }; 72 struct sigreq_t { RT_TASK *sigtask; RT_TASK *task; long signal; void (*sighdl)(int, RT_TASK *); }; 73 struct sigsuprt_t arg = *funarg; 74 75 if ((arg.sigtask = rt_thread_init(rt_get_name(0), SIGNAL_TASK_INIPRIO, 0, SCHED_FIFO, 1 << arg.cpuid))) { 76 if (!rtai_lxrt(RTAI_SIGNALS_IDX, sizeof(struct sigreq_t), RT_SIGNAL_REQUEST, &arg).i[LOW]) { 77 rt_grow_and_lock_stack(SIGNAL_TASK_STACK_SIZE/2); 78 rt_make_hard_real_time(); 79 while (rtai_lxrt(RTAI_SIGNALS_IDX, sizeof(struct sigtsk_t), RT_SIGNAL_WAITSIG, &arg).i[LOW]) { 80 arg.sighdl(arg.signal, arg.task); 81 } 82 rt_make_soft_real_time(); 83 } 84 rt_task_delete(arg.sigtask); 85 } 86 } 87 88 #endif /* __SIGNAL_SUPPORT_FUN__ */ 89 90 RTAI_PROTO(int, rt_request_signal, (long signal, void (*sighdl)(long, RT_TASK *))) 91 { 92 if (signal >= 0 && sighdl) { 93 struct sigsuprt_t arg = { NULL, rt_buddy(), signal, sighdl }; 94 arg.cpuid = rtai_lxrt(RTAI_SIGNALS_IDX, sizeof(void *), RT_SIGNAL_HELPER, &arg.sigtask).i[LOW]; 95 if (rt_thread_create((void *)signal_suprt_fun, &arg, SIGNAL_TASK_STACK_SIZE)) { 96 return rtai_lxrt(RTAI_SIGNALS_IDX, sizeof(RT_TASK *), RT_SIGNAL_HELPER, &arg.task).i[LOW]; 97 } 98 } 99 return -EINVAL; 100 } 101 102 RTAI_PROTO(int, rt_release_signal, (long signal, RT_TASK *task)) 103 { 104 struct { long signal; RT_TASK *task; } arg = { signal, task }; 105 return rtai_lxrt(RTAI_SIGNALS_IDX, SIZARG, RT_SIGNAL_RELEASE, &arg).i[LOW]; 106 } 107 108 RTAI_PROTO(void, rt_enable_signal, (long signal, RT_TASK *task)) 109 { 110 struct { long signal; RT_TASK *task; } arg = { signal, task }; 111 rtai_lxrt(RTAI_SIGNALS_IDX, SIZARG, RT_SIGNAL_ENABLE, &arg); 112 } 113 114 RTAI_PROTO(void, rt_disable_signal, (long signal, RT_TASK *task)) 115 { 116 struct { long signal; RT_TASK *task; } arg = { signal, task }; 117 rtai_lxrt(RTAI_SIGNALS_IDX, SIZARG, RT_SIGNAL_DISABLE, &arg); 118 } 119 120 RTAI_PROTO(void, rt_trigger_signal, (long signal, RT_TASK *task)) 121 { 122 struct { long signal; RT_TASK *task; } arg = { signal, task }; 123 rtai_lxrt(RTAI_SIGNALS_IDX, SIZARG, RT_SIGNAL_TRIGGER, &arg); 124 } 125 126 #endif /* __KERNEL__ */ 127 128 #endif /* !_RTAI_SIGNAL_H_ */