# mini RTAI LXRT tasklets module

## Detailed Description

The MINI_RTAI_LXRT tasklets module adds an interesting new feature along the line, pioneered by RTAI, of a symmetric usage of all its services inter-intra kernel and user space, both for soft and hard real time applications.

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.

## Functions

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_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_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.
rt_tasklet_struct * | rt_find_tasklet_by_id (unsigned long id)
| Find a tasklet identified by its id.

## Function Documentation

int rt_delete_tasklet | ( | struct rt_tasklet_struct * | tasklet | ) | `[inline]`

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.

Parameters:

  | tasklet | is the pointer to the tasklet structure (struct rt_tasklet_struct) returned by rt_tasklet_init.

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.

Note:
  To be used only with RTAI24.x.xx.

int rt_exec_tasklet | ( | struct rt_tasklet_struct * | tasklet | ) | `[inline]`

Exec a tasklet.

rt_exec_tasklet execute a tasklet from the list of tasklets to be processed.

Parameters:

  | tasklet | is the pointer to the tasklet structure to be used to manage the tasklet tasklet.

Kernel space tasklets addresses are usually available directly and can be easily be used in calling rt_tasklet_exec. In fact one can call the related handler directly without using such a support function, which is mainly supplied for symmetry and to ease the porting of applications from one space to the other.

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().

Note:
  To be used only with RTAI24.x.xx.

struct rt_tasklet_struct* rt_find_tasklet_by_id | ( | unsigned long | id | ) |

Find a tasklet identified by its id.

Parameters:

  | id | is the unique unsigned long to be used to identify the tasklet.

The support functions nam2num() and num2nam() can be used for setting up id from a six character string.

Returns:
  the pointer to a tasklet handler on success

Return values:

  | 0 | to indicate that id is not a valid identifier so that the related tasklet was not found.

Note:
  To be used only with RTAI24.x.xx.

struct rt_tasklet_struct * rt_init_tasklet | ( | void |  | ) | `[inline]`

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.

Returns:
  the pointer to the tasklet structure the user space application must use to access all its related services.

int rt_insert_tasklet | ( | struct rt_tasklet_struct * | tasklet,
|  | int | priority,
|  | void(*)(unsigned long) | handler,
|  | unsigned long | data,
|  | unsigned long | id,
|  | int | pid
| ) | `[inline]`

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.

Parameters:

  | tasklet | is the pointer to the tasklet structure to be used to manage the tasklet at hand.
  | handler | is the tasklet function to be executed.
  | data | is an unsigned long to be passed to the handler. Clearly by an appropriate type casting one can pass a pointer to whatever data structure and type is needed.
  | id | is a unique unsigned number to be used to identify the tasklet tasklet. It is typically required by the kernel space service, interrupt handler ot task, in charge of executing a user space tasklet. The support functions nam2num() and num2nam() can be used for setting up id from a six character string.
  | pid | is an integer that marks a tasklet either as being a kernel or user space one. Despite its name you need not to know the pid of the tasklet parent process in user space. Simple use 0 for kernel space and 1 for user space.

Return values:

  | 0 | on success

Returns:
  a negative number to indicate that an invalid handler address has been passed.

Note:
  To be used only with RTAI24.x.xx.

int rt_insert_timer | ( | struct rt_tasklet_struct * | timer,
|  | int | priority,
|  | RTIME | firing_time,
|  | RTIME | period,
|  | void(*)(unsigned long) | handler,
|  | unsigned long | data,
|  | int | pid
| ) | `[inline]`

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.

Parameters:

  | timer | is the pointer to the timer structure to be used to manage the timer at hand.
  | priority | is the priority to be used to execute timers handlers when more than one timer has to be fired at the same time.It can be assigned any value such that: 0 < priority < RT_LOWEST_PRIORITY.
  | firing_time | is the time of the first timer expiration.
  | period | is the period of a periodic timer. A periodic timer keeps calling its handler at firing_time + k*period k = 0, 1. To define a oneshot timer simply use a null period.
  | handler | is the timer function to be executed at each timer expiration.
  | data | is an unsigned long to be passed to the handler. Clearly by a appropriate type casting one can pass a pointer to whatever data structure and type is needed.
  | pid | is an integer that marks a timer either as being a kernel or user space one. Despite its name you need not to know the pid of the timer parent process in user space. Simple use 0 for kernel space and 1 for user space.

Return values:

  | 0 | on success
  | EINVAL | if handler is an invalid handler address

Note:
  To be used only with RTAI24.x.xx.

void rt_remove_tasklet | ( | struct rt_tasklet_struct * | tasklet | ) | `[inline]`

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.

Parameters:

  | tasklet | is the pointer to the tasklet structure to be used to manage the tasklet at hand.

Note:
  To be used only with RTAI24.x.xx.

void rt_remove_timer | ( | struct rt_tasklet_struct * | timer | ) | `[inline]`

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.

Parameters:

  | timer | is the pointer to the timer structure to be used to manage the timer at hand.

Note:
  To be used only with RTAI24.x.xx.

void rt_set_timer_firing_time | ( | struct rt_tasklet_struct * | timer,
|  | RTIME | firing_time
| ) | `[inline]`

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.

Parameters:

  | timer | is the pointer to the timer structure to be used to manage the timer at hand.
  | firing_time | is the new time of the first timer expiration.

This function can be used within the timer handler.

Return values:

  | 0 | on success.

Note:
  To be used only with RTAI24.x.xx.

void rt_set_timer_period | ( | struct rt_tasklet_struct * | timer,
|  | RTIME | period
| ) | `[inline]`

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.

Parameters:

  | timer | is the pointer to the timer structure to be used to manage the timer at hand.
  | period | is the new period of a periodic timer.

The macro #rt_fast_set_timer_period can substitute the corresponding function in kernel space if both the existing timer period and the new one fit into an 32 bits integer.

This function an be used within the timer handler.

Return values:

  | 0 | on success.

Note:
  To be used only with RTAI24.x.xx.

void rt_set_timer_priority | ( | struct rt_tasklet_struct * | timer,
|  | int | priority
| ) | `[inline]`

Change the priority of an existing timer.

rt_set_timer_priority change the priority of an existing timer.

Parameters:

  | timer | is the pointer to the timer structure to be used to manage the timer at hand.
  | priority | is the priority to be used to execute timers handlers when more than one timer has to be fired at the same time. It can be assigned any value such that: 0 < priority < RT_LOWEST_PRIORITY.

This function can be used within the timer handler.

Note:
  To be used only with RTAI24.x.xx.