In such a way you have opened a whole spectrum of development and implementation lanes, allowing maximum flexibility with uncompromized performances.
The new services provided can be useful when you have many tasks, both in kernel and user space, that must execute in soft/hard real time but do not need any RTAI scheduler service that could lead to a task block. Such tasks are here called tasklets and can be of two kinds: normal tasklets and timed tasklets (timers).
It must be noted that only timers should need to be made available both in user and kernel space. In fact normal tasklets in kernel space are nothing but standard functions that can be directly executed by calling them, so there would be no need for any special treatment. However to maintain full usage symmetry, and to ease any possible porting from one address space to the other, also normal tasklet functions can be used in whatever address space.
Note that if, at this point, you are reminded to similar Linux kernel services you are not totally wrong. They are not exactly the same, because of their symmetric availability in kernel and user space, but the basic idea behind them is clearly fairly similar.
Tasklets should be used whenever the standard hard real time tasks available with RTAI and LXRT schedulers can be a waist of resources and the execution of simple, possibly timed, functions could often be more than enough. Instances of such applications are timed polling and simple Programmable Logic Controllers (PLC) like sequences of services. Obviously there are many others instances that can make it sufficient the use of tasklets, either normal or timers. In general such an approach can be a very useful complement to fully featured tasks in controlling complex machines and systems, both for basic and support services.
It is remarked that the implementation found here for timed tasklets rely on a server support task that executes the related timer functions, either in oneshot or periodic mode, on the base of their time deadline and according to their, user assigned, priority. Instead, as told above, plain tasklets are just functions executed from kernel space; their execution needs no server and is simply triggered by calling a given service function at due time, either from a kernel task or interrupt handler requiring, or in charge of, their execution when they are needed. Once more it is important to recall that all non blocking RTAI scheduler services can be used in any tasklet function. Blocking services must absolutely be avoided. They will deadlock the timers server task, executing task or interrupt handler, whichever applies, so that no more tasklet functions will be executed.
User and kernel space MINI_RTAI_LXRT applications can cooperate and synchronize by using shared memory. It has been called MINI_RTAI_LXRT because it is a kind of light soft/hard real time server that can partially substitute RTAI and LXRT in simple applications, i.e. if the constraints hinted above are wholly satisfied. So MINI_RTAI_LXRT can be used in kernel and user space, with any RTAI scheduler. Its implementations has been very easy, as it is nothing but what its name implies. LXRT made all the needed tools already available. In fact it duplicates a lot of LXRT so that its final production version will be fully integrated with it, ASAP. However, at the moment, it cannot work with LXRT yet.
Note that in user space you run within the memory of the process owning the tasklet function so you MUST lock all of your processes memory in core, by using mlockall, to prevent it being swapped out. Also abundantly pre grow your stack to the largest size needed during the execution of your application, see mlockall usage in Linux manuals.
The RTAI distribution contains many useful examples that demonstrate the use of most services, both in kernel and user space.
Files | |
file | rtai_nam2num.h |
Conversion between characters strings and unsigned long identifiers. | |
file | rtai_tasklets.h |
Interface of the mini LXRT RTAI tasklets module. | |
file | tasklets.c |
Implementation of the mini LXRT RTAI tasklets module. | |
Data Structures | |
struct | rt_tasklet_struct |
Defines | |
#define | TSKIDX 1 |
#define | INIT 0 |
#define | DELETE 1 |
#define | TASK_INSERT 2 |
#define | TASK_REMOVE 3 |
#define | USE_FPU 4 |
#define | TIMER_INSERT 5 |
#define | TIMER_REMOVE 6 |
#define | SET_TASKLETS_PRI 7 |
#define | SET_FIR_TIM 8 |
#define | SET_PER 9 |
#define | SET_HDL 10 |
#define | SET_DAT 11 |
#define | EXEC_TASKLET 12 |
#define | WAIT_IS_HARD 13 |
#define | SET_TSK_PRI 14 |
#define | REG_TASK 15 |
#define | TASKLET_STACK_SIZE 8196 |
#define | rt_init_timer rt_init_tasklet |
#define | rt_delete_timer rt_delete_tasklet |
#define | rt_set_timer_handler rt_set_tasklet_handler |
#define | rt_set_timer_data rt_set_tasklet_data |
#define | rt_timer_use_fpu rt_tasklet_use_fpu |
#define | sched_malloc(size) rt_malloc((size)) |
#define | sched_free(adr) rt_free((adr)) |
Functions | |
int | support_tasklet (void *tasklet) |
rt_tasklet_struct * | rt_init_tasklet (void) |
Init, in kernel space, a tasklet structure to be used in user space. | |
void | rt_delete_tasklet (struct rt_tasklet_struct *tasklet) |
Delete, in kernel space, a tasklet structure to be used in user space. | |
int | rt_insert_timer (struct rt_tasklet_struct *timer, int priority, RTIME firing_time, RTIME period, void(*handler)(unsigned long), unsigned long data, int pid) |
Insert a timer in the list of timers to be processed. | |
void | rt_remove_timer (struct rt_tasklet_struct *timer) |
Remove a timer in the list of timers to be processed. | |
void | rt_set_timer_priority (struct rt_tasklet_struct *timer, int priority) |
Change the priority of an existing timer. | |
void | rt_set_timer_firing_time (struct rt_tasklet_struct *timer, RTIME firing_time) |
Change the firing time of a timer. | |
void | rt_set_timer_period (struct rt_tasklet_struct *timer, RTIME period) |
Change the period of a timer. | |
int | rt_set_tasklet_handler (struct rt_tasklet_struct *tasklet, void(*handler)(unsigned long)) |
void | rt_set_tasklet_data (struct rt_tasklet_struct *tasklet, unsigned long data) |
RT_TASK * | rt_tasklet_use_fpu (struct rt_tasklet_struct *tasklet, int use_fpu) |
int | rt_insert_tasklet (struct rt_tasklet_struct *tasklet, int priority, void(*handler)(unsigned long), unsigned long data, unsigned long id, int pid) |
Insert a tasklet in the list of tasklets to be processed. | |
void | rt_set_tasklet_priority (struct rt_tasklet_struct *tasklet, int priority) |
void | rt_remove_tasklet (struct rt_tasklet_struct *tasklet) |
Remove a tasklet in the list of tasklets to be processed. | |
int | rt_exec_tasklet (struct rt_tasklet_struct *tasklet) |
Exec a tasklet. | |
MODULE_LICENSE ("GPL") | |
rt_fun_entry rt_tasklet_fun[] | __attribute__ ((__unused__)) |
void | enq_timer (struct rt_tasklet_struct *timed_timer) |
void | rem_timer (struct rt_tasklet_struct *timer) |
rt_tasklet_struct * | rt_find_tasklet_by_id (unsigned long id) |
Find a tasklet identified by its id. | |
void | asgn_min_prio (void) |
void | set_timer_firing_time (struct rt_tasklet_struct *timer, RTIME firing_time) |
void | rt_timers_manager (long dummy) |
void | rt_register_task (struct rt_tasklet_struct *tasklet, struct rt_tasklet_struct *usptasklet, RT_TASK *task) |
void | rt_wait_tasklet_is_hard (struct rt_tasklet_struct *tasklet, int thread) |
MODULE_PARM (tasklets_stacksize,"i") | |
int | __rtai_tasklets_init (void) |
void | __rtai_tasklets_exit (void) |
Variables | |
DEFINE_LINUX_CR0 struct rt_tasklet_struct | timers_list |
rt_tasklet_struct | tasklets_list |
spinlock_t | tasklets_lock = SPIN_LOCK_UNLOCKED |
spinlock_t | timers_lock = SPIN_LOCK_UNLOCKED |
rt_fun_entry | rt_tasklet_fun [] |
RT_TASK | timers_manager |
int | tasklets_stacksize = TASKLET_STACK_SIZE |
RT_TASK * | rt_base_linux_task |
|
Definition at line 39 of file rtai_tasklets.h. Referenced by rt_delete_tasklet(). |
|
Definition at line 50 of file rtai_tasklets.h. Referenced by rt_exec_tasklet(). |
|
Definition at line 38 of file rtai_tasklets.h. Referenced by rt_init_tasklet(). |
|
Definition at line 53 of file rtai_tasklets.h. Referenced by support_tasklet(). |
|
Definition at line 356 of file rtai_tasklets.h. |
|
Definition at line 345 of file rtai_tasklets.h. |
|
Definition at line 408 of file rtai_tasklets.h. |
|
Definition at line 400 of file rtai_tasklets.h. |
|
Definition at line 420 of file rtai_tasklets.h. |
|
Definition at line 117 of file tasklets.c. Referenced by frstk_srq_handler(), and rt_mbx_delete(). |
|
Definition at line 116 of file tasklets.c. Referenced by rt_typed_mbx_init(). |
|
Definition at line 49 of file rtai_tasklets.h. Referenced by rt_set_tasklet_data(). |
|
Definition at line 46 of file rtai_tasklets.h. Referenced by rt_set_timer_firing_time(). |
|
Definition at line 48 of file rtai_tasklets.h. Referenced by rt_set_tasklet_handler(), and support_tasklet(). |
|
Definition at line 47 of file rtai_tasklets.h. Referenced by rt_set_timer_period(). |
|
Definition at line 45 of file rtai_tasklets.h. Referenced by rt_set_timer_priority(). |
|
Definition at line 52 of file rtai_tasklets.h. Referenced by rt_set_tasklet_priority(). |
|
Definition at line 40 of file rtai_tasklets.h. Referenced by rt_insert_tasklet(). |
|
Definition at line 41 of file rtai_tasklets.h. Referenced by rt_remove_tasklet(). |
|
Definition at line 57 of file rtai_tasklets.h. Referenced by rt_init_tasklet(). |
|
Definition at line 43 of file rtai_tasklets.h. Referenced by rt_insert_timer(). |
|
Definition at line 44 of file rtai_tasklets.h. Referenced by rt_remove_timer(). |
|
|
Definition at line 42 of file rtai_tasklets.h. Referenced by rt_tasklet_use_fpu(). |
|
Definition at line 51 of file rtai_tasklets.h. Referenced by rt_init_tasklet(). |
|
|
|
Definition at line 768 of file tasklets.c. References printk(), rt_base_linux_task, rt_task_delete(), rt_tasklet_fun, timers_manager, and TSKIDX. Here is the call graph for this function: ![]() |
|
Definition at line 749 of file tasklets.c. References NR_RT_CPUS, printk(), rt_base_linux_task, rt_get_base_linux_task(), RT_SCHED_LOWEST_PRIORITY, RT_SCHED_MUP, rt_sched_type(), RT_TASK, rt_task_init(), rt_task_resume(), rt_tasklet_fun, rt_timers_manager(), tasklets_stacksize, timers_manager, TSKIDX, and tuned. Here is the call graph for this function: ![]() |
|
Definition at line 392 of file tasklets.c. References flags, rt_tasklet_struct::next, RT_SCHED_READY, rt_spin_lock_irqsave(), rt_spin_unlock_irqrestore, timers_list, timers_lock, and timers_manager. Referenced by rt_timers_manager(). Here is the call graph for this function: ![]() |
|
Definition at line 196 of file tasklets.c. References rt_tasklet_struct::firing_time, rt_tasklet_struct::next, rt_tasklet_struct::prev, and timers_list. Referenced by set_timer_firing_time(). |
|
|
|
|
|
Definition at line 205 of file tasklets.c. References rt_tasklet_struct::next, and rt_tasklet_struct::prev. Referenced by rt_timers_manager(), and set_timer_firing_time(). |
|
Delete, in kernel space, a tasklet structure to be used in user space. rt_tasklet_delete free a tasklet structure (struct rt_tasklet_struct) in kernel space that was allocated by rt_tasklet_init.
References DELETE, rtai_lxrt_t::i, LOW, rt_thread_join(), rtai_lxrt(), SIZARG, and TSKIDX. Here is the call graph for this function: ![]() |
|
Exec a tasklet. rt_exec_tasklet execute a tasklet from the list of tasklets to be processed.
User space tasklets instead must be first found within the tasklet list by calling rt_find_tasklet_by_id() to get the tasklet address to be used in rt_tasklet_exec(). Definition at line 445 of file rtai_tasklets.h. References EXEC_TASKLET, rtai_lxrt_t::i, LOW, rtai_lxrt(), SIZARG, and TSKIDX. Here is the call graph for this function: ![]() |
|
Find a tasklet identified by its id.
References rt_tasklet_struct::id, rt_tasklet_struct::next, and tasklets_list. |
|
Init, in kernel space, a tasklet structure to be used in user space. rt_tasklet_init allocate a tasklet structure (struct rt_tasklet_struct) in kernel space to be used for the management of a user space tasklet. This function is to be used only for user space tasklets. In kernel space it is just an empty macro, as the user can, and must allocate the related structure directly, either statically or dynamically.
References INIT, LOW, rt_thread_create(), rtai_lxrt(), SIZARG, support_tasklet(), TASKLET_STACK_SIZE, TSKIDX, rtai_lxrt_t::v, and WAIT_IS_HARD. Here is the call graph for this function: ![]() |
|
Insert a tasklet in the list of tasklets to be processed. rt_insert_tasklet insert a tasklet in the list of tasklets to be processed.
References handler, rtai_lxrt_t::i, LOW, pid, rtai_lxrt(), SIZARG, TASK_INSERT, and TSKIDX. Here is the call graph for this function: ![]() |
|
Insert a timer in the list of timers to be processed. rt_insert_timer insert a timer in the list of timers to be processed. Timers can be either periodic or oneshot. A periodic timer is reloaded at each expiration so that it executes with the assigned periodicity. A oneshot timer is fired just once and then removed from the timers list. Timers can be reinserted or modified within their handlers functions.
References handler, rtai_lxrt_t::i, LOW, pid, rtai_lxrt(), RTIME, SIZARG, TIMER_INSERT, and TSKIDX. Here is the call graph for this function: ![]() |
|
Definition at line 700 of file tasklets.c. References RT_TASK, task, rt_tasklet_struct::task, and rt_tasklet_struct::usptasklet. |
|
Remove a tasklet in the list of tasklets to be processed. rt_remove_tasklet remove a tasklet from the list of tasklets to be processed.
References rtai_lxrt(), SIZARG, TASK_REMOVE, and TSKIDX. Here is the call graph for this function: ![]() |
|
Remove a timer in the list of timers to be processed. rt_remove_timer remove a timer from the list of the timers to be processed.
References rtai_lxrt(), SIZARG, TIMER_REMOVE, and TSKIDX. Here is the call graph for this function: ![]() |
|
Definition at line 402 of file rtai_tasklets.h. References rtai_lxrt(), SET_DAT, SIZARG, and TSKIDX. Here is the call graph for this function: ![]() |
|
Definition at line 394 of file rtai_tasklets.h. References handler, rtai_lxrt_t::i, LOW, rtai_lxrt(), SET_HDL, SIZARG, and TSKIDX. Here is the call graph for this function: ![]() |
|
Definition at line 433 of file rtai_tasklets.h. References rtai_lxrt(), SET_TSK_PRI, SIZARG, and TSKIDX. Here is the call graph for this function: ![]() |
|
Change the firing time of a timer. rt_set_timer_firing_time changes the firing time of a periodic timer overloading any existing value, so that the timer next shoot will take place at the new firing time. Note that if a oneshot timer has its firing time changed after it has already expired this function has no effect. You should reinsert it in the timer list with the new firing time.
References rtai_lxrt(), RTIME, SET_FIR_TIM, SIZARG, and TSKIDX. Here is the call graph for this function: ![]() |
|
Change the period of a timer. rt_set_timer_period changes the period of a periodic timer. Note that the new period will be used to pace the timer only after the expiration of the firing time already in place. Using this function with a period different from zero for a oneshot timer, that has not expired yet, will transform it into a periodic timer.
This function an be used within the timer handler.
References rtai_lxrt(), RTIME, SET_PER, SIZARG, and TSKIDX. Here is the call graph for this function: ![]() |
|
Change the priority of an existing timer. rt_set_timer_priority change the priority of an existing timer.
References rtai_lxrt(), SET_TASKLETS_PRI, SIZARG, and TSKIDX. Here is the call graph for this function: ![]() |
|
Definition at line 410 of file rtai_tasklets.h. References LOW, RT_TASK, rt_task_use_fpu(), rtai_lxrt(), SIZARG, task, TSKIDX, USE_FPU, and rtai_lxrt_t::v. Here is the call graph for this function: ![]() |
|
Definition at line 625 of file tasklets.c. References asgn_min_prio(), flags, linux_cr0, rt_tasklet_struct::next, rem_timer(), restore_fpcr, restore_fpenv, RT_SCHED_LOWEST_PRIORITY, rt_sleep_until(), rt_spin_lock_irqsave(), rt_spin_unlock_irqrestore, rt_task_resume(), RTIME, save_fpcr_and_enable_fpu, save_fpenv, set_timer_firing_time(), timers_list, timers_lock, timers_manager, and tuned. Referenced by __rtai_tasklets_init(). Here is the call graph for this function: ![]() |
|
Definition at line 707 of file tasklets.c. References RT_SCHED_SUSPENDED, rt_tasklet_struct::task, and rt_tasklet_struct::thread. |
|
Definition at line 420 of file tasklets.c. References enq_timer(), rt_tasklet_struct::firing_time, flags, rt_tasklet_struct::next, rt_tasklet_struct::prev, rem_timer(), rt_spin_lock_irqsave(), rt_spin_unlock_irqrestore, RTIME, and timers_lock. Referenced by rt_timers_manager(). Here is the call graph for this function: ![]() |
|
Definition at line 296 of file rtai_tasklets.h. References rt_tasklet_struct::data, rt_tasklet_struct::handler, handler, REG_TASK, rt_make_hard_real_time(), rt_make_soft_real_time(), RT_TASK, rt_task_delete(), rt_task_suspend(), rt_thread_init(), rtai_lxrt(), rtai_sti, SET_HDL, SIZARG, task, and TSKIDX. Referenced by rt_init_tasklet(). Here is the call graph for this function: ![]() |
|
Definition at line 747 of file tasklets.c. Referenced by __rtai_tasklets_exit(), and __rtai_tasklets_init(). |
|
Initial value: Definition at line 140 of file tasklets.c. Referenced by __rtai_tasklets_exit(), and __rtai_tasklets_init(). |
|
Initial value: Definition at line 132 of file tasklets.c. Referenced by rt_find_tasklet_by_id(). |
|
Definition at line 135 of file tasklets.c. |
|
Definition at line 744 of file tasklets.c. Referenced by __rtai_tasklets_init(). |
|
Initial value: Definition at line 125 of file tasklets.c. Referenced by asgn_min_prio(), enq_timer(), and rt_timers_manager(). |
|
Definition at line 136 of file tasklets.c. Referenced by asgn_min_prio(), rt_timers_manager(), and set_timer_firing_time(). |
|
Definition at line 390 of file tasklets.c. Referenced by __rtai_tasklets_exit(), __rtai_tasklets_init(), asgn_min_prio(), and rt_timers_manager(). |