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 GET_TASK_INFO           17  // was LINUX_USE_FPU
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 SET_LINUX_SYSCALL_MODE         212
00316 /*#define RETURN_LINUX_SYSCALL         213 available */
00317 #define REQUEST_RTC                    214
00318 #define RELEASE_RTC                    215
00319 #define RT_GETTID                      216
00320 #define SET_NETRPC_TIMEOUT             217
00321 #define GET_REAL_TIME              218
00322 #define GET_REAL_TIME_NS           219
00323 
00324 #define MQ_REG_USP_NOTIFIER        220
00325 
00326 #define RT_SIGNAL_HELPER           221
00327 #define RT_SIGNAL_WAITSIG          222
00328 #define RT_SIGNAL_REQUEST          223
00329 #define RT_SIGNAL_RELEASE          224
00330 #define RT_SIGNAL_ENABLE           225
00331 #define RT_SIGNAL_DISABLE          226
00332 #define RT_SIGNAL_TRIGGER          227
00333 
00334 #define SEM_RT_POLL                228
00335 #define RT_POLL_NETRPC             229
00336 
00337 #define MAX_LXRT_FUN               230
00338 
00339 // not recovered yet 
00340 // Qblk's 
00341 #define RT_INITTICKQUEUE        69
00342 #define RT_RELEASETICKQUEUE         70
00343 #define RT_QDYNALLOC                71
00344 #define RT_QDYNFREE                 72
00345 #define RT_QDYNINIT                 73
00346 #define RT_QBLKWAIT         74
00347 #define RT_QBLKREPEAT           75
00348 #define RT_QBLKSOON         76
00349 #define RT_QBLKDEQUEUE          77
00350 #define RT_QBLKCANCEL           78
00351 #define RT_QSYNC            79
00352 #define RT_QRECEIVE         80
00353 #define RT_QLOOP            81
00354 #define RT_QSTEP            82
00355 #define RT_QBLKBEFORE           83
00356 #define RT_QBLKAFTER            84
00357 #define RT_QBLKUNHOOK           85
00358 #define RT_QBLKRELEASE          86
00359 #define RT_QBLKCOMPLETE         87
00360 #define RT_QHOOKFLUSH           88
00361 #define RT_QBLKATHEAD           89
00362 #define RT_QBLKATTAIL           90
00363 #define RT_QHOOKINIT            91
00364 #define RT_QHOOKRELEASE         92
00365 #define RT_QBLKSCHEDULE         93
00366 #define RT_GETTICKQUEUEHOOK     94
00367 // Testing
00368 #define RT_BOOM             95
00369 #define RTAI_MALLOC         96
00370 #define RT_FREE             97
00371 #define RT_MMGR_STATS           98
00372 #define RT_STOMP                    99
00373 // VC
00374 #define RT_VC_ATTACH                100
00375 #define RT_VC_RELEASE               101
00376 #define RT_VC_RESERVE               102
00377 // Linux Signal Support
00378 #define RT_GET_LINUX_SIGNAL     103
00379 #define RT_GET_ERRNO            104
00380 #define RT_SET_LINUX_SIGNAL_HANDLER 105
00381 // end of not recovered yet
00382 
00383 #define LXRT_GET_ADR        1000
00384 #define LXRT_GET_NAME       1001
00385 #define LXRT_TASK_INIT      1002
00386 #define LXRT_TASK_DELETE    1003
00387 #define LXRT_SEM_INIT       1004
00388 #define LXRT_SEM_DELETE     1005
00389 #define LXRT_MBX_INIT       1006
00390 #define LXRT_MBX_DELETE     1007
00391 #define MAKE_SOFT_RT        1008
00392 #define MAKE_HARD_RT        1009
00393 #define PRINT_TO_SCREEN     1010
00394 #define NONROOT_HRT     1011
00395 #define RT_BUDDY        1012
00396 #define HRT_USE_FPU         1013
00397 #define USP_SIGHDL          1014
00398 #define GET_USP_FLAGS       1015
00399 #define SET_USP_FLAGS       1016
00400 #define GET_USP_FLG_MSK     1017
00401 #define SET_USP_FLG_MSK     1018
00402 #define IS_HARD             1019
00403 #define LINUX_SERVER_INIT   1020
00404 #define ALLOC_REGISTER      1021
00405 #define DELETE_DEREGISTER   1022
00406 #define FORCE_TASK_SOFT     1023
00407 #define PRINTK          1024
00408 #define GET_EXECTIME        1025
00409 #define GET_TIMEORIG        1026
00410 #define LXRT_RWL_INIT       1027
00411 #define LXRT_RWL_DELETE     1028
00412 #define LXRT_SPL_INIT       1029
00413 #define LXRT_SPL_DELETE     1030
00414 
00415 #define FORCE_SOFT 0x80000000
00416 
00417 // Keep LXRT call enc/decoding together, so you are sure to act consistently.
00418 // This is the encoding, note " | GT_NR_SYSCALLS" to ensure not a Linux syscall, ...
00419 #define GT_NR_SYSCALLS  (1 << 11)
00420 #define ENCODE_LXRT_REQ(dynx, srq, lsize)  (((dynx) << 24) | ((srq) << 12) | GT_NR_SYSCALLS | (lsize))
00421 // ... and this is the decoding.
00422 #define SRQ(x)   (((x) >> 12) & 0xFFF)
00423 #define NARG(x)  ((x) & (GT_NR_SYSCALLS - 1))
00424 #define INDX(x)  (((x) >> 24) & 0xF)
00425 
00426 #define SYNC_LINUX_SYSCALL   1
00427 #define ASYNC_LINUX_SYSCALL  0
00428 
00429 #define SRV_NSYSCALL_REGS  7
00430 #define PAC_NSYSCALL_ARGS  6
00431 
00432 struct mode_regs { long regs[SRV_NSYSCALL_REGS], mode, pacargs[PAC_NSYSCALL_ARGS]; };
00433 struct linux_syscalls_list { int in, out, nr, mode; void *serv; struct mode_regs *moderegs; RT_TASK *task; void (*callback_fun)(long, long); long retval; };
00434 
00435 #ifdef __KERNEL__
00436 
00437 #include <asm/rtai_lxrt.h>
00438 
00439 /*
00440      Encoding of system call argument
00441             31                                    0  
00442 soft SRQ    .... |||| |||| |||| .... .... .... ....  0 - 4095 max
00443 int  NARG   .... .... .... .... |||| |||| |||| ||||  
00444 arg  INDX   |||| .... .... .... .... .... .... ....
00445 */
00446 
00447 /*
00448 These USP (unsigned long) type fields allow to read and write up to 2 arguments.  
00449                                                
00450 The high part of the unsigned long encodes writes
00451 W ARG1 BF .... .... ..|| |... .... .... .... ....
00452 W ARG1 SZ .... ...| ||.. .... .... .... .... ....
00453 W ARG2 BF .... |||. .... .... .... .... .... ....
00454 W ARG2 SZ .||| .... .... .... .... .... .... ....
00455 
00456 The low part of the unsigned long encodes writes
00457 R ARG1 BF .... .... .... .... .... .... ..|| |...
00458 R ARG1 SZ .... .... .... .... .... ...| ||.. ....
00459 R ARG2 BF .... .... .... .... .... |||. .... ....
00460 R ARG2 SZ .... .... .... .... .||| .... .... ....
00461 
00462 The low part of the unsigned long encodes also
00463 RT Switch .... .... .... .... .... .... .... ...|
00464 
00465 If SZ is zero sizeof(int) is copied by default, if LL bit is set sizeof(long long) is copied.
00466 */
00467 
00468 // These are for setting appropriate bits in any function entry structure, OR
00469 // them in fun entry type to obtain the desired encoding
00470 
00471 // for writes
00472 #define UW1(bf, sz)  ((((bf) & 0x7) << 19) | (((sz) & 0x7) << 22))
00473 #define UW2(bf, sz)  ((((bf) & 0x7) << 25) | (((sz) & 0x7) << 28))
00474 
00475 // for reads
00476 #define UR1(bf, sz)  ((((bf) & 0x7) << 3) | (((sz) & 0x7) <<  6))
00477 #define UR2(bf, sz)  ((((bf) & 0x7) << 9) | (((sz) & 0x7) << 12))
00478 
00479 #define NEED_TO_RW(x)   ((x) & 0xFFFFFFFE)
00480 
00481 #define NEED_TO_W(x)    ((x) & (0x3F << 19))
00482 #define NEED_TO_W2ND(x) ((x) & (0x3F << 25))
00483 
00484 #define NEED_TO_R(x)    ((x) & (0x3F <<  3))
00485 #define NEED_TO_R2ND(x) ((x) & (0x3F <<  9))
00486 
00487 #define USP_WBF1(x)     (((x) >> 19) & 0x7)
00488 #define USP_WSZ1(x)     (((x) >> 22) & 0x7)
00489 #define USP_WBF2(x)     (((x) >> 25) & 0x7)
00490 #define USP_WSZ2(x)     (((x) >> 28) & 0x7)
00491 
00492 #define USP_RBF1(x)     (((x) >>  3) & 0x7)
00493 #define USP_RSZ1(x)     (((x) >>  6) & 0x7)
00494 #define USP_RBF2(x)     (((x) >>  9) & 0x7)
00495 #define USP_RSZ2(x)     (((x) >> 12) & 0x7)
00496 
00497 struct rt_fun_entry {
00498     unsigned long type;
00499     void *fun;
00500 };
00501 
00502 struct rt_native_fun_entry {
00503     struct rt_fun_entry fun;
00504     int index;
00505 };
00506 
00507 extern struct rt_fun_entry rt_fun_lxrt[];
00508 
00509 void reset_rt_fun_entries(struct rt_native_fun_entry *entry);
00510 
00511 int set_rt_fun_entries(struct rt_native_fun_entry *entry);
00512 
00513 #ifdef __cplusplus
00514 extern "C" {
00515 #endif /* __cplusplus */
00516 
00517 #if 1 // needs CONFIG_RTAI_INTERNAL_LXRT_SUPPORT no more
00518  
00519 static inline struct rt_task_struct *pid2rttask(long pid)
00520 {
00521     struct task_struct *lnxtsk = find_task_by_pid(pid);
00522         return lnxtsk ? lnxtsk->rtai_tskext(TSKEXT0) : NULL;
00523     return ((unsigned long)pid) > PID_MAX_LIMIT ? (struct rt_task_struct *)pid : find_task_by_pid(pid)->rtai_tskext(TSKEXT0);
00524 }
00525 
00526 static inline long rttask2pid(struct rt_task_struct * task)
00527 {
00528     return task->lnxtsk ? task->lnxtsk->pid : (long)task;
00529 }
00530 
00531 #else /* !CONFIG_RTAI_INTERNAL_LXRT_SUPPORT */
00532 
00533 static inline struct rt_task_struct *pid2rttask(pid_t pid)
00534 {
00535     return 0;
00536 }
00537 
00538 // The following might look strange but it must be so to work with
00539 // buddies also.
00540 static inline pid_t rttask2pid(struct rt_task_struct * task)
00541 {
00542     return (long) task;
00543 }
00544 
00545 #endif /* CONFIG_RTAI_INTERNAL_LXRT_SUPPORT */
00546 
00547 int set_rtai_callback(void (*fun)(void));
00548 
00549 void remove_rtai_callback(void (*fun)(void));
00550 
00551 RT_TASK *rt_lxrt_whoami(void);
00552 
00553 void exec_func(void (*func)(void *data, int evn),
00554            void *data,
00555            int evn);
00556 
00557 int  set_rt_fun_ext_index(struct rt_fun_entry *fun,
00558               int idx);
00559 
00560 void reset_rt_fun_ext_index(struct rt_fun_entry *fun,
00561                 int idx);
00562 
00563 #ifdef __cplusplus
00564 }
00565 #endif /* __cplusplus */
00566 
00567 #else /* !__KERNEL__ */
00568 
00569 #include <sys/types.h>
00570 #include <sys/mman.h>
00571 #include <sched.h>
00572 #include <stdarg.h>
00573 #include <stdio.h>
00574 #include <stdlib.h>
00575 #include <string.h>
00576 #include <asm/rtai_lxrt.h>
00577 
00578 struct apic_timer_setup_data;
00579 
00580 #ifdef CONFIG_MMU
00581 
00582 #define rt_grow_and_lock_stack(incr) \
00583     do { \
00584         char buf[incr]; \
00585         memset(buf, 0, incr); \
00586         mlockall(MCL_CURRENT | MCL_FUTURE); \
00587     } while (0)
00588 
00589 #else
00590 
00591 #define rt_grow_and_lock_stack(incr) do { } while (0)
00592 
00593 #endif
00594 
00595 #define BIDX   0 // rt_fun_ext[0]
00596 #define SIZARG sizeof(arg)
00597 
00598 #ifdef __cplusplus
00599 extern "C" {
00600 #endif /* __cplusplus */
00601 
00602 /**
00603  * Get an object address by its name.
00604  *
00605  * rt_get_adr returns the address associated to @a name.
00606  *
00607  * @return the address associated to @a name on success, 0 on failure
00608  */
00609 RTAI_PROTO(void *, rt_get_adr, (unsigned long name))
00610 {
00611     struct { unsigned long name; } arg = { name };
00612     return rtai_lxrt(BIDX, SIZARG, LXRT_GET_ADR, &arg).v[LOW];
00613 } 
00614 
00615 /**
00616  * Get an object name by its address.
00617  *
00618  * rt_get_name returns the name pointed by the address @a adr.
00619  *
00620  * @return the identifier pointed by the address @a adr on success, 0 on
00621  * failure.
00622  */
00623 RTAI_PROTO(unsigned long, rt_get_name, (void *adr))
00624 {
00625     struct { void *adr; } arg = { adr };
00626     return rtai_lxrt(BIDX, SIZARG, LXRT_GET_NAME, &arg).i[LOW];
00627 }
00628 
00629 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))
00630 {
00631         struct sched_param mysched;
00632         struct { unsigned long name; long priority, stack_size, max_msg_size, cpus_allowed; } arg = { name ? name : rt_get_name(NULL), priority, stack_size, max_msg_size, cpus_allowed };
00633 
00634         if (policy == SCHED_OTHER) {
00635             mysched.sched_priority = 0;
00636     } else if ((mysched.sched_priority = sched_get_priority_max(policy) - priority) < 1) {
00637         mysched.sched_priority = 1;
00638     }
00639         if (sched_setscheduler(0, policy, &mysched) < 0) {
00640                 return 0;
00641         }
00642     rtai_iopl();
00643     mlockall(MCL_CURRENT | MCL_FUTURE);
00644 
00645     return (RT_TASK *)rtai_lxrt(BIDX, SIZARG, LXRT_TASK_INIT, &arg).v[LOW];
00646 }
00647 
00648 static inline int rt_clone(void *fun, void *args, long stack_size, unsigned long flags)
00649 {
00650     void *sp;
00651     if (!flags) {
00652         flags = CLONE_VM | CLONE_FS | CLONE_FILES;
00653     }
00654     memset(sp = malloc(stack_size), 0, stack_size);
00655     sp = (void *)(((unsigned long)sp + stack_size - 16) & ~0xF);
00656     return clone((int (*)(void *))fun, sp, flags, args);
00657 }
00658 
00659 #define RT_THREAD_STACK_MIN  64*1024
00660 
00661 #include <pthread.h>
00662 
00663 RTAI_PROTO(long, rt_thread_create, (void *fun, void *args, int stack_size))
00664 {
00665     long thread;
00666     pthread_attr_t attr;
00667 
00668         pthread_attr_init(&attr);
00669     if (!pthread_attr_setstacksize(&attr, stack_size > RT_THREAD_STACK_MIN ? stack_size : RT_THREAD_STACK_MIN)) {
00670         struct { unsigned long hs; } arg = { 0 };
00671         if ((arg.hs = rtai_lxrt(BIDX, SIZARG, IS_HARD, &arg).i[LOW])) {
00672             rtai_lxrt(BIDX, SIZARG, MAKE_SOFT_RT, &arg);
00673         }
00674         if (pthread_create((pthread_t *)&thread, &attr, (void *(*)(void *))fun, args)) {
00675             thread = 0;
00676         }
00677         if (arg.hs) {
00678             rtai_lxrt(BIDX, SIZARG, MAKE_HARD_RT, &arg);
00679         }
00680     } else {
00681         thread = 0;
00682     }
00683     return thread;
00684 }
00685 
00686 RTAI_PROTO(int, rt_thread_join, (long thread))
00687 {
00688     return pthread_join((pthread_t)thread, NULL);
00689 }
00690 
00691 #ifndef __SUPPORT_LINUX_SERVER__
00692 #define __SUPPORT_LINUX_SERVER__
00693 
00694 #include <unistd.h>
00695 #include <sys/mman.h>
00696 
00697 RTAI_PROTO(int, rt_thread_delete, (RT_TASK *task));
00698 static void linux_syscall_server_fun(struct linux_syscalls_list *list)
00699 {
00700     struct linux_syscalls_list syscalls = *list;
00701 
00702     syscalls.serv = &syscalls;
00703     syscalls.in = syscalls.out = 0;
00704 
00705     if ((syscalls.serv = rtai_lxrt(BIDX, sizeof(struct linux_syscalls_list), LINUX_SERVER_INIT, &syscalls).v[LOW])) {
00706         long *regs;
00707         struct mode_regs moderegs[syscalls.nr];
00708         memset(moderegs, 0, sizeof(moderegs));
00709         syscalls.moderegs = moderegs;
00710                 mlockall(MCL_CURRENT | MCL_FUTURE);
00711         rtai_lxrt(BIDX, sizeof(RT_TASK *), RESUME, &syscalls.task);
00712         while (abs(rtai_lxrt(BIDX, sizeof(RT_TASK *), SUSPEND, &syscalls.serv).i[LOW]) < RTE_LOWERR) {
00713             regs = moderegs[syscalls.out].regs;
00714             syscalls.retval = syscall(regs[0], regs[1], regs[2], regs[3], regs[4], regs[5], regs[6]);
00715             if (syscalls.moderegs[syscalls.out].mode == SYNC_LINUX_SYSCALL) {
00716                 rtai_lxrt(BIDX, sizeof(RT_TASK *), RESUME, &syscalls.task);
00717             } else if (syscalls.callback_fun) {
00718                 syscalls.callback_fun(regs[0], syscalls.retval);
00719             }
00720             if (++syscalls.out >= syscalls.nr) {
00721                 syscalls.out = 0;
00722             }
00723         }
00724         }
00725     rt_thread_delete((RT_TASK *)syscalls.serv);
00726 }
00727 
00728 #endif /* __SUPPORT_LINUX_SERVER__ */
00729 
00730 RTAI_PROTO(void, rt_set_linux_syscall_mode, (int mode, void (*callback_fun)(long, long)))
00731 {
00732     struct { long mode; void (*callback_fun)(long, long); } arg = { mode, callback_fun };
00733     rtai_lxrt(BIDX, SIZARG, SET_LINUX_SYSCALL_MODE, &arg);
00734 }
00735 
00736 RTAI_PROTO(int, rt_create_linux_syscall_server, (RT_TASK *task, int mode, void (*callback_fun)(long, long), int nr_bufd_async_calls))
00737 {
00738     if ((task || (task = (RT_TASK *)rtai_lxrt(BIDX, sizeof(RT_TASK *), RT_BUDDY, &task).v[LOW])) && nr_bufd_async_calls > 0) {
00739         struct linux_syscalls_list syscalls;
00740         syscalls.task         = task;
00741         syscalls.callback_fun = callback_fun;
00742         syscalls.mode         = mode;
00743         syscalls.nr           = nr_bufd_async_calls + 1;
00744         if (rt_thread_create((void *)linux_syscall_server_fun, &syscalls, RT_THREAD_STACK_MIN + syscalls.nr*sizeof(struct mode_regs))) {
00745             rtai_lxrt(BIDX, sizeof(RT_TASK *), SUSPEND, &task);
00746             return 0;
00747         }
00748     }
00749     return -1;
00750 }
00751 
00752 #define rt_sync_async_linux_syscall_server_create(task, mode, cbfun, nr_calls)  rt_create_linux_syscall_server(task, mode, cbfun, nr_calls)
00753 
00754 #define rt_linux_syscall_server_create(task)  rt_sync_async_linux_syscall_server_create(task, SYNC_LINUX_SYSCALL, NULL, 1);
00755 
00756 RTAI_PROTO(RT_TASK *, rt_thread_init, (unsigned long name, int priority, int max_msg_size, int policy, int cpus_allowed))
00757 {
00758     return rt_task_init_schmod(name, priority, 0, max_msg_size, policy, cpus_allowed);
00759 }
00760 
00761 /**
00762  * Create an RTAI task extension for a Linux process/task in user space.
00763  * 
00764  * rt_task_init extends the Linux task structure, making it possible to use
00765  * RTAI APIs that wants to access RTAI scheduler services.   It needs no task
00766  * function as none is used, but it does need to setup an RTAI task structure
00767  * and initialize it appropriately as the provided services are carried out as
00768  * if the Linux process has become an RTAI task also.   Because of that it 
00769  * requires less arguments and returns the pointer to the RTAI task extension
00770  * that is to be used in related calls.
00771  *
00772  * @param name is a unique identifier that is possibly used to ease
00773  * referencing the RTAI task extension of a peer Linux process.
00774  *
00775  * @param priority is the priority of the RTAI task extension.
00776  *
00777  * @param stack_size, a legacy parameter used nomore; kept for portability 
00778  * reasons only. (It was just what is implied by such a name and referred to 
00779  * the stack size used by the buddy in the very first implementation of LXRT).
00780  *
00781  * @param max_msg_size is a hint for the size of the most lengthy intertask
00782  * message that is likely to be exchanged.
00783  *
00784  * @a max_msg_size can be zero, in which case a default internal value is
00785  * used.  Keep an eye on such a default message (256) size. It could be 
00786  * possible that a larger size is required to suite your needs best. In such 
00787  * a case either recompile sys.c with the macro MSG_SIZE set appropriately, 
00788  * or assign a larger size here esplicitly.  Note that the message size is 
00789  * not critical though. In fact the module reassigns it, dynamically and 
00790  * appropriately sized, whenever it is needed.  The cost is a real time 
00791  * allocation of the new buffer.
00792  * Note also that @a max_msg_size is for a buffer to be used to copy whatever
00793  * intertask message from user to kernel space, as intertask messages are not 
00794  * necessarily used immediately.
00795  *
00796  * It is important to remark that the returned task pointers cannot be used
00797  * directly, they are for kernel space data, but just passed as arguments when
00798  * needed.
00799  *
00800  * @return On success a pointer to the task structure initialized in kernel
00801  * space.
00802  * @return On failure a NULL value is returned if it was not possible to setup 
00803  * the RTAI task extension or something using the same name was found.
00804  */
00805 RTAI_PROTO(RT_TASK *,rt_task_init,(unsigned long name, int priority, int stack_size, int max_msg_size))
00806 {
00807     return rt_task_init_schmod(name, priority, 0, max_msg_size, SCHED_FIFO, 0xFF);
00808 }
00809 
00810 RTAI_PROTO(void,rt_set_sched_policy,(RT_TASK *task, int policy, int rr_quantum_ns))
00811 {
00812     struct { RT_TASK *task; long policy; long rr_quantum_ns; } arg = { task, policy, rr_quantum_ns };
00813     rtai_lxrt(BIDX, SIZARG, SET_SCHED_POLICY, &arg);
00814 }
00815 
00816 RTAI_PROTO(int,rt_change_prio,(RT_TASK *task, int priority))
00817 {
00818     struct { RT_TASK *task; long priority; } arg = { task, priority };
00819     return rtai_lxrt(BIDX, SIZARG, CHANGE_TASK_PRIO, &arg).i[LOW];
00820 }
00821 
00822 /**
00823  * Return a hard real time Linux process, or pthread to the standard Linux
00824  * behavior.
00825  *
00826  * rt_make_soft_real_time returns to soft Linux POSIX real time a process, from
00827  * which it is called, that was made hard real time by a call to
00828  * rt_make_hard_real_time.
00829  *
00830  * Only the process itself can use this functions, it is not possible to impose
00831  * the related transition from another process.
00832  *
00833  */
00834 RTAI_PROTO(void,rt_make_soft_real_time,(void))
00835 {
00836     struct { unsigned long dummy; } arg;
00837     rtai_lxrt(BIDX, SIZARG, MAKE_SOFT_RT, &arg);
00838 }
00839 
00840 RTAI_PROTO(int, rt_thread_delete, (RT_TASK *task))
00841 {
00842     struct { RT_TASK *task; } arg = { task };
00843     rt_make_soft_real_time();
00844     return rtai_lxrt(BIDX, SIZARG, LXRT_TASK_DELETE, &arg).i[LOW];
00845 }
00846 
00847 #define rt_task_delete(task)  rt_thread_delete(task)
00848 
00849 RTAI_PROTO(int,rt_task_yield,(void))
00850 {
00851     struct { unsigned long dummy; } arg;
00852     return rtai_lxrt(BIDX, SIZARG, YIELD, &arg).i[LOW];
00853 }
00854 
00855 RTAI_PROTO(int,rt_task_suspend,(RT_TASK *task))
00856 {
00857     struct { RT_TASK *task; } arg = { task };
00858     return rtai_lxrt(BIDX, SIZARG, SUSPEND, &arg).i[LOW];
00859 }
00860 
00861 RTAI_PROTO(int,rt_task_suspend_if,(RT_TASK *task))
00862 {
00863     struct { RT_TASK *task; } arg = { task };
00864     return rtai_lxrt(BIDX, SIZARG, SUSPEND_IF, &arg).i[LOW];
00865 }
00866 
00867 RTAI_PROTO(int,rt_task_suspend_until,(RT_TASK *task, RTIME time))
00868 {
00869     struct { RT_TASK *task; RTIME time; } arg = { task, time };
00870     return rtai_lxrt(BIDX, SIZARG, SUSPEND_UNTIL, &arg).i[LOW];
00871 }
00872 
00873 RTAI_PROTO(int,rt_task_suspend_timed,(RT_TASK *task, RTIME delay))
00874 {
00875     struct { RT_TASK *task; RTIME delay; } arg = { task, delay };
00876     return rtai_lxrt(BIDX, SIZARG, SUSPEND_TIMED, &arg).i[LOW];
00877 }
00878 
00879 RTAI_PROTO(int,rt_task_resume,(RT_TASK *task))
00880 {
00881     struct { RT_TASK *task; } arg = { task };
00882     return rtai_lxrt(BIDX, SIZARG, RESUME, &arg).i[LOW];
00883 }
00884 
00885 RTAI_PROTO(void, rt_sched_lock, (void))
00886 {
00887     struct { long dummy; } arg;
00888     rtai_lxrt(BIDX, SIZARG, SCHED_LOCK, &arg);
00889 }
00890 
00891 RTAI_PROTO(void, rt_sched_unlock, (void))
00892 {
00893     struct { long dummy; } arg;
00894     rtai_lxrt(BIDX, SIZARG, SCHED_UNLOCK, &arg);
00895 }
00896 
00897 RTAI_PROTO(void, rt_pend_linux_irq, (unsigned irq))
00898 {
00899     struct { unsigned irq; } arg = { irq };
00900     rtai_lxrt(BIDX, SIZARG, PEND_LINUX_IRQ, &arg);
00901 }
00902 
00903 RTAI_PROTO(int, rt_irq_wait, (unsigned irq))
00904 {
00905     struct { unsigned irq; } arg = { irq };
00906     return rtai_lxrt(BIDX, SIZARG, IRQ_WAIT, &arg).i[LOW];
00907 }
00908 
00909 RTAI_PROTO(int, rt_irq_wait_if, (unsigned irq))
00910 {
00911     struct { unsigned irq; } arg = { irq };
00912     return rtai_lxrt(BIDX, SIZARG, IRQ_WAIT_IF, &arg).i[LOW];
00913 }
00914 
00915 RTAI_PROTO(int, rt_irq_wait_until, (unsigned irq, RTIME time))
00916 {
00917     struct { unsigned irq; RTIME time; } arg = { irq, time };
00918     return rtai_lxrt(BIDX, SIZARG, IRQ_WAIT_UNTIL, &arg).i[LOW];
00919 }
00920 
00921 RTAI_PROTO(int, rt_irq_wait_timed, (unsigned irq, RTIME delay))
00922 {
00923     struct { unsigned irq; RTIME delay; } arg = { irq, delay };
00924     return rtai_lxrt(BIDX, SIZARG, IRQ_WAIT_TIMED, &arg).i[LOW];
00925 }
00926 
00927 RTAI_PROTO(int, rt_irq_signal, (unsigned irq))
00928 {
00929     struct { unsigned irq; } arg = { irq };
00930     return rtai_lxrt(BIDX, SIZARG, IRQ_SIGNAL, &arg).i[LOW];
00931 }
00932 
00933 RTAI_PROTO(int, rt_request_irq_task, (unsigned irq, void *handler, int type, int affine2task))
00934 {
00935     struct { unsigned irq; void *handler; long type, affine2task; } arg = { irq, handler, type, affine2task };
00936     return rtai_lxrt(BIDX, SIZARG, REQUEST_IRQ_TASK, &arg).i[LOW];
00937 }
00938 
00939 
00940 RTAI_PROTO(int, rt_release_irq_task, (unsigned irq))
00941 {
00942     struct { unsigned irq; } arg = { irq };
00943     return rtai_lxrt(BIDX, SIZARG, RELEASE_IRQ_TASK, &arg).i[LOW];
00944 }
00945 
00946 RTAI_PROTO(int, rt_task_make_periodic,(RT_TASK *task, RTIME start_time, RTIME period))
00947 {
00948     struct { RT_TASK *task; RTIME start_time, period; } arg = { task, start_time, period };
00949     return rtai_lxrt(BIDX, SIZARG, MAKE_PERIODIC, &arg).i[LOW];
00950 }
00951 
00952 RTAI_PROTO(int,rt_task_make_periodic_relative_ns,(RT_TASK *task, RTIME start_delay, RTIME period))
00953 {
00954     struct { RT_TASK *task; RTIME start_time, period; } arg = { task, start_delay, period };
00955     return rtai_lxrt(BIDX, SIZARG, MAKE_PERIODIC_NS, &arg).i[LOW];
00956 }
00957 
00958 RTAI_PROTO(int,rt_task_wait_period,(void))
00959 {
00960     struct { unsigned long dummy; } arg;
00961     return rtai_lxrt(BIDX, SIZARG, WAIT_PERIOD, &arg).i[LOW];
00962 }
00963 
00964 RTAI_PROTO(int,rt_sleep,(RTIME delay))
00965 {
00966     struct { RTIME delay; } arg = { delay };
00967     return rtai_lxrt(BIDX, SIZARG, SLEEP, &arg).i[LOW];
00968 }
00969 
00970 RTAI_PROTO(int,rt_sleep_until,(RTIME time))
00971 {
00972     struct { RTIME time; } arg = { time };
00973     return rtai_lxrt(BIDX, SIZARG, SLEEP_UNTIL, &arg).i[LOW];
00974 }
00975 
00976 RTAI_PROTO(int,rt_is_hard_timer_running,(void))
00977 {
00978     struct { unsigned long dummy; } arg;
00979     return rtai_lxrt(BIDX, SIZARG, HARD_TIMER_RUNNING, &arg).i[LOW];
00980 }
00981 
00982 RTAI_PROTO(RTIME, start_rt_timer, (int period))
00983 {
00984     int hs;
00985     RTIME retval;
00986     struct { long period; } arg = { 0 };
00987     if ((hs = rtai_lxrt(BIDX, SIZARG, IS_HARD, &arg).i[LOW])) {
00988         rtai_lxrt(BIDX, SIZARG, MAKE_SOFT_RT, &arg);
00989     }
00990     arg.period = period;
00991     retval = rtai_lxrt(BIDX, SIZARG, START_TIMER, &arg).rt;
00992     if (hs) {
00993         rtai_lxrt(BIDX, SIZARG, MAKE_HARD_RT, &arg);
00994     }
00995     return retval;
00996 }
00997 
00998 RTAI_PROTO(void, stop_rt_timer, (void))
00999 {
01000     struct { long hs; } arg = { 0 };
01001     if ((arg.hs = rtai_lxrt(BIDX, SIZARG, IS_HARD, &arg).i[LOW])) {
01002         rtai_lxrt(BIDX, SIZARG, MAKE_SOFT_RT, &arg);
01003     }
01004     rtai_lxrt(BIDX, SIZARG, STOP_TIMER, &arg);
01005     if (arg.hs) {
01006         rtai_lxrt(BIDX, SIZARG, MAKE_HARD_RT, &arg);
01007     }
01008 }
01009 
01010 RTAI_PROTO(void, rt_request_rtc,(int rtc_freq, void *handler))
01011 {
01012     struct { long rtc_freq; void *handler; } arg = { rtc_freq, handler };
01013     rtai_lxrt(BIDX, SIZARG, REQUEST_RTC, &arg);
01014 }
01015 
01016 RTAI_PROTO(void, rt_release_rtc,(void))
01017 {
01018     struct { unsigned long dummy; } arg;
01019     rtai_lxrt(BIDX, SIZARG, RELEASE_RTC, &arg);
01020 }
01021 
01022 RTAI_PROTO(RTIME,rt_get_time,(void))
01023 {
01024     struct { unsigned long dummy; } arg;
01025     return rtai_lxrt(BIDX, SIZARG, GET_TIME, &arg).rt;
01026 }
01027 
01028 RTAI_PROTO(RTIME, rt_get_real_time, (void))
01029 {
01030     struct { unsigned long dummy; } arg;
01031     return rtai_lxrt(BIDX, SIZARG, GET_REAL_TIME, &arg).rt;
01032 }
01033 
01034 RTAI_PROTO(RTIME, rt_get_real_time_ns, (void))
01035 {
01036     struct { unsigned long dummy; } arg;
01037     return rtai_lxrt(BIDX, SIZARG, GET_REAL_TIME_NS, &arg).rt;
01038 }
01039 
01040 RTAI_PROTO(RTIME,count2nano,(RTIME count))
01041 {
01042     struct { RTIME count; } arg = { count };
01043     return rtai_lxrt(BIDX, SIZARG, COUNT2NANO, &arg).rt;
01044 }
01045 
01046 RTAI_PROTO(RTIME,nano2count,(RTIME nanos))
01047 {
01048     struct { RTIME nanos; } arg = { nanos };
01049     return rtai_lxrt(BIDX, SIZARG, NANO2COUNT, &arg).rt;
01050 }
01051 
01052 RTAI_PROTO(void,rt_busy_sleep,(int ns))
01053 {
01054     struct { long ns; } arg = { ns };
01055     rtai_lxrt(BIDX, SIZARG, BUSY_SLEEP, &arg);
01056 }
01057 
01058 RTAI_PROTO(void,rt_set_periodic_mode,(void))
01059 {
01060     struct { unsigned long dummy; } arg;
01061     rtai_lxrt(BIDX, SIZARG, SET_PERIODIC_MODE, &arg);
01062 }
01063 
01064 RTAI_PROTO(void,rt_set_oneshot_mode,(void))
01065 {
01066     struct { unsigned long dummy; } arg;
01067     rtai_lxrt(BIDX, SIZARG, SET_ONESHOT_MODE, &arg);
01068 }
01069 
01070 RTAI_PROTO(int, rt_task_signal_handler, (RT_TASK *task, void (*handler)(void)))
01071 {
01072     struct { RT_TASK *task; void (*handler)(void); } arg = { task, handler };
01073     return rtai_lxrt(BIDX, SIZARG, SIGNAL_HANDLER, &arg).i[LOW];
01074 }
01075 
01076 RTAI_PROTO(int,rt_task_use_fpu,(RT_TASK *task, int use_fpu_flag))
01077 {
01078         struct { RT_TASK *task; long use_fpu_flag; } arg = { task, use_fpu_flag };
01079         if (rtai_lxrt(BIDX, SIZARG, RT_BUDDY, &arg).v[LOW] != task) {
01080                 return rtai_lxrt(BIDX, SIZARG, TASK_USE_FPU, &arg).i[LOW];
01081         } else {
01082 // note that it would be enough to do whatever FP op here to have it OK. But
01083 // that is scary if it is done when already in hard real time, and we do not
01084 // want to force users to call this before making it hard.
01085                 rtai_lxrt(BIDX, SIZARG, HRT_USE_FPU, &arg);
01086                 return 0;
01087         }
01088 }
01089 
01090 RTAI_PROTO(int,rt_buddy_task_use_fpu,(RT_TASK *task, int use_fpu_flag))
01091 {
01092     struct { RT_TASK *task; long use_fpu_flag; } arg = { task, use_fpu_flag };
01093     return rtai_lxrt(BIDX, SIZARG, TASK_USE_FPU, &arg).i[LOW];
01094 }
01095 
01096 /*
01097 RTAI_PROTO(int,rt_linux_use_fpu,(int use_fpu_flag))
01098 {
01099     struct { long use_fpu_flag; } arg = { use_fpu_flag };
01100     return rtai_lxrt(BIDX, SIZARG, LINUX_USE_FPU, &arg).i[LOW];
01101 }
01102 */
01103 
01104 RTAI_PROTO(int, rt_task_get_info, (RT_TASK *task, RT_TASK_INFO *task_info))
01105 {
01106     RT_TASK_INFO ltask_info;
01107     struct { RT_TASK *task; RT_TASK_INFO *taskinfo; } arg = { task, &ltask_info };
01108     if (task_info && !rtai_lxrt(BIDX, SIZARG, GET_TASK_INFO, &arg).i[LOW]) {
01109         *task_info = ltask_info;
01110         return 0;
01111     }
01112     return -EINVAL;
01113 }
01114 
01115 RTAI_PROTO(int, rt_get_priorities, (RT_TASK *task, int *priority, int *base_priority))
01116 {
01117     RT_TASK_INFO task_info;
01118     if (priority && base_priority && !rt_task_get_info(task, &task_info)) {
01119         *priority      = task_info.priority;
01120         *base_priority = task_info.base_priority;
01121         return 0;
01122     }
01123     return -EINVAL;
01124 }
01125 
01126 RTAI_PROTO(int, rt_hard_timer_tick, (void))
01127 {
01128     struct { long dummy; } arg;
01129     return rtai_lxrt(BIDX, SIZARG, HARD_TIMER_COUNT, &arg).i[LOW];
01130 }
01131 
01132 RTAI_PROTO(RTIME,rt_get_time_ns,(void))
01133 {
01134     struct { unsigned long dummy; } arg;
01135     return rtai_lxrt(BIDX, SIZARG, GET_TIME_NS, &arg).rt;
01136 }
01137 
01138 RTAI_PROTO(RTIME,rt_get_cpu_time_ns,(void))
01139 {
01140     struct { unsigned long dummy; } arg;
01141     return rtai_lxrt(BIDX, SIZARG, GET_CPU_TIME_NS, &arg).rt;
01142 }
01143 
01144 #define rt_named_task_init(task_name, thread, data, stack_size, prio, uses_fpu, signal) \
01145     rt_task_init(nam2num(task_name), thread, data, stack_size, prio, uses_fpu, signal)
01146 
01147 #define rt_named_task_init_cpuid(task_name, thread, data, stack_size, prio, uses_fpu, signal, run_on_cpu) \
01148     rt_task_init_cpuid(nam2num(task_name), thread, data, stack_size, prio, uses_fpu, signal, run_on_cpu)
01149 
01150 RTAI_PROTO(void,rt_set_runnable_on_cpus,(RT_TASK *task, unsigned long cpu_mask))
01151 {
01152     struct { RT_TASK *task; unsigned long cpu_mask; } arg = { task, cpu_mask };
01153     rtai_lxrt(BIDX, SIZARG, SET_RUNNABLE_ON_CPUS, &arg);
01154 }
01155 
01156 RTAI_PROTO(void,rt_set_runnable_on_cpuid,(RT_TASK *task, unsigned int cpuid))
01157 {
01158     struct { RT_TASK *task; unsigned long cpuid; } arg = { task, cpuid };
01159     rtai_lxrt(BIDX, SIZARG, SET_RUNNABLE_ON_CPUID, &arg);
01160 }
01161 
01162 RTAI_PROTO(int,rt_get_timer_cpu,(void))
01163 {
01164     struct { unsigned long dummy; } arg;
01165     return rtai_lxrt(BIDX, SIZARG, GET_TIMER_CPU, &arg).i[LOW];
01166 }
01167 
01168 RTAI_PROTO(void,start_rt_apic_timers,(struct apic_timer_setup_data *setup_mode, unsigned int rcvr_jiffies_cpuid))
01169 {
01170     struct { struct apic_timer_setup_data *setup_mode; unsigned long rcvr_jiffies_cpuid; } arg = { setup_mode, rcvr_jiffies_cpuid };
01171     rtai_lxrt(BIDX, SIZARG, START_RT_APIC_TIMERS, &arg);
01172 }
01173 
01174 RTAI_PROTO(int, rt_hard_timer_tick_cpuid, (int cpuid))
01175 {
01176     struct { unsigned long cpuid; } arg = { cpuid };
01177     return rtai_lxrt(BIDX, SIZARG, HARD_TIMER_COUNT_CPUID, &arg).i[LOW];
01178 }
01179 
01180 RTAI_PROTO(RTIME,count2nano_cpuid,(RTIME count, unsigned int cpuid))
01181 {
01182     struct { RTIME count; unsigned long cpuid; } arg = { count, cpuid };
01183     return rtai_lxrt(BIDX, SIZARG, COUNT2NANO_CPUID, &arg).rt;
01184 }
01185 
01186 RTAI_PROTO(RTIME,nano2count_cpuid,(RTIME nanos, unsigned int cpuid))
01187 {
01188     struct { RTIME nanos; unsigned long cpuid; } arg = { nanos, cpuid };
01189     return rtai_lxrt(BIDX, SIZARG, NANO2COUNT_CPUID, &arg).rt;
01190 }
01191 
01192 RTAI_PROTO(RTIME,rt_get_time_cpuid,(unsigned int cpuid))
01193 {
01194     struct { unsigned long cpuid; } arg = { cpuid };
01195     return rtai_lxrt(BIDX, SIZARG, GET_TIME_CPUID, &arg).rt;
01196 }
01197 
01198 RTAI_PROTO(RTIME,rt_get_time_ns_cpuid,(unsigned int cpuid))
01199 {
01200     struct { unsigned long cpuid; } arg = { cpuid };
01201     return rtai_lxrt(BIDX, SIZARG, GET_TIME_NS_CPUID, &arg).rt;
01202 }
01203 
01204 RTAI_PROTO(void,rt_boom,(void))
01205 {
01206     struct { long dummy; } arg = { 0 };
01207     rtai_lxrt(BIDX, SIZARG, RT_BOOM, &arg);
01208 }
01209 
01210 RTAI_PROTO(void,rt_mmgr_stats,(void))
01211 {
01212     struct { long dummy; } arg = { 0 };
01213     rtai_lxrt(BIDX, SIZARG, RT_MMGR_STATS, &arg);
01214 }
01215 
01216 RTAI_PROTO(void,rt_stomp,(void) )
01217 {
01218     struct { long dummy; } arg = { 0 };
01219     rtai_lxrt(BIDX, SIZARG, RT_STOMP, &arg);
01220 }
01221 
01222 RTAI_PROTO(int,rt_get_linux_signal,(RT_TASK *task))
01223 {
01224     struct { RT_TASK *task; } arg = { task };
01225     return rtai_lxrt(BIDX, SIZARG, RT_GET_LINUX_SIGNAL, &arg).i[LOW];
01226 }
01227 
01228 RTAI_PROTO(int,rt_get_errno,(RT_TASK *task))
01229 {
01230     struct { RT_TASK *task; } arg = { task };
01231     return rtai_lxrt(BIDX, SIZARG, RT_GET_ERRNO, &arg).i[LOW];
01232 }
01233 
01234 RTAI_PROTO(int,rt_set_linux_signal_handler,(RT_TASK *task, void (*handler)(int sig)))
01235 {
01236     struct { RT_TASK *task; void (*handler)(int sig); } arg = { task, handler };
01237     return rtai_lxrt(BIDX, SIZARG, RT_SET_LINUX_SIGNAL_HANDLER, &arg).i[LOW];
01238 }
01239 
01240 #define VSNPRINTF_BUF_SIZE 256
01241 RTAI_PROTO(int,rtai_print_to_screen,(const char *format, ...))
01242 {
01243     char display[VSNPRINTF_BUF_SIZE];
01244     struct { const char *display; long nch; } arg = { display, 0 };
01245     va_list args;
01246 
01247     va_start(args, format);
01248     arg.nch = vsnprintf(display, VSNPRINTF_BUF_SIZE, format, args);
01249     va_end(args);
01250     rtai_lxrt(BIDX, SIZARG, PRINT_TO_SCREEN, &arg);
01251     return arg.nch;
01252 }
01253 
01254 RTAI_PROTO(int,rt_printk,(const char *format, ...))
01255 {
01256     char display[VSNPRINTF_BUF_SIZE];
01257     struct { const char *display; long nch; } arg = { display, 0 };
01258     va_list args;
01259 
01260     va_start(args, format);
01261     arg.nch = vsnprintf(display, VSNPRINTF_BUF_SIZE, format, args);
01262     va_end(args);
01263     rtai_lxrt(BIDX, SIZARG, PRINTK, &arg);
01264     return arg.nch;
01265 }
01266 
01267 RTAI_PROTO(int,rt_usp_signal_handler,(void (*handler)(void)))
01268 {
01269     struct { void (*handler)(void); } arg = { handler };
01270     return rtai_lxrt(BIDX, SIZARG, USP_SIGHDL, &arg).i[0];
01271 }
01272 
01273 RTAI_PROTO(unsigned long,rt_get_usp_flags,(RT_TASK *rt_task))
01274 {
01275     struct { RT_TASK *task; } arg = { rt_task };
01276     return rtai_lxrt(BIDX, SIZARG, GET_USP_FLAGS, &arg).i[LOW];
01277 }
01278 
01279 RTAI_PROTO(unsigned long,rt_get_usp_flags_mask,(RT_TASK *rt_task))
01280 {
01281     struct { RT_TASK *task; } arg = { rt_task };
01282     return rtai_lxrt(BIDX, SIZARG, GET_USP_FLG_MSK, &arg).i[LOW];
01283 }
01284 
01285 RTAI_PROTO(void,rt_set_usp_flags,(RT_TASK *rt_task, unsigned long flags))
01286 {
01287     struct { RT_TASK *task; unsigned long flags; } arg = { rt_task, flags };
01288     rtai_lxrt(BIDX, SIZARG, SET_USP_FLAGS, &arg);
01289 }
01290 
01291 RTAI_PROTO(void,rt_set_usp_flags_mask,(unsigned long flags_mask))
01292 {
01293     struct { unsigned long flags_mask; } arg = { flags_mask };
01294     rtai_lxrt(BIDX, SIZARG, SET_USP_FLG_MSK, &arg);
01295 }
01296 
01297 RTAI_PROTO(RT_TASK *,rt_force_task_soft,(int pid))
01298 {
01299     struct { long pid; } arg = { pid };
01300     return (RT_TASK *)rtai_lxrt(BIDX, SIZARG, FORCE_TASK_SOFT, &arg).v[LOW];
01301 }
01302 
01303 RTAI_PROTO(RT_TASK *,rt_agent,(void))
01304 {
01305     struct { unsigned long dummy; } arg;
01306     return (RT_TASK *)rtai_lxrt(BIDX, SIZARG, RT_BUDDY, &arg).v[LOW];
01307 }
01308 
01309 #define rt_buddy() rt_agent()
01310 
01311 RTAI_PROTO(int, rt_gettid, (void))
01312 {
01313     struct { unsigned long dummy; } arg;
01314     return rtai_lxrt(BIDX, SIZARG, RT_GETTID, &arg).i[LOW];
01315 }
01316 
01317 /**
01318  * Give a Linux process, or pthread, hard real time execution capabilities 
01319  * allowing full kernel preemption.
01320  *
01321  * rt_make_hard_real_time makes the soft Linux POSIX real time process, from
01322  * which it is called, a hard real time LXRT process.   It is important to
01323  * remark that this function must be used only with soft Linux POSIX processes
01324  * having their memory locked in memory.   See Linux man pages.
01325  *
01326  * Only the process itself can use this functions, it is not possible to impose
01327  * the related transition from another process.
01328  *
01329  * Note that processes made hard real time should avoid making any Linux System
01330  * call that can lead to a task switch as Linux cannot run anymore processes
01331  * that are made hard real time.   To interact with Linux you should couple the
01332  * process that was made hard real time with a Linux buddy server, either
01333  * standard or POSIX soft real time.   To communicate and synchronize with the
01334  * buddy you can use the wealth of available RTAI, and its schedulers, services.
01335  * 
01336  * After all it is pure nonsense to use a non hard real time Operating System,
01337  * i.e. Linux, from within hard real time processes.
01338  */
01339 RTAI_PROTO(void,rt_make_hard_real_time,(void))
01340 {
01341     struct { unsigned long dummy; } arg;
01342     rtai_lxrt(BIDX, SIZARG, MAKE_HARD_RT, &arg);
01343 }
01344 
01345 /**
01346  * Allows a non root user to use the Linux POSIX soft real time process 
01347  * management and memory lock functions, and allows it to do any input-output
01348  * operation from user space.
01349  *
01350  * Only the process itself can use this functions, it is not possible to impose
01351  * the related transition from another process.
01352  */
01353 RTAI_PROTO(void,rt_allow_nonroot_hrt,(void))
01354 {
01355     struct { unsigned long dummy; } arg;
01356     rtai_lxrt(BIDX, SIZARG, NONROOT_HRT, &arg);
01357 }
01358 
01359 RTAI_PROTO(int,rt_is_hard_real_time,(RT_TASK *rt_task))
01360 {
01361     struct { RT_TASK *task; } arg = { rt_task };
01362     return rtai_lxrt(BIDX, SIZARG, IS_HARD, &arg).i[LOW];
01363 }
01364 
01365 #define rt_is_soft_real_time(rt_task) (!rt_is_hard_real_time((rt_task)))
01366 
01367 RTAI_PROTO(void,rt_task_set_resume_end_times,(RTIME resume, RTIME end))
01368 {
01369     struct { RTIME resume, end; } arg = { resume, end };
01370     rtai_lxrt(BIDX, SIZARG, SET_RESUME_END, &arg);
01371 }
01372 
01373 RTAI_PROTO(int,rt_set_resume_time,(RT_TASK *rt_task, RTIME new_resume_time))
01374 {
01375     struct { RT_TASK *rt_task; RTIME new_resume_time; } arg = { rt_task, new_resume_time };
01376     return rtai_lxrt(BIDX, SIZARG, SET_RESUME_TIME, &arg).i[LOW];
01377 }
01378 
01379 RTAI_PROTO(int,rt_set_period,(RT_TASK *rt_task, RTIME new_period))
01380 {
01381     struct { RT_TASK *rt_task; RTIME new_period; } arg = { rt_task, new_period };
01382     return rtai_lxrt(BIDX, SIZARG, SET_PERIOD, &arg).i[LOW];
01383 }
01384 
01385 RTAI_PROTO(void,rt_spv_RMS,(int cpuid))
01386 {
01387     struct { long cpuid; } arg = { cpuid };
01388     rtai_lxrt(BIDX, SIZARG, SPV_RMS, &arg);
01389 }
01390 
01391 RTAI_PROTO(int, rt_task_masked_unblock,(RT_TASK *task, unsigned long mask))
01392 {
01393     struct { RT_TASK *task; unsigned long mask; } arg = { task, mask };
01394     return rtai_lxrt(BIDX, SIZARG, WAKEUP_SLEEPING, &arg).i[LOW];
01395 }
01396 
01397 #define rt_task_wakeup_sleeping(task)  rt_task_masked_unblock(task, RT_SCHED_DELAYED)
01398 
01399 RTAI_PROTO(void, rt_get_exectime, (RT_TASK *task, RTIME *exectime))
01400 {
01401     RTIME lexectime[] = { 0LL, 0LL, 0LL };
01402     struct { RT_TASK *task; RTIME *lexectime; } arg = { task, lexectime };
01403     rtai_lxrt(BIDX, SIZARG, GET_EXECTIME, &arg);
01404     memcpy(exectime, lexectime, sizeof(lexectime));
01405 }
01406 
01407 RTAI_PROTO(void, rt_gettimeorig, (RTIME time_orig[]))
01408 {
01409     struct { RTIME *time_orig; } arg = { time_orig };
01410     rtai_lxrt(BIDX, SIZARG, GET_TIMEORIG, &arg);
01411 }
01412 
01413 RTAI_PROTO(RT_TASK *,ftask_init,(unsigned long name, int priority))
01414 {
01415     struct { unsigned long name; long priority, stack_size, max_msg_size, cpus_allowed; } arg = { name, priority, 0, 0, 0 };
01416     return (RT_TASK *)rtai_lxrt(BIDX, SIZARG, LXRT_TASK_INIT, &arg).v[LOW];
01417 }
01418 
01419 RTAI_PROTO(RTIME, start_ftimer,(long period, long ftick_freq))
01420 {
01421     struct { long ftick_freq; void *handler; } arg = { ftick_freq, NULL };
01422     if (!period) {
01423         rtai_lxrt(BIDX, sizeof(long), SET_ONESHOT_MODE, &period);
01424     } else {
01425         rtai_lxrt(BIDX, sizeof(long), SET_PERIODIC_MODE, &period);
01426     }
01427     rtai_lxrt(BIDX, SIZARG, REQUEST_RTC, &arg);
01428     return rtai_lxrt(BIDX, sizeof(long), START_TIMER, &period).rt;
01429 }
01430 
01431 RTAI_PROTO(RTIME, stop_ftimer,(void))
01432 {
01433     struct { long dummy; } arg;
01434     rtai_lxrt(BIDX, SIZARG, RELEASE_RTC, &arg);
01435     return rtai_lxrt(BIDX, SIZARG, STOP_TIMER, &arg).rt;
01436 }
01437 
01438 #ifdef __cplusplus
01439 }
01440 #endif /* __cplusplus */
01441 
01442 #endif /* __KERNEL__ */
01443 
01444 /*@}*/
01445 
01446 #endif /* !_RTAI_LXRT_H */

Generated on Tue Feb 2 17:46:04 2010 for RTAI API by  doxygen 1.4.7