README
1 TASKLETS Tasklets Support Module 2 ================================ 3 4 The TASKLETS module you'll find here adds an interesting new feature along 5 the line, pioneered by RTAI, of a symmetric usage of all its services 6 inter-intra kernel and user space both for soft and hard real time. 7 In such a way you have an wide spectrum of development and implementation 8 options, allowing maximum flexibility with uncompromised performances. 9 And of course, all LGPL open source. 10 11 New services: tasklets and timers 12 --------------------------------- 13 14 The new services provided can be useful when you have many tasks, both in 15 kernel and user space, that must execute in hard real time but do not need 16 any RTAI scheduler services that could lead to a task block. This constraint 17 is critical and make sure you fully understand it. 18 19 Such tasks are called tasklets and can be of two kinds: 20 21 - A simple tasklets, 22 23 - Timed tasklets (timers). 24 25 It must be noted that only timers need to be made available both in user and 26 kernel space. In fact, simple tasklets in kernel space are nothing but 27 standard functions that can be directly executed by simply calling them, so 28 there is no need for any special treatment. However in order to maintain full 29 usage symmetry, and to continue to allow the possibility of porting 30 applications from one address space to the other, tasklets functions have 31 been implemented so they can be used in whatever address space. 32 33 Note that the Linux kernel offers similar services. They are not exactly the 34 same because of the RTAI symmetrical API implementation, but the basic idea 35 behind them is clearly fairly similar. 36 37 It should be clear that for such tasks the standard hard real time tasks 38 available with RTAI and LXRT schedulers can be a waist of resources and the 39 execution of simple, possibly timed, functions could often be more than 40 enough. 41 42 Examples of such applications are timed pollings and simple Programmable Logic 43 Controllers (PLC) like sequences of services. Obviously there are many others 44 instances that justify the use of tasklets, either simple or timed. In general 45 such an approach can be a very usefull complement in controlling complex 46 machines and systems, both for basic and support services. 47 48 The implementation 49 ------------------ 50 51 The TASKLETS implementation of timed tasklets relies on a server support 52 task that executes the related timer functions, either in oneshot or periodic 53 mode, on the base of their time deadline and according to their user assigned 54 priority. 55 56 As explained above, plain tasklets are just functions executed from kernel 57 space. Their execution needs no server and is simply triggered by calling 58 the user specified tasklet function at due time, either from a kernel task 59 or interrupt handler in charge of their execution when they are needed. 60 61 Once more it is important to recall that only non blocking RTAI scheduler 62 services can be used in any tasklet function. Services that can block must 63 absolutely be avoided, as they will deadlock the timers server task, executing 64 task or interrupt handler, whichever applies, so that no more tasklet functions 65 will be executed from them. 66 67 User and kernel space TASKLETS applications should cooperate and synchronize 68 by using shared memory. 69 70 It has been called TASKLETS because it is a kind of light hard real time 71 server that can substitute both RTAI and LXRT, if the constraints hinted above 72 are wholly satisfied. So TASKLETS can be used in kernel and user space, 73 with any RTAI scheduler. 74 75 Its implementation has been very easy to accomplish, as it is nothing but what 76 its name implies, so that LXRT made all the needed tools already available. 77 78 As already done for shared memory and LXRT the function calls for Linux 79 processes are inlined in the file "tasklets.h". This approach has been 80 preferred to a library since it is simpler, more effective, the calls are 81 short and simple so that, even if it is likely that only a few calls are used 82 for a typical process, they do not add significantly to the size of the 83 program. 84 85 86 TASKLETS Services 87 ------------------ 88 89 Services made available by the TASKLETS module (functions, macros and 90 variable names are self explanatory, see also example test.c): 91 92 struct rt_tasklet_struct *rt_tasklet_init(void) 93 94 void rt_tasklet_delete(strct rt_tasklet_struct *tasklet) 95 96 int rt_insert_tasklet( 97 struct rt_tasklet_struct *tasklet, 98 void (*handler)(unsigned long), 99 unsigned long data, 100 unsigned long id, 101 int pid 102 ) 103 104 void rt_remove_tasklet(struct rt_tasklet_struct *tasklet) 105 106 struct rt_tasklet_struct *rt_find_tasklet_by_id(unsigned long id) 107 108 void rt_exec_tasklet(struct rt_tasklet_struct *tasklet) 109 110 void rt_set_tasklet_priority(struct rt_tasklet_struct *tasklet, int priority) 111 112 int rt_set_tasklet_handler(struct rt_tasklet_struct *tasklet, void (*handler)(unsigned long)) 113 114 #define rt_fast_set_tasklet_handler(tasklet, handler) 115 116 void rt_set_tasklet_data(struct rt_tasklet_struct *tasklet, unsigned long data) 117 118 #define rt_fast_set_tasklet_data(tasklet, data) 119 120 void rt_tasklet_use_fpu(struct rt_tasklet_struct *tasklet, int use_fpu) 121 122 struct rt_tasklet_struct *rt_timer_init(void) 123 124 void rt_timer_delete(strct rt_tasklet_struct *timer) 125 126 int rt_insert_timer( 127 struct rt_tasklet_struct *timer, 128 int priority, 129 RTIME firing_time, 130 RTIME period, 131 void (*handler)(unsigned long), 132 unsigned long data, 133 int pid 134 ) 135 136 void rt_remove_timer(struct rt_tasklet_struct *timer) 137 138 void rt_set_timer_priority(struct rt_tasklet_struct *timer, int priority) 139 140 void rt_set_timer_firing_time(struct rt_tasklet_struct *timer, RTIME firing_time) 141 142 void rt_set_timer_period(struct rt_tasklet_struct *timer, RTIME period) 143 144 #define rt_fast_set_timer_period(timer, period) 145 146 int rt_set_timer_handler(struct rt_tasklet_struct *timer, void (*handler)(unsigned long)) 147 148 #define rt_fast_set_timer_handler(timer, handler) 149 150 void rt_set_timer_data(struct rt_tasklet_struct *timer, unsigned long data) 151 152 #define rt_fast_set_timer_data(timer, data) 153 154 void rt_timer_use_fpu(struct rt_tasklet_struct *timer, int use_fpu) 155 156 The rt_fast... timer related macros can be safely used in kernel space as 157 alternative to their standard equivalents when the related data and timer 158 structure address are available. 159 160 Remember to always include the header file rtai_timers.h, found in this 161 directory. It defines struct rt_tasklet_struct and all the tasklet functions 162 prototypes and macros. 163 164 The functions rt_tasklet_init, rt_timer_init, rt_tasklet_delete and 165 rt_timer_delete are meant to be used in user space only, where the timer 166 structure must be allocated dynamically in kernel space. They become empty 167 macros in kernel space, where you must allocate the tasklet structure yourself. 168 169 170 FPU Support and other technicalities 171 ------------------------------------ 172 173 The timers server task assumes that timer functions never use the Floating 174 Point Unit (FPU). If that is not the case, the function rt_tasklets_use_fpu 175 should be used to allow the use of the FPU if it is needed by any timer 176 function, both in kernel and user space. The same applies to simple tasklets 177 in user space. 178 179 In the kernel, the task, or interrupt handler, executing any tasklet directly 180 must enable the FPU by appropriately using the fsave and frestore, and 181 clearing clts (see rtai.h for the related macros). 182 183 The timers server runs on a 8096 bytes stack, which should be enough for running 184 most timers tasklet functions in kernel space. If you need a larger stack either 185 recompile tasklets.c after setting the macro STACK_SIZE in tasklets.h to what 186 you want, or simply load the timers server module using "ldmod ./rtai_timers 187 StackSize=<xxxx>", where <xxxx> is your new stack size. 188 189 In user space you run within the memory of the thread associated to the handler 190 function at tasklet/timer creation, so no problem should arise. Note however 191 that the thread must lock all of its memory so that it cannot be swapped out. 192 Generally a tasklet handler should not require more than the stack size Linux 193 assigns to a process/thread by default. If it is not so pregrow all your 194 needed memory, see mlockall usage in Linux manuals, by changing the function 195 support_tasklet found in tasklets.h. 196 197 There are also many very useful test cases that demonstrate the use of most 198 services, both in kernel and user space. See directory tests and related run 199 files. 200 201 RTAI TASKLETS in user space can now work also with LXRT. In facts, as hinted 202 above their implementation uses a support thread. This because it is thought 203 that a symmetric use of the TASKLETS APIs along with any user space application 204 is a must, and all other tried integrations of TASKLETS with LXRT have resulted 205 to be more cumbersome, huglier and heavier. 206 To help figuring out what said above note that on a 500 MHz PIII the switching 207 overhead in user space is around 1 us. 208 Moreover LXRT has been changed to ease its porting to other architecture, thus 209 tasklets in user space will be also available to taht architecture, at no added 210 cost, once the related LXRT port is completed. 211 It must also be noted that user space tasklest/timers can live in the space of 212 hard real time LXRT processes/threads. Since hard real time LXRT processes 213 cannot interact with Linux tasklets/timers, init/delete functions must be called 214 only when such processes are in soft real time state. It should not be a heavy 215 constraint unless dynamic init/delete calls are required. In such a case a soft 216 server thread should be used, a standard way of doing things within hard LXRT. 217 218 From: Paolo Mantegazza (mantegazza@aero.polimi.it). 219 Organization: DIAPM.