base/include/rtai_lxrt.h

Go to the documentation of this file.
00001 /** 00002 * @ingroup lxrt 00003 * @file 00004 * 00005 * LXRT main header. 00006 * 00007 * @author Paolo Mantegazza 00008 * 00009 * @note Copyright &copy; 1999-2003 Paolo Mantegazza <mantegazza@aero.polimi.it> 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 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, Suite 330, Boston, MA 02111-1307 USA. 00024 * 00025 * ACKNOWLEDGMENTS: 00026 * Pierre Cloutier (pcloutier@poseidoncontrols.com) has suggested the 6 00027 * characters names and fixed many inconsistencies within this file. 00028 */ 00029 00030 /** 00031 * @defgroup lxrt LXRT module. 00032 * 00033 * LXRT services (soft-hard real time in user space) 00034 * 00035 * LXRT is a module that allows you to use all the services made available by 00036 * RTAI and its schedulers in user space, both for soft and hard real time. At 00037 * the moment it is a feature youll find nowhere but with RTAI. For an 00038 * explanation of how it works see 00039 * @ref lxrt_faq "Pierre Cloutiers LXRT-INFORMED FAQs", and the explanation of 00040 * @ref whatis_lxrt "the implementation of hard real time in user space" 00041 * (contributed by: Pierre Cloutier, Paolo Mantegazza, Steve Papacharalambous). 00042 * 00043 * LXRT-INFORMED should be the production version of LXRT, the latter being the 00044 * development version. So it can happen that LXRT-INFORMED could be lagging 00045 * slightly behind LXRT. If you need to hurry to the services not yet ported to 00046 * LXRT-INFORMED do it without pain. Even if you are likely to miss some useful 00047 * services found only in LXRT-INFORMED, we release only when a feature is 00048 * relatively stable. 00049 * 00050 * From what said above there should be no need for anything specific as all the 00051 * functions you can use in user space have been already documented in this 00052 * manual. There are however a few exceptions that need to be explained. 00053 * 00054 * Note also that, as already done for the shared memory services in user space, 00055 * the function calls for Linux processes are inlined in the file 00056 * rtai_lxrt.h. This approach has been preferred to a library since it is 00057 * simpler, more effective, the calls are short and simple so that, even if it 00058 * is likely that there can be more than just a few per process, they could 00059 * never be charged of making codes too bigger. Also common to shared memory 00060 * is the use of unsigned int to identify LXRT objects. If you want to use 00061 * string identifiers the same support functions, i.e. nam2num() and 00062 * num2nam(), can be used. 00063 * 00064 *@{*/ 00065 00066 #ifndef _RTAI_LXRT_H 00067 #define _RTAI_LXRT_H 00068 00069 #include <rtai_sched.h> 00070 #include <rtai_nam2num.h> 00071 00072 // scheduler 00073 #define YIELD 0 00074 #define SUSPEND 1 00075 #define RESUME 2 00076 #define MAKE_PERIODIC 3 00077 #define WAIT_PERIOD 4 00078 #define SLEEP 5 00079 #define SLEEP_UNTIL 6 00080 #define START_TIMER 7 00081 #define STOP_TIMER 8 00082 #define GET_TIME 9 00083 #define COUNT2NANO 10 00084 #define NANO2COUNT 11 00085 #define BUSY_SLEEP 12 00086 #define SET_PERIODIC_MODE 13 00087 #define SET_ONESHOT_MODE 14 00088 #define SIGNAL_HANDLER 15 00089 #define TASK_USE_FPU 16 00090 #define LINUX_USE_FPU 17 00091 #define HARD_TIMER_COUNT 18 00092 #define GET_TIME_NS 19 00093 #define GET_CPU_TIME_NS 20 00094 #define SET_RUNNABLE_ON_CPUS 21 00095 #define SET_RUNNABLE_ON_CPUID 22 00096 #define GET_TIMER_CPU 23 00097 #define START_RT_APIC_TIMERS 24 00098 #define HARD_TIMER_COUNT_CPUID 25 00099 #define COUNT2NANO_CPUID 26 00100 #define NANO2COUNT_CPUID 27 00101 #define GET_TIME_CPUID 28 00102 #define GET_TIME_NS_CPUID 29 00103 #define MAKE_PERIODIC_NS 30 00104 #define SET_SCHED_POLICY 31 00105 #define SET_RESUME_END 32 00106 #define SPV_RMS 33 00107 #define WAKEUP_SLEEPING 34 00108 #define CHANGE_TASK_PRIO 35 00109 #define SET_RESUME_TIME 36 00110 #define SET_PERIOD 37 00111 #define HARD_TIMER_RUNNING 38 00112 00113 // semaphores 00114 #define TYPED_SEM_INIT 39 00115 #define SEM_DELETE 40 00116 #define NAMED_SEM_INIT 41 00117 #define NAMED_SEM_DELETE 42 00118 #define SEM_SIGNAL 43 00119 #define SEM_WAIT 44 00120 #define SEM_WAIT_IF 45 00121 #define SEM_WAIT_UNTIL 46 00122 #define SEM_WAIT_TIMED 47 00123 #define SEM_BROADCAST 48 00124 #define SEM_WAIT_BARRIER 49 00125 #define SEM_COUNT 50 00126 #define COND_WAIT 51 00127 #define COND_WAIT_UNTIL 52 00128 #define COND_WAIT_TIMED 53 00129 #define RWL_INIT 54 00130 #define RWL_DELETE 55 00131 #define NAMED_RWL_INIT 56 00132 #define NAMED_RWL_DELETE 57 00133 #define RWL_RDLOCK 58 00134 #define RWL_RDLOCK_IF 59 00135 #define RWL_RDLOCK_UNTIL 60 00136 #define RWL_RDLOCK_TIMED 61 00137 #define RWL_WRLOCK 62 00138 #define RWL_WRLOCK_IF 63 00139 #define RWL_WRLOCK_UNTIL 64 00140 #define RWL_WRLOCK_TIMED 65 00141 #define RWL_UNLOCK 66 00142 #define SPL_INIT 67 00143 #define SPL_DELETE 68 00144 #define NAMED_SPL_INIT 69 00145 #define NAMED_SPL_DELETE 70 00146 #define SPL_LOCK 71 00147 #define SPL_LOCK_IF 72 00148 #define SPL_LOCK_TIMED 73 00149 #define SPL_UNLOCK 74 00150 00151 // mail boxes 00152 #define TYPED_MBX_INIT 75 00153 #define MBX_DELETE 76 00154 #define NAMED_MBX_INIT 77 00155 #define NAMED_MBX_DELETE 78 00156 #define MBX_SEND 79 00157 #define MBX_SEND_WP 80 00158 #define MBX_SEND_IF 81 00159 #define MBX_SEND_UNTIL 82 00160 #define MBX_SEND_TIMED 83 00161 #define MBX_RECEIVE 84 00162 #define MBX_RECEIVE_WP 85 00163 #define MBX_RECEIVE_IF 86 00164 #define MBX_RECEIVE_UNTIL 87 00165 #define MBX_RECEIVE_TIMED 88 00166 #define MBX_EVDRP 89 00167 #define MBX_OVRWR_SEND 90 00168 00169 // short intertask messages 00170 #define SENDMSG 91 00171 #define SEND_IF 92 00172 #define SEND_UNTIL 93 00173 #define SEND_TIMED 94 00174 #define RECEIVEMSG 95 00175 #define RECEIVE_IF 96 00176 #define RECEIVE_UNTIL 97 00177 #define RECEIVE_TIMED 98 00178 #define RPCMSG 99 00179 #define RPC_IF 100 00180 #define RPC_UNTIL 101 00181 #define RPC_TIMED 102 00182 #define EVDRP 103 00183 #define ISRPC 104 00184 #define RETURNMSG 105 00185 00186 // extended intertask messages 00187 #define RPCX 106 00188 #define RPCX_IF 107 00189 #define RPCX_UNTIL 108 00190 #define RPCX_TIMED 109 00191 #define SENDX 110 00192 #define SENDX_IF 111 00193 #define SENDX_UNTIL 112 00194 #define SENDX_TIMED 113 00195 #define RETURNX 114 00196 #define RECEIVEX 115 00197 #define RECEIVEX_IF 116 00198 #define RECEIVEX_UNTIL 117 00199 #define RECEIVEX_TIMED 118 00200 #define EVDRPX 119 00201 00202 // proxies 00203 #define PROXY_ATTACH 120 00204 #define PROXY_DETACH 121 00205 #define PROXY_TRIGGER 122 00206 00207 00208 // synchronous user space specific intertask messages and related proxies 00209 #define RT_SEND 123 00210 #define RT_RECEIVE 124 00211 #define RT_CRECEIVE 125 00212 #define RT_REPLY 126 00213 #define RT_PROXY_ATTACH 127 00214 #define RT_PROXY_DETACH 128 00215 #define RT_TRIGGER 129 00216 #define RT_NAME_ATTACH 130 00217 #define RT_NAME_DETACH 131 00218 #define RT_NAME_LOCATE 132 00219 00220 // bits 00221 #define BITS_INIT 133 00222 #define BITS_DELETE 134 00223 #define NAMED_BITS_INIT 135 00224 #define NAMED_BITS_DELETE 136 00225 #define BITS_GET 137 00226 #define BITS_RESET 138 00227 #define BITS_SIGNAL 139 00228 #define BITS_WAIT 140 00229 #define BITS_WAIT_IF 141 00230 #define BITS_WAIT_UNTIL 142 00231 #define BITS_WAIT_TIMED 143 00232 00233 // typed mail boxes 00234 #define TBX_INIT 144 00235 #define TBX_DELETE 145 00236 #define NAMED_TBX_INIT 146 00237 #define NAMED_TBX_DELETE 147 00238 #define TBX_SEND 148 00239 #define TBX_SEND_IF 149 00240 #define TBX_SEND_UNTIL 150 00241 #define TBX_SEND_TIMED 151 00242 #define TBX_RECEIVE 152 00243 #define TBX_RECEIVE_IF 153 00244 #define TBX_RECEIVE_UNTIL 154 00245 #define TBX_RECEIVE_TIMED 155 00246 #define TBX_BROADCAST 156 00247 #define TBX_BROADCAST_IF 157 00248 #define TBX_BROADCAST_UNTIL 158 00249 #define TBX_BROADCAST_TIMED 159 00250 #define TBX_URGENT 160 00251 #define TBX_URGENT_IF 161 00252 #define TBX_URGENT_UNTIL 162 00253 #define TBX_URGENT_TIMED 163 00254 00255 // pqueue 00256 #define MQ_OPEN 164 00257 #define MQ_RECEIVE 165 00258 #define MQ_SEND 166 00259 #define MQ_CLOSE 167 00260 #define MQ_GETATTR 168 00261 #define MQ_SETATTR 169 00262 #define MQ_NOTIFY 170 00263 #define MQ_UNLINK 171 00264 #define MQ_TIMEDRECEIVE 172 00265 #define MQ_TIMEDSEND 173 00266 00267 // named tasks init/delete 00268 #define NAMED_TASK_INIT 174 00269 #define NAMED_TASK_INIT_CPUID 175 00270 #define NAMED_TASK_DELETE 176 00271 00272 // registry 00273 #define GET_ADR 177 00274 #define GET_NAME 178 00275 00276 // netrpc 00277 #define NETRPC 179 00278 #define SEND_REQ_REL_PORT 180 00279 #define DDN2NL 181 00280 #define SET_THIS_NODE 182 00281 #define FIND_ASGN_STUB 183 00282 #define REL_STUB 184 00283 #define WAITING_RETURN 185 00284 00285 // a semaphore extension 00286 #define COND_SIGNAL 186 00287 00288 // new shm 00289 #define SHM_ALLOC 187 00290 #define SHM_FREE 188 00291 #define SHM_SIZE 189 00292 #define HEAP_SET 190 00293 #define HEAP_ALLOC 191 00294 #define HEAP_FREE 192 00295 #define HEAP_NAMED_ALLOC 193 00296 #define HEAP_NAMED_FREE 194 00297 #define MALLOC 195 00298 #define FREE 196 00299 #define NAMED_MALLOC 197 00300 #define NAMED_FREE 198 00301 00302 #define SUSPEND_IF 199 00303 #define SUSPEND_UNTIL 200 00304 #define SUSPEND_TIMED 201 00305 #define IRQ_WAIT 202 00306 #define IRQ_WAIT_IF 203 00307 #define IRQ_WAIT_UNTIL 204 00308 #define IRQ_WAIT_TIMED 205 00309 #define IRQ_SIGNAL 206 00310 #define REQUEST_IRQ_TASK 207 00311 #define RELEASE_IRQ_TASK 208 00312 #define SCHED_LOCK 209 00313 #define SCHED_UNLOCK 210 00314 #define PEND_LINUX_IRQ 211 00315 #define RECEIVE_LINUX_SYSCALL 212 00316 #define RETURN_LINUX_SYSCALL 213 00317 #define REQUEST_RTC 214 00318 #define RELEASE_RTC 215 00319 00320 #define MAX_LXRT_FUN 220 00321 00322 // not recovered yet 00323 // Qblk's 00324 #define RT_INITTICKQUEUE 69 00325 #define RT_RELEASETICKQUEUE 70 00326 #define RT_QDYNALLOC 71 00327 #define RT_QDYNFREE 72 00328 #define RT_QDYNINIT 73 00329 #define RT_QBLKWAIT 74 00330 #define RT_QBLKREPEAT 75 00331 #define RT_QBLKSOON 76 00332 #define RT_QBLKDEQUEUE 77 00333 #define RT_QBLKCANCEL 78 00334 #define RT_QSYNC 79 00335 #define RT_QRECEIVE 80 00336 #define RT_QLOOP 81 00337 #define RT_QSTEP 82 00338 #define RT_QBLKBEFORE 83 00339 #define RT_QBLKAFTER 84 00340 #define RT_QBLKUNHOOK 85 00341 #define RT_QBLKRELEASE 86 00342 #define RT_QBLKCOMPLETE 87 00343 #define RT_QHOOKFLUSH 88 00344 #define RT_QBLKATHEAD 89 00345 #define RT_QBLKATTAIL 90 00346 #define RT_QHOOKINIT 91 00347 #define RT_QHOOKRELEASE 92 00348 #define RT_QBLKSCHEDULE 93 00349 #define RT_GETTICKQUEUEHOOK 94 00350 // Testing 00351 #define RT_BOOM 95 00352 #define RTAI_MALLOC 96 00353 #define RT_FREE 97 00354 #define RT_MMGR_STATS 98 00355 #define RT_STOMP 99 00356 // VC 00357 #define RT_VC_ATTACH 100 00358 #define RT_VC_RELEASE 101 00359 #define RT_VC_RESERVE 102 00360 // Linux Signal Support 00361 #define RT_GET_LINUX_SIGNAL 103 00362 #define RT_GET_ERRNO 104 00363 #define RT_SET_LINUX_SIGNAL_HANDLER 105 00364 // end of not recovered yet 00365 00366 #define LXRT_GET_ADR 1000 00367 #define LXRT_GET_NAME 1001 00368 #define LXRT_TASK_INIT 1002 00369 #define LXRT_TASK_DELETE 1003 00370 #define LXRT_SEM_INIT 1004 00371 #define LXRT_SEM_DELETE 1005 00372 #define LXRT_MBX_INIT 1006 00373 #define LXRT_MBX_DELETE 1007 00374 #define MAKE_SOFT_RT 1008 00375 #define MAKE_HARD_RT 1009 00376 #define PRINT_TO_SCREEN 1010 00377 #define NONROOT_HRT 1011 00378 #define RT_BUDDY 1012 00379 #define HRT_USE_FPU 1013 00380 #define USP_SIGHDL 1014 00381 #define GET_USP_FLAGS 1015 00382 #define SET_USP_FLAGS 1016 00383 #define GET_USP_FLG_MSK 1017 00384 #define SET_USP_FLG_MSK 1018 00385 #define IS_HARD 1019 00386 #define LINUX_SERVER_INIT 1020 00387 #define ALLOC_REGISTER 1021 00388 #define DELETE_DEREGISTER 1022 00389 #define FORCE_TASK_SOFT 1023 00390 #define PRINTK 1024 00391 #define GET_EXECTIME 1025 00392 #define GET_TIMEORIG 1026 00393 #define LXRT_RWL_INIT 1027 00394 #define LXRT_RWL_DELETE 1028 00395 #define LXRT_SPL_INIT 1029 00396 #define LXRT_SPL_DELETE 1030 00397 00398 #define FORCE_SOFT 0x80000000 00399 00400 // Keep LXRT call enc/decoding together, so you are sure to act consistently. 00401 // This is the encoding, note " | GT_NR_SYSCALLS" to ensure not a Linux syscall, ... 00402 #define GT_NR_SYSCALLS (1 << 11) 00403 #define ENCODE_LXRT_REQ(dynx, srq, lsize) (((dynx) << 24) | ((srq) << 12) | GT_NR_SYSCALLS | (lsize)) 00404 // ... and this is the decoding. 00405 #define SRQ(x) (((x) >> 12) & 0xFFF) 00406 #define NARG(x) ((x) & (GT_NR_SYSCALLS - 1)) 00407 #define INDX(x) (((x) >> 24) & 0xF) 00408 00409 #ifdef __KERNEL__ 00410 00411 #include <asm/rtai_lxrt.h> 00412 00413 /* 00414 Encoding of system call argument 00415 31 0 00416 soft SRQ .... |||| |||| |||| .... .... .... .... 0 - 4095 max 00417 int NARG .... .... .... .... |||| |||| |||| |||| 00418 arg INDX |||| .... .... .... .... .... .... .... 00419 */ 00420 00421 /* 00422 These USP (unsigned long) type fields allow to read and write up to 2 arguments. 00423 00424 The high part of the unsigned long encodes writes 00425 W ARG1 BF .... .... ..|| |... .... .... .... .... 00426 W ARG1 SZ .... ...| ||.. .... .... .... .... .... 00427 W ARG2 BF .... |||. .... .... .... .... .... .... 00428 W ARG2 SZ .||| .... .... .... .... .... .... .... 00429 00430 The low part of the unsigned long encodes writes 00431 R ARG1 BF .... .... .... .... .... .... ..|| |... 00432 R ARG1 SZ .... .... .... .... .... ...| ||.. .... 00433 R ARG2 BF .... .... .... .... .... |||. .... .... 00434 R ARG2 SZ .... .... .... .... .||| .... .... .... 00435 00436 The low part of the unsigned long encodes also 00437 RT Switch .... .... .... .... .... .... .... ...| 00438 00439 If SZ is zero sizeof(int) is copied by default, if LL bit is set sizeof(long long) is copied. 00440 */ 00441 00442 // These are for setting appropriate bits in any function entry structure, OR 00443 // them in fun entry type to obtain the desired encoding 00444 00445 // for writes 00446 #define UW1(bf, sz) ((((bf) & 0x7) << 19) | (((sz) & 0x7) << 22)) 00447 #define UW2(bf, sz) ((((bf) & 0x7) << 25) | (((sz) & 0x7) << 28)) 00448 00449 // for reads 00450 #define UR1(bf, sz) ((((bf) & 0x7) << 3) | (((sz) & 0x7) << 6)) 00451 #define UR2(bf, sz) ((((bf) & 0x7) << 9) | (((sz) & 0x7) << 12)) 00452 00453 #define NEED_TO_RW(x) ((x) & 0xFFFFFFFE) 00454 00455 #define NEED_TO_W(x) ((x) & (0x3F << 19)) 00456 #define NEED_TO_W2ND(x) ((x) & (0x3F << 25)) 00457 00458 #define NEED_TO_R(x) ((x) & (0x3F << 3)) 00459 #define NEED_TO_R2ND(x) ((x) & (0x3F << 9)) 00460 00461 #define USP_WBF1(x) (((x) >> 19) & 0x7) 00462 #define USP_WSZ1(x) (((x) >> 22) & 0x7) 00463 #define USP_WBF2(x) (((x) >> 25) & 0x7) 00464 #define USP_WSZ2(x) (((x) >> 28) & 0x7) 00465 00466 #define USP_RBF1(x) (((x) >> 3) & 0x7) 00467 #define USP_RSZ1(x) (((x) >> 6) & 0x7) 00468 #define USP_RBF2(x) (((x) >> 9) & 0x7) 00469 #define USP_RSZ2(x) (((x) >> 12) & 0x7) 00470 00471 struct rt_fun_entry { 00472 unsigned long type; 00473 void *fun; 00474 }; 00475 00476 struct rt_native_fun_entry { 00477 struct rt_fun_entry fun; 00478 int index; 00479 }; 00480 00481 extern struct rt_fun_entry rt_fun_lxrt[]; 00482 00483 void reset_rt_fun_entries(struct rt_native_fun_entry *entry); 00484 00485 int set_rt_fun_entries(struct rt_native_fun_entry *entry); 00486 00487 #ifdef __cplusplus 00488 extern "C" { 00489 #endif /* __cplusplus */ 00490 00491 #if CONFIG_RTAI_INTERNAL_LXRT_SUPPORT 00492 00493 static inline struct rt_task_struct *pid2rttask(long pid) 00494 { 00495 return ((unsigned long)pid) > PID_MAX_LIMIT ? (struct rt_task_struct *)pid : find_task_by_pid(pid)->rtai_tskext(TSKEXT0); 00496 } 00497 00498 static inline long rttask2pid(struct rt_task_struct * task) 00499 { 00500 return task->lnxtsk ? task->lnxtsk->pid : (long)task; 00501 } 00502 00503 #else /* !CONFIG_RTAI_INTERNAL_LXRT_SUPPORT */ 00504 00505 static inline struct rt_task_struct *pid2rttask(pid_t pid) 00506 { 00507 return 0; 00508 } 00509 00510 // The following might look strange but it must be so to work with 00511 // buddies also. 00512 static inline pid_t rttask2pid(struct rt_task_struct * task) 00513 { 00514 return (long) task; 00515 } 00516 00517 #endif /* CONFIG_RTAI_INTERNAL_LXRT_SUPPORT */ 00518 00519 int set_rtai_callback(void (*fun)(void)); 00520 00521 void remove_rtai_callback(void (*fun)(void)); 00522 00523 RT_TASK *rt_lxrt_whoami(void); 00524 00525 void exec_func(void (*func)(void *data, int evn), 00526 void *data, 00527 int evn); 00528 00529 int set_rt_fun_ext_index(struct rt_fun_entry *fun, 00530 int idx); 00531 00532 void reset_rt_fun_ext_index(struct rt_fun_entry *fun, 00533 int idx); 00534 00535 #ifdef __cplusplus 00536 } 00537 #endif /* __cplusplus */ 00538 00539 #else /* !__KERNEL__ */ 00540 00541 #include <sys/types.h> 00542 #include <sched.h> 00543 #include <stdarg.h> 00544 #include <stdio.h> 00545 #include <string.h> 00546 #include <asm/rtai_lxrt.h> 00547 00548 struct apic_timer_setup_data; 00549 00550 #define rt_grow_and_lock_stack(incr) \ 00551 do { \ 00552 char buf[incr]; \ 00553 memset(buf, 0, incr); \ 00554 mlockall(MCL_CURRENT | MCL_FUTURE); \ 00555 } while (0) 00556 00557 #define BIDX 0 // rt_fun_ext[0] 00558 #define SIZARG sizeof(arg) 00559 00560 #ifdef __cplusplus 00561 extern "C" { 00562 #endif /* __cplusplus */ 00563 00564 /** 00565 * Get an object address by its name. 00566 * 00567 * rt_get_adr returns the address associated to @a name. 00568 * 00569 * @return the address associated to @a name on success, 0 on failure 00570 */ 00571 RTAI_PROTO(void *, rt_get_adr, (unsigned long name)) 00572 { 00573 struct { unsigned long name; } arg = { name }; 00574 return rtai_lxrt(BIDX, SIZARG, LXRT_GET_ADR, &arg).v[LOW]; 00575 } 00576 00577 /** 00578 * Get an object name by its address. 00579 * 00580 * rt_get_name returns the name pointed by the address @a adr. 00581 * 00582 * @return the identifier pointed by the address @a adr on success, 0 on 00583 * failure. 00584 */ 00585 RTAI_PROTO(unsigned long, rt_get_name, (void *adr)) 00586 { 00587 struct { void *adr; } arg = { adr }; 00588 return rtai_lxrt(BIDX, SIZARG, LXRT_GET_NAME, &arg).i[LOW]; 00589 } 00590 00591 RTAI_PROTO(RT_TASK *, rt_task_init_schmod, (unsigned long name, int priority, int stack_size, int max_msg_size, int policy, int cpus_allowed)) 00592 { 00593 struct sched_param mysched; 00594 struct { unsigned long name; int priority, stack_size, max_msg_size, cpus_allowed; } arg = { name, priority, stack_size, max_msg_size, cpus_allowed }; 00595 00596 mysched.sched_priority = sched_get_priority_max(policy) - priority; 00597 if (mysched.sched_priority < 1 ) { 00598 mysched.sched_priority = 1; 00599 } 00600 if (sched_setscheduler(0, policy, &mysched) < 0) { 00601 return 0; 00602 } 00603 rtai_iopl(); 00604 00605 return (RT_TASK *)rtai_lxrt(BIDX, SIZARG, LXRT_TASK_INIT, &arg).v[LOW]; 00606 } 00607 00608 static inline int rt_clone(void *fun, void *args, long stack_size, unsigned long flags) 00609 { 00610 void *sp; 00611 if (!flags) { 00612 flags = CLONE_VM | CLONE_FS | CLONE_FILES; 00613 } 00614 memset(sp = malloc(stack_size), 0, stack_size); 00615 sp = (void *)(((unsigned long)sp + stack_size - 16) & ~0xF); 00616 return clone((int (*)(void *))fun, sp, flags, args); 00617 } 00618 00619 #define RT_THREAD_STACK_MIN 64*1024 00620 00621 #if 1 00622 #include <pthread.h> 00623 00624 RTAI_PROTO(int, rt_thread_create,(void *fun, void *args, int stack_size)) 00625 { 00626 pthread_t thread; 00627 pthread_attr_t attr; 00628 pthread_attr_init(&attr); 00629 if (pthread_attr_setstacksize(&attr, stack_size > RT_THREAD_STACK_MIN ? stack_size : RT_THREAD_STACK_MIN)) { 00630 return -1; 00631 } 00632 if (pthread_create(&thread, &attr, (void *(*)(void *))fun, args)) { 00633 return -1; 00634 } 00635 return thread; 00636 } 00637 00638 RTAI_PROTO(int, rt_thread_join, (int thread)) 00639 { 00640 return pthread_join((pthread_t)thread, NULL); 00641 } 00642 00643 #else 00644 00645 #include <sys/wait.h> 00646 00647 RTAI_PROTO(int, rt_thread_create, (void *fun, void *args, int stack_size)) 00648 { 00649 void *sp; 00650 if (stack_size < RT_THREAD_STACK_MIN) { 00651 stack_size = RT_THREAD_STACK_MIN; 00652 } 00653 memset(sp = malloc(stack_size), 0, stack_size); 00654 sp = (void *)(((unsigned long)sp + stack_size - 16) & ~0xF); 00655 return rt_clone(fun, args, stack_size, 0); 00656 } 00657 00658 RTAI_PROTO(int, rt_thread_join, (int thread)) 00659 { 00660 return waitpid(thread, NULL, 0); 00661 } 00662 00663 #endif 00664 00665 #ifndef __SUPPORT_LINUX_SERVER__ 00666 #define __SUPPORT_LINUX_SERVER__ 00667 00668 #include <asm/ptrace.h> 00669 #include <unistd.h> 00670 00671 static inline RT_TASK *rt_receive_linux_syscall(RT_TASK *task, struct pt_regs *regs) 00672 { 00673 struct { RT_TASK *task; struct pt_regs *regs; } arg = { task, regs }; 00674 return (RT_TASK *)rtai_lxrt(BIDX, SIZARG, RECEIVE_LINUX_SYSCALL, &arg).v[LOW]; 00675 } 00676 00677 static inline void rt_return_linux_syscall(RT_TASK *task, unsigned long retval) 00678 { 00679 struct { RT_TASK *task; unsigned long retval; } arg = { task, retval }; 00680 rtai_lxrt(BIDX, SIZARG, RETURN_LINUX_SYSCALL, &arg); 00681 } 00682 00683 #include <rtai_msg.h> 00684 static void linux_syscall_server_fun(RT_TASK *task) 00685 { 00686 struct pt_regs regs; 00687 if (rtai_lxrt(BIDX, sizeof(RT_TASK *), LINUX_SERVER_INIT, &task).i[LOW]) { 00688 // rtai_lxrt(BIDX, sizeof(RT_TASK *), RESUME, &task); 00689 for (;;) { 00690 if (rt_receive_linux_syscall(task, &regs) == task) { 00691 rt_return_linux_syscall(task, syscall(regs.LINUX_SYSCALL_NR, regs.LINUX_SYSCALL_REG1, regs.LINUX_SYSCALL_REG2, regs.LINUX_SYSCALL_REG3, regs.LINUX_SYSCALL_REG4, regs.LINUX_SYSCALL_REG5, regs.LINUX_SYSCALL_REG6)); 00692 } 00693 } 00694 } 00695 } 00696 00697 #endif /* __SUPPORT_LINUX_SERVER__ */ 00698 00699 RTAI_PROTO(int, rt_linux_syscall_server_create, (RT_TASK * task)) 00700 { 00701 //return rtai_lxrt(BIDX, sizeof(RT_TASK *), LINUX_SERVER_INIT, &task).i[LOW]; 00702 if (task || (task = (RT_TASK *)rtai_lxrt(BIDX, sizeof(RT_TASK *), RT_BUDDY, &task).v[LOW])) { 00703 if (rt_thread_create((void *)linux_syscall_server_fun, task, 0) > 0) { 00704 rtai_lxrt(BIDX, sizeof(RT_TASK *), SUSPEND, &task); 00705 return 0; 00706 } 00707 } 00708 return -1; 00709 } 00710 00711 RTAI_PROTO(RT_TASK *, rt_thread_init, (unsigned long name, int priority, int max_msg_size, int policy, int cpus_allowed)) 00712 { 00713 return rt_task_init_schmod(name, priority, 0, max_msg_size, policy, cpus_allowed); 00714 } 00715 00716 /** 00717 * Create a new real time task in user space. 00718 * 00719 * rt_task_init provides a real time buddy, also called proxy, task to the Linux 00720 * process that wants to access RTAI scheduler services. It needs no task 00721 * function as none is used, but it does need to setup a task structure and 00722 * initialize it appropriately as the provided services are carried out as if 00723 * the Linux process has become an RTAI task. Because of that it requires less 00724 * arguments and returns the pointer to the task that is to be used in related 00725 * calls. 00726 * 00727 * @param name is a unique identifier that is possibly used by easing 00728 * referencing the buddy RTAItask, and thus its peer Linux process. 00729 * 00730 * @param priority is the priority of the buddys priority. 00731 * 00732 * @param stack_size is just what is implied by such a name and refers to the 00733 * stack size used by the buddy. 00734 * 00735 * @param max_msg_size is a hint for the size of the most lengthy message than 00736 * is likely to be exchanged. 00737 * 00738 * @a stack_size and @a max_msg_size can be zero, in which case the default 00739 * internal values are used. The assignment of a different value should be 00740 * required only if you want to use task signal functions. In such a case note 00741 * that these signal functions are intended to catch asyncrounous events in 00742 * kernel space and, as such, must be programmed into a companion module and 00743 * interfaced to their parent Linux process through the available services. 00744 * 00745 * Keep an eye on the default stack (512) and message (256) sizes as they seem 00746 * to be acceptable, but this API has not been used extensively with complex 00747 * interrupt service routines. Since the latter are served on the stack of 00748 * any task being interrupted, and more than one can pile up on the same stack, 00749 * it can be possible that a larger stack is required. In such a case either 00750 * recompile lxrt.c with macros STACK_SIZE and MSG_SIZE set appropriately, or 00751 * explicitly assign larger values at your buddy tasks inits. Note that while 00752 * the stack size can be critical the message size will not. In fact the module 00753 * reassigns it, appropriately sized, whenever it is needed. The cost is a 00754 * kmalloc with GFP_KERNEL that can block, but within the Linux environment. 00755 * Note also that @a max_msg_size is for a buffer to be used to copy whatever 00756 * message, either mailbox or inter task, from user to kernel space, as messages 00757 * are not necessarily copied immediately, and has nothing to do directly with 00758 * what you are doing. 00759 * 00760 * It is important to remark that the returned task pointers cannot be used 00761 * directly, they are for kernel space data, but just passed as arguments when 00762 * needed. 00763 * 00764 * @return On success a pointer to the task structure initialized in kernel 00765 * space. 00766 * @return On failure a 0 value is returned if it was not possible to setup the 00767 * buddy task or something using the same name was found. 00768 */ 00769 RTAI_PROTO(RT_TASK *,rt_task_init,(unsigned long name, int priority, int stack_size, int max_msg_size)) 00770 { 00771 return rt_task_init_schmod(name, priority, 0, max_msg_size, SCHED_FIFO, 0xFF); 00772 } 00773 00774 RTAI_PROTO(void,rt_set_sched_policy,(RT_TASK *task, int policy, int rr_quantum_ns)) 00775 { 00776 struct { RT_TASK *task; long policy; long rr_quantum_ns; } arg = { task, policy, rr_quantum_ns }; 00777 rtai_lxrt(BIDX, SIZARG, SET_SCHED_POLICY, &arg); 00778 } 00779 00780 RTAI_PROTO(int,rt_change_prio,(RT_TASK *task, int priority)) 00781 { 00782 struct { RT_TASK *task; long priority; } arg = { task, priority }; 00783 return rtai_lxrt(BIDX, SIZARG, CHANGE_TASK_PRIO, &arg).i[LOW]; 00784 } 00785 00786 /** 00787 * Return a hard real time Linux process, or pthread to the standard Linux 00788 * behavior. 00789 * 00790 * rt_make_soft_real_time returns to soft Linux POSIX real time a process, from 00791 * which it is called, that was made hard real time by a call to 00792 * rt_make_hard_real_time. 00793 * 00794 * Only the process itself can use this functions, it is not possible to impose 00795 * the related transition from another process. 00796 * 00797 */ 00798 RTAI_PROTO(void,rt_make_soft_real_time,(void)) 00799 { 00800 struct { unsigned long dummy; } arg; 00801 rtai_lxrt(BIDX, SIZARG, MAKE_SOFT_RT, &arg); 00802 } 00803 00804 RTAI_PROTO(int,rt_task_delete,(RT_TASK *task)) 00805 { 00806 struct { RT_TASK *task; } arg = { task }; 00807 rt_make_soft_real_time(); 00808 return rtai_lxrt(BIDX, SIZARG, LXRT_TASK_DELETE, &arg).i[LOW]; 00809 } 00810 00811 RTAI_PROTO(int,rt_task_yield,(void)) 00812 { 00813 struct { unsigned long dummy; } arg; 00814 return rtai_lxrt(BIDX, SIZARG, YIELD, &arg).i[LOW]; 00815 } 00816 00817 RTAI_PROTO(int,rt_task_suspend,(RT_TASK *task)) 00818 { 00819 struct { RT_TASK *task; } arg = { task }; 00820 return rtai_lxrt(BIDX, SIZARG, SUSPEND, &arg).i[LOW]; 00821 } 00822 00823 RTAI_PROTO(int,rt_task_suspend_if,(RT_TASK *task)) 00824 { 00825 struct { RT_TASK *task; } arg = { task }; 00826 return rtai_lxrt(BIDX, SIZARG, SUSPEND_IF, &arg).i[LOW]; 00827 } 00828 00829 RTAI_PROTO(int,rt_task_suspend_until,(RT_TASK *task, RTIME time)) 00830 { 00831 struct { RT_TASK *task; RTIME time; } arg = { task, time }; 00832 return rtai_lxrt(BIDX, SIZARG, SUSPEND_UNTIL, &arg).i[LOW]; 00833 } 00834 00835 RTAI_PROTO(int,rt_task_suspend_timed,(RT_TASK *task, RTIME delay)) 00836 { 00837 struct { RT_TASK *task; RTIME delay; } arg = { task, delay }; 00838 return rtai_lxrt(BIDX, SIZARG, SUSPEND_TIMED, &arg).i[LOW]; 00839 } 00840 00841 RTAI_PROTO(int,rt_task_resume,(RT_TASK *task)) 00842 { 00843 struct { RT_TASK *task; } arg = { task }; 00844 return rtai_lxrt(BIDX, SIZARG, RESUME, &arg).i[LOW]; 00845 } 00846 00847 RTAI_PROTO(void, rt_sched_lock, (void)) 00848 { 00849 struct { int dummy; } arg; 00850 rtai_lxrt(BIDX, SIZARG, SCHED_LOCK, &arg); 00851 } 00852 00853 RTAI_PROTO(void, rt_sched_unlock, (void)) 00854 { 00855 struct { int dummy; } arg; 00856 rtai_lxrt(BIDX, SIZARG, SCHED_UNLOCK, &arg); 00857 } 00858 00859 RTAI_PROTO(void, rt_pend_linux_irq, (unsigned irq)) 00860 { 00861 struct { unsigned irq; } arg = { irq }; 00862 rtai_lxrt(BIDX, SIZARG, PEND_LINUX_IRQ, &arg); 00863 } 00864 00865 RTAI_PROTO(int, rt_irq_wait, (unsigned irq)) 00866 { 00867 struct { unsigned irq; } arg = { irq }; 00868 return rtai_lxrt(BIDX, SIZARG, IRQ_WAIT, &arg).i[LOW]; 00869 } 00870 00871 RTAI_PROTO(int, rt_irq_wait_if, (unsigned irq)) 00872 { 00873 struct { unsigned irq; } arg = { irq }; 00874 return rtai_lxrt(BIDX, SIZARG, IRQ_WAIT_IF, &arg).i[LOW]; 00875 } 00876 00877 RTAI_PROTO(int, rt_irq_wait_until, (unsigned irq, RTIME time)) 00878 { 00879 struct { unsigned irq; RTIME time; } arg = { irq, time }; 00880 return rtai_lxrt(BIDX, SIZARG, IRQ_WAIT_UNTIL, &arg).i[LOW]; 00881 } 00882 00883 RTAI_PROTO(int, rt_irq_wait_timed, (unsigned irq, RTIME delay)) 00884 { 00885 struct { unsigned irq; RTIME delay; } arg = { irq, delay }; 00886 return rtai_lxrt(BIDX, SIZARG, IRQ_WAIT_TIMED, &arg).i[LOW]; 00887 } 00888 00889 RTAI_PROTO(int, rt_irq_signal, (unsigned irq)) 00890 { 00891 struct { unsigned irq; } arg = { irq }; 00892 return rtai_lxrt(BIDX, SIZARG, IRQ_SIGNAL, &arg).i[LOW]; 00893 } 00894 00895 RTAI_PROTO(int, rt_request_irq_task, (unsigned irq, void *handler, int type, int affine2task)) 00896 { 00897 struct { unsigned irq; void *handler; long type, affine2task; } arg = { irq, handler, type, affine2task }; 00898 return rtai_lxrt(BIDX, SIZARG, REQUEST_IRQ_TASK, &arg).i[LOW]; 00899 } 00900 00901 00902 RTAI_PROTO(int, rt_release_irq_task, (unsigned irq)) 00903 { 00904 struct { unsigned irq; } arg = { irq }; 00905 return rtai_lxrt(BIDX, SIZARG, RELEASE_IRQ_TASK, &arg).i[LOW]; 00906 } 00907 00908 RTAI_PROTO(int, rt_task_make_periodic,(RT_TASK *task, RTIME start_time, RTIME period)) 00909 { 00910 struct { RT_TASK *task; RTIME start_time, period; } arg = { task, start_time, period }; 00911 return rtai_lxrt(BIDX, SIZARG, MAKE_PERIODIC, &arg).i[LOW]; 00912 } 00913 00914 RTAI_PROTO(int,rt_task_make_periodic_relative_ns,(RT_TASK *task, RTIME start_delay, RTIME period)) 00915 { 00916 struct { RT_TASK *task; RTIME start_time, period; } arg = { task, start_delay, period }; 00917 return rtai_lxrt(BIDX, SIZARG, MAKE_PERIODIC_NS, &arg).i[LOW]; 00918 } 00919 00920 RTAI_PROTO(int,rt_task_wait_period,(void)) 00921 { 00922 struct { unsigned long dummy; } arg; 00923 return rtai_lxrt(BIDX, SIZARG, WAIT_PERIOD, &arg).i[LOW]; 00924 } 00925 00926 RTAI_PROTO(int,rt_sleep,(RTIME delay)) 00927 { 00928 struct { RTIME delay; } arg = { delay }; 00929 return rtai_lxrt(BIDX, SIZARG, SLEEP, &arg).i[LOW]; 00930 } 00931 00932 RTAI_PROTO(int,rt_sleep_until,(RTIME time)) 00933 { 00934 struct { RTIME time; } arg = { time }; 00935 return rtai_lxrt(BIDX, SIZARG, SLEEP_UNTIL, &arg).i[LOW]; 00936 } 00937 00938 RTAI_PROTO(int,rt_is_hard_timer_running,(void)) 00939 { 00940 struct { unsigned long dummy; } arg; 00941 return rtai_lxrt(BIDX, SIZARG, HARD_TIMER_RUNNING, &arg).i[LOW]; 00942 } 00943 00944 RTAI_PROTO(RTIME, start_rt_timer,(int period)) 00945 { 00946 struct { long period; } arg = { period }; 00947 return rtai_lxrt(BIDX, SIZARG, START_TIMER, &arg).rt; 00948 } 00949 00950 RTAI_PROTO(void, stop_rt_timer,(void)) 00951 { 00952 struct { unsigned long dummy; } arg; 00953 rtai_lxrt(BIDX, SIZARG, STOP_TIMER, &arg); 00954 } 00955 00956 RTAI_PROTO(void, rt_request_rtc,(int rtc_freq, void *handler)) 00957 { 00958 struct { long rtc_freq; void *handler; } arg = { rtc_freq, handler }; 00959 rtai_lxrt(BIDX, SIZARG, REQUEST_RTC, &arg); 00960 } 00961 00962 RTAI_PROTO(void, rt_release_rtc,(void)) 00963 { 00964 struct { unsigned long dummy; } arg; 00965 rtai_lxrt(BIDX, SIZARG, RELEASE_RTC, &arg); 00966 } 00967 00968 RTAI_PROTO(RTIME,rt_get_time,(void)) 00969 { 00970 struct { unsigned long dummy; } arg; 00971 return rtai_lxrt(BIDX, SIZARG, GET_TIME, &arg).rt; 00972 } 00973 00974 RTAI_PROTO(RTIME,count2nano,(RTIME count)) 00975 { 00976 struct { RTIME count; } arg = { count }; 00977 return rtai_lxrt(BIDX, SIZARG, COUNT2NANO, &arg).rt; 00978 } 00979 00980 RTAI_PROTO(RTIME,nano2count,(RTIME nanos)) 00981 { 00982 struct { RTIME nanos; } arg = { nanos }; 00983 return rtai_lxrt(BIDX, SIZARG, NANO2COUNT, &arg).rt; 00984 } 00985 00986 RTAI_PROTO(void,rt_busy_sleep,(int ns)) 00987 { 00988 struct { long ns; } arg = { ns }; 00989 rtai_lxrt(BIDX, SIZARG, BUSY_SLEEP, &arg); 00990 } 00991 00992 RTAI_PROTO(void,rt_set_periodic_mode,(void)) 00993 { 00994 struct { unsigned long dummy; } arg; 00995 rtai_lxrt(BIDX, SIZARG, SET_PERIODIC_MODE, &arg); 00996 } 00997 00998 RTAI_PROTO(void,rt_set_oneshot_mode,(void)) 00999 { 01000 struct { unsigned long dummy; } arg; 01001 rtai_lxrt(BIDX, SIZARG, SET_ONESHOT_MODE, &arg); 01002 } 01003 01004 RTAI_PROTO(int,rt_task_signal_handler,(RT_TASK *task, void (*handler)(void))) 01005 { 01006 struct { RT_TASK *task; void (*handler)(void); } arg = { task, handler }; 01007 return rtai_lxrt(BIDX, SIZARG, SIGNAL_HANDLER, &arg).i[LOW]; 01008 } 01009 01010 RTAI_PROTO(int,rt_task_use_fpu,(RT_TASK *task, int use_fpu_flag)) 01011 { 01012 struct { RT_TASK *task; long use_fpu_flag; } arg = { task, use_fpu_flag }; 01013 if (rtai_lxrt(BIDX, SIZARG, RT_BUDDY, &arg).v[LOW] != task) { 01014 return rtai_lxrt(BIDX, SIZARG, TASK_USE_FPU, &arg).i[LOW]; 01015 } else { 01016 // note that it would be enough to do whatever FP op here to have it OK. But 01017 // that is scary if it is done when already in hard real time, and we do not 01018 // want to force users to call this before making it hard. 01019 rtai_lxrt(BIDX, SIZARG, HRT_USE_FPU, &arg); 01020 return 0; 01021 } 01022 } 01023 01024 RTAI_PROTO(int,rt_buddy_task_use_fpu,(RT_TASK *task, int use_fpu_flag)) 01025 { 01026 struct { RT_TASK *task; long use_fpu_flag; } arg = { task, use_fpu_flag }; 01027 return rtai_lxrt(BIDX, SIZARG, TASK_USE_FPU, &arg).i[LOW]; 01028 } 01029 01030 RTAI_PROTO(int,rt_linux_use_fpu,(int use_fpu_flag)) 01031 { 01032 struct { long use_fpu_flag; } arg = { use_fpu_flag }; 01033 return rtai_lxrt(BIDX, SIZARG, LINUX_USE_FPU, &arg).i[LOW]; 01034 } 01035 01036 RTAI_PROTO(int, rt_hard_timer_tick, (void)) 01037 { 01038 struct { long dummy; } arg; 01039 return rtai_lxrt(BIDX, SIZARG, HARD_TIMER_COUNT, &arg).i[LOW]; 01040 } 01041 01042 RTAI_PROTO(RTIME,rt_get_time_ns,(void)) 01043 { 01044 struct { unsigned long dummy; } arg; 01045 return rtai_lxrt(BIDX, SIZARG, GET_TIME_NS, &arg).rt; 01046 } 01047 01048 RTAI_PROTO(RTIME,rt_get_cpu_time_ns,(void)) 01049 { 01050 struct { unsigned long dummy; } arg; 01051 return rtai_lxrt(BIDX, SIZARG, GET_CPU_TIME_NS, &arg).rt; 01052 } 01053 01054 #define rt_named_task_init(task_name, thread, data, stack_size, prio, uses_fpu, signal) \ 01055 rt_task_init(nam2num(task_name), thread, data, stack_size, prio, uses_fpu, signal) 01056 01057 #define rt_named_task_init_cpuid(task_name, thread, data, stack_size, prio, uses_fpu, signal, run_on_cpu) \ 01058 rt_task_init_cpuid(nam2num(task_name), thread, data, stack_size, prio, uses_fpu, signal, run_on_cpu) 01059 01060 RTAI_PROTO(void,rt_set_runnable_on_cpus,(RT_TASK *task, unsigned long cpu_mask)) 01061 { 01062 struct { RT_TASK *task; unsigned long cpu_mask; } arg = { task, cpu_mask }; 01063 rtai_lxrt(BIDX, SIZARG, SET_RUNNABLE_ON_CPUS, &arg); 01064 } 01065 01066 RTAI_PROTO(void,rt_set_runnable_on_cpuid,(RT_TASK *task, unsigned int cpuid)) 01067 { 01068 struct { RT_TASK *task; unsigned long cpuid; } arg = { task, cpuid }; 01069 rtai_lxrt(BIDX, SIZARG, SET_RUNNABLE_ON_CPUID, &arg); 01070 } 01071 01072 RTAI_PROTO(int,rt_get_timer_cpu,(void)) 01073 { 01074 struct { unsigned long dummy; } arg; 01075 return rtai_lxrt(BIDX, SIZARG, GET_TIMER_CPU, &arg).i[LOW]; 01076 } 01077 01078 RTAI_PROTO(void,start_rt_apic_timers,(struct apic_timer_setup_data *setup_mode, unsigned int rcvr_jiffies_cpuid)) 01079 { 01080 struct { struct apic_timer_setup_data *setup_mode; unsigned long rcvr_jiffies_cpuid; } arg = { setup_mode, rcvr_jiffies_cpuid }; 01081 rtai_lxrt(BIDX, SIZARG, START_RT_APIC_TIMERS, &arg); 01082 } 01083 01084 RTAI_PROTO(int, rt_hard_timer_tick_cpuid, (int cpuid)) 01085 { 01086 struct { unsigned long cpuid; } arg = { cpuid }; 01087 return rtai_lxrt(BIDX, SIZARG, HARD_TIMER_COUNT_CPUID, &arg).i[LOW]; 01088 } 01089 01090 RTAI_PROTO(RTIME,count2nano_cpuid,(RTIME count, unsigned int cpuid)) 01091 { 01092 struct { RTIME count; unsigned long cpuid; } arg = { count, cpuid }; 01093 return rtai_lxrt(BIDX, SIZARG, COUNT2NANO_CPUID, &arg).rt; 01094 } 01095 01096 RTAI_PROTO(RTIME,nano2count_cpuid,(RTIME nanos, unsigned int cpuid)) 01097 { 01098 struct { RTIME nanos; unsigned long cpuid; } arg = { nanos, cpuid }; 01099 return rtai_lxrt(BIDX, SIZARG, NANO2COUNT_CPUID, &arg).rt; 01100 } 01101 01102 RTAI_PROTO(RTIME,rt_get_time_cpuid,(unsigned int cpuid)) 01103 { 01104 struct { unsigned long cpuid; } arg = { cpuid }; 01105 return rtai_lxrt(BIDX, SIZARG, GET_TIME_CPUID, &arg).rt; 01106 } 01107 01108 RTAI_PROTO(RTIME,rt_get_time_ns_cpuid,(unsigned int cpuid)) 01109 { 01110 struct { unsigned long cpuid; } arg = { cpuid }; 01111 return rtai_lxrt(BIDX, SIZARG, GET_TIME_NS_CPUID, &arg).rt; 01112 } 01113 01114 RTAI_PROTO(void,rt_boom,(void)) 01115 { 01116 struct { int dummy; } arg = { 0 }; 01117 rtai_lxrt(BIDX, SIZARG, RT_BOOM, &arg); 01118 } 01119 01120 RTAI_PROTO(void,rt_mmgr_stats,(void)) 01121 { 01122 struct { int dummy; } arg = { 0 }; 01123 rtai_lxrt(BIDX, SIZARG, RT_MMGR_STATS, &arg); 01124 } 01125 01126 RTAI_PROTO(void,rt_stomp,(void) ) 01127 { 01128 struct { int dummy; } arg = { 0 }; 01129 rtai_lxrt(BIDX, SIZARG, RT_STOMP, &arg); 01130 } 01131 01132 RTAI_PROTO(int,rt_get_linux_signal,(RT_TASK *task)) 01133 { 01134 struct { RT_TASK *task; } arg = { task }; 01135 return rtai_lxrt(BIDX, SIZARG, RT_GET_LINUX_SIGNAL, &arg).i[LOW]; 01136 } 01137 01138 RTAI_PROTO(int,rt_get_errno,(RT_TASK *task)) 01139 { 01140 struct { RT_TASK *task; } arg = { task }; 01141 return rtai_lxrt(BIDX, SIZARG, RT_GET_ERRNO, &arg).i[LOW]; 01142 } 01143 01144 RTAI_PROTO(int,rt_set_linux_signal_handler,(RT_TASK *task, void (*handler)(int sig))) 01145 { 01146 struct { RT_TASK *task; void (*handler)(int sig); } arg = { task, handler }; 01147 return rtai_lxrt(BIDX, SIZARG, RT_SET_LINUX_SIGNAL_HANDLER, &arg).i[LOW]; 01148 } 01149 01150 RTAI_PROTO(int,rtai_print_to_screen,(const char *format, ...)) 01151 { 01152 char display[256]; 01153 struct { const char *display; long nch; } arg = { display, 0 }; 01154 va_list args; 01155 01156 va_start(args, format); 01157 arg.nch = vsprintf(display, format, args); 01158 va_end(args); 01159 rtai_lxrt(BIDX, SIZARG, PRINT_TO_SCREEN, &arg); 01160 return arg.nch; 01161 } 01162 01163 RTAI_PROTO(int,rt_printk,(const char *format, ...)) 01164 { 01165 char display[256]; 01166 struct { const char *display; long nch; } arg = { display, 0 }; 01167 va_list args; 01168 01169 va_start(args, format); 01170 arg.nch = vsprintf(display, format, args); 01171 va_end(args); 01172 rtai_lxrt(BIDX, SIZARG, PRINTK, &arg); 01173 return arg.nch; 01174 } 01175 01176 RTAI_PROTO(int,rt_usp_signal_handler,(void (*handler)(void))) 01177 { 01178 struct { void (*handler)(void); } arg = { handler }; 01179 return rtai_lxrt(BIDX, SIZARG, USP_SIGHDL, &arg).i[0]; 01180 } 01181 01182 RTAI_PROTO(unsigned long,rt_get_usp_flags,(RT_TASK *rt_task)) 01183 { 01184 struct { RT_TASK *task; } arg = { rt_task }; 01185 return rtai_lxrt(BIDX, SIZARG, GET_USP_FLAGS, &arg).i[LOW]; 01186 } 01187 01188 RTAI_PROTO(unsigned long,rt_get_usp_flags_mask,(RT_TASK *rt_task)) 01189 { 01190 struct { RT_TASK *task; } arg = { rt_task }; 01191 return rtai_lxrt(BIDX, SIZARG, GET_USP_FLG_MSK, &arg).i[LOW]; 01192 } 01193 01194 RTAI_PROTO(void,rt_set_usp_flags,(RT_TASK *rt_task, unsigned long flags)) 01195 { 01196 struct { RT_TASK *task; unsigned long flags; } arg = { rt_task, flags }; 01197 rtai_lxrt(BIDX, SIZARG, SET_USP_FLAGS, &arg); 01198 } 01199 01200 RTAI_PROTO(void,rt_set_usp_flags_mask,(unsigned long flags_mask)) 01201 { 01202 struct { unsigned long flags_mask; } arg = { flags_mask }; 01203 rtai_lxrt(BIDX, SIZARG, SET_USP_FLG_MSK, &arg); 01204 } 01205 01206 RTAI_PROTO(RT_TASK *,rt_force_task_soft,(int pid)) 01207 { 01208 struct { long pid; } arg = { pid }; 01209 return (RT_TASK *)rtai_lxrt(BIDX, SIZARG, FORCE_TASK_SOFT, &arg).v[LOW]; 01210 } 01211 01212 RTAI_PROTO(RT_TASK *,rt_agent,(void)) 01213 { 01214 struct { unsigned long dummy; } arg; 01215 return (RT_TASK *)rtai_lxrt(BIDX, SIZARG, RT_BUDDY, &arg).v[LOW]; 01216 } 01217 01218 #define rt_buddy() rt_agent() 01219 01220 /** 01221 * Give a Linux process, or pthread, hard real time execution capabilities 01222 * allowing full kernel preemption. 01223 * 01224 * rt_make_hard_real_time makes the soft Linux POSIX real time process, from 01225 * which it is called, a hard real time LXRT process. It is important to 01226 * remark that this function must be used only with soft Linux POSIX processes 01227 * having their memory locked in memory. See Linux man pages. 01228 * 01229 * Only the process itself can use this functions, it is not possible to impose 01230 * the related transition from another process. 01231 * 01232 * Note that processes made hard real time should avoid making any Linux System 01233 * call that can lead to a task switch as Linux cannot run anymore processes 01234 * that are made hard real time. To interact with Linux you should couple the 01235 * process that was made hard real time with a Linux buddy server, either 01236 * standard or POSIX soft real time. To communicate and synchronize with the 01237 * buddy you can use the wealth of available RTAI, and its schedulers, services. 01238 * 01239 * After all it is pure nonsense to use a non hard real time Operating System, 01240 * i.e. Linux, from within hard real time processes. 01241 */ 01242 RTAI_PROTO(void,rt_make_hard_real_time,(void)) 01243 { 01244 struct { unsigned long dummy; } arg; 01245 rtai_lxrt(BIDX, SIZARG, MAKE_HARD_RT, &arg); 01246 } 01247 01248 /** 01249 * Allows a non root user to use the Linux POSIX soft real time process 01250 * management and memory lock functions, and allows it to do any input-output 01251 * operation from user space. 01252 * 01253 * Only the process itself can use this functions, it is not possible to impose 01254 * the related transition from another process. 01255 */ 01256 RTAI_PROTO(void,rt_allow_nonroot_hrt,(void)) 01257 { 01258 struct { unsigned long dummy; } arg; 01259 rtai_lxrt(BIDX, SIZARG, NONROOT_HRT, &arg); 01260 } 01261 01262 RTAI_PROTO(int,rt_is_hard_real_time,(RT_TASK *rt_task)) 01263 { 01264 struct { RT_TASK *task; } arg = { rt_task }; 01265 return rtai_lxrt(BIDX, SIZARG, IS_HARD, &arg).i[LOW]; 01266 } 01267 01268 #define rt_is_soft_real_time(rt_task) (!rt_is_hard_real_time((rt_task))) 01269 01270 RTAI_PROTO(void,rt_task_set_resume_end_times,(RTIME resume, RTIME end)) 01271 { 01272 struct { RTIME resume, end; } arg = { resume, end }; 01273 rtai_lxrt(BIDX, SIZARG, SET_RESUME_END, &arg); 01274 } 01275 01276 RTAI_PROTO(int,rt_set_resume_time,(RT_TASK *rt_task, RTIME new_resume_time)) 01277 { 01278 struct { RT_TASK *rt_task; RTIME new_resume_time; } arg = { rt_task, new_resume_time }; 01279 return rtai_lxrt(BIDX, SIZARG, SET_RESUME_TIME, &arg).i[LOW]; 01280 } 01281 01282 RTAI_PROTO(int,rt_set_period,(RT_TASK *rt_task, RTIME new_period)) 01283 { 01284 struct { RT_TASK *rt_task; RTIME new_period; } arg = { rt_task, new_period }; 01285 return rtai_lxrt(BIDX, SIZARG, SET_PERIOD, &arg).i[LOW]; 01286 } 01287 01288 RTAI_PROTO(void,rt_spv_RMS,(int cpuid)) 01289 { 01290 struct { long cpuid; } arg = { cpuid }; 01291 rtai_lxrt(BIDX, SIZARG, SPV_RMS, &arg); 01292 } 01293 01294 RTAI_PROTO(int, rt_task_masked_unblock,(RT_TASK *task, unsigned long mask)) 01295 { 01296 struct { RT_TASK *task; unsigned long mask; } arg = { task, mask }; 01297 return rtai_lxrt(BIDX, SIZARG, WAKEUP_SLEEPING, &arg).i[LOW]; 01298 } 01299 01300 #define rt_task_wakeup_sleeping(task, mask) rt_task_masked_unblock(task, RT_SCHED_DELAYED) 01301 01302 RTAI_PROTO(void,rt_get_exectime,(RT_TASK *task, RTIME *exectime)) 01303 { 01304 RTIME lexectime[] = { 0LL, 0LL, 0LL }; 01305 struct { RT_TASK *task; RTIME *lexectime; } arg = { task, lexectime }; 01306 rtai_lxrt(BIDX, SIZARG, GET_EXECTIME, &arg); 01307 memcpy(exectime, lexectime, sizeof(lexectime)); 01308 } 01309 01310 RTAI_PROTO(void,rt_gettimeorig,(RTIME time_orig[])) 01311 { 01312 struct { RTIME *time_orig; } arg = { time_orig }; 01313 rtai_lxrt(BIDX, SIZARG, GET_TIMEORIG, &arg); 01314 } 01315 01316 RTAI_PROTO(RT_TASK *,ftask_init,(unsigned long name, int priority)) 01317 { 01318 struct { unsigned long name; int priority, stack_size, max_msg_size, cpus_allowed; } arg = { name, priority, 0, 0, 0 }; 01319 return (RT_TASK *)rtai_lxrt(BIDX, SIZARG, LXRT_TASK_INIT, &arg).v[LOW]; 01320 } 01321 01322 RTAI_PROTO(RTIME, start_ftimer,(long period, long ftick_freq)) 01323 { 01324 struct { long ftick_freq; void *handler; } arg = { ftick_freq, NULL }; 01325 if (!period) { 01326 rtai_lxrt(BIDX, sizeof(long), SET_ONESHOT_MODE, &period); 01327 } else { 01328 rtai_lxrt(BIDX, sizeof(long), SET_PERIODIC_MODE, &period); 01329 } 01330 rtai_lxrt(BIDX, SIZARG, REQUEST_RTC, &arg); 01331 return rtai_lxrt(BIDX, sizeof(long), START_TIMER, &period).rt; 01332 } 01333 01334 RTAI_PROTO(RTIME, stop_ftimer,(void)) 01335 { 01336 struct { long dummy; } arg; 01337 rtai_lxrt(BIDX, SIZARG, RELEASE_RTC, &arg); 01338 return rtai_lxrt(BIDX, SIZARG, STOP_TIMER, &arg).rt; 01339 } 01340 01341 #ifdef __cplusplus 01342 } 01343 #endif /* __cplusplus */ 01344 01345 #endif /* __KERNEL__ */ 01346 01347 /*@}*/ 01348 01349 #endif /* !_RTAI_LXRT_H */

Generated on Thu Nov 20 11:49:49 2008 for RTAI API by doxygen 1.3.8