# RTAI services functions.

## Detailed Description

This module defines some functions that can be used by RTAI tasks, for managing interrupts and communication services with Linux processes.

## Files

file | hal.c
| ARTI -- RTAI-compatible Adeos-based Real-Time Interface.

file | hal.c
| ARTI -- RTAI-compatible Adeos-based Real-Time Interface.

file | rtai_hal.h
| ARTI -- RTAI-compatible Adeos-based Real-Time Interface.

file | rtai_hal.h
| ARTI -- RTAI-compatible Adeos-based Real-Time Interface.

## Functions

unsigned | rt_startup_irq (unsigned irq)
| start and initialize the PIC to accept interrupt request irq.
void | rt_shutdown_irq (unsigned irq)
| Shut down an IRQ source.
void | rt_enable_irq (unsigned irq)
| Enable an IRQ source.
void | rt_disable_irq (unsigned irq)
| Disable an IRQ source.
void | rt_mask_and_ack_irq (unsigned irq)
| Mask and acknowledge and IRQ source.
void | rt_unmask_irq (unsigned irq)
| Unmask and IRQ source.
void | rt_ack_irq (unsigned irq)
| Acknowledge an IRQ source.
int | rt_request_linux_irq (unsigned irq, irqreturn_t(*handler)(int irq, void *dev_id, struct pt_regs *regs), char *name, void *dev_id)
| Install shared Linux interrupt handler.
int | rt_free_linux_irq (unsigned irq, void *dev_id)
| Uninstall shared Linux interrupt handler.
void | rt_pend_linux_irq (unsigned irq)
| Pend an IRQ to Linux.
int | rt_request_srq (unsigned label, void(*k_handler)(void), long long(*u_handler)(unsigned))
| Install a system request handler.
int | rt_free_srq (unsigned srq)
| Uninstall a system request handler.
void | rt_pend_linux_srq (unsigned srq)
| Append a Linux IRQ.
int | rt_request_timer (void(*handler)(void), unsigned tick, int use_apic)
| Install a timer interrupt handler.
void | rt_free_timer (void)
| Uninstall a timer interrupt handler.
int | rt_request_linux_irq (unsigned irq, void(*handler)(int irq, void *dev_id, struct pt_regs *regs), char *name, void *dev_id)
| Install shared Linux interrupt handler.

## Variables

int unsigned long | used_apic
| Install a timer interrupt handler.

## Function Documentation

void rt_ack_irq | ( | unsigned | irq | ) |

Acknowledge an IRQ source.

The related request can then interrupt the CPU again, provided it has not been masked.

The above function allow you to manipulate the PIC at hand, but you must know what you are doing. Such a duty does not pertain to this manual and you should refer to your PIC datasheet.

Note that Linux has the same functions, but they must be used only for its interrupts. Only the above ones can be safely used in real time handlers.

It must also be remarked that when you install a real time interrupt handler, RTAI already calls either rt_mask_and_ack_irq(), for level triggered interrupts, or rt_ack_irq(), for edge triggered interrupts, before passing control to you interrupt handler. hus generally you should just call rt_unmask_irq() at due time, for level triggered interrupts, while nothing should be done for edge triggered ones. Recall that in the latter case you allow also any new interrupts on the same request as soon as you enable interrupts at the CPU level.

Often some of the above functions do equivalent things. Once more there is no way of doing it right except by knowing the hardware you are manipulating. Furthermore you must also remember that when you install a hard real time handler the related interrupt is usually disabled, unless you are overtaking one already owned by Linux which has been enabled by it. Recall that if have done it right, and interrupts do not show up, it is likely you have just to rt_enable_irq() your irq.

void rt_disable_irq | ( | unsigned | irq | ) |

Disable an IRQ source.

The above function allow you to manipulate the PIC at hand, but you must know what you are doing. Such a duty does not pertain to this manual and you should refer to your PIC datasheet.

Note that Linux has the same functions, but they must be used only for its interrupts. Only the above ones can be safely used in real time handlers.

It must also be remarked that when you install a real time interrupt handler, RTAI already calls either rt_mask_and_ack_irq(), for level triggered interrupts, or rt_ack_irq(), for edge triggered interrupts, before passing control to you interrupt handler. hus generally you should just call rt_unmask_irq() at due time, for level triggered interrupts, while nothing should be done for edge triggered ones. Recall that in the latter case you allow also any new interrupts on the same request as soon as you enable interrupts at the CPU level.

Often some of the above functions do equivalent things. Once more there is no way of doing it right except by knowing the hardware you are manipulating. Furthermore you must also remember that when you install a hard real time handler the related interrupt is usually disabled, unless you are overtaking one already owned by Linux which has been enabled by it. Recall that if have done it right, and interrupts do not show up, it is likely you have just to rt_enable_irq() your irq.

void rt_enable_irq | ( | unsigned | irq | ) |

Enable an IRQ source.

The above function allow you to manipulate the PIC at hand, but you must know what you are doing. Such a duty does not pertain to this manual and you should refer to your PIC datasheet.

Note that Linux has the same functions, but they must be used only for its interrupts. Only the above ones can be safely used in real time handlers.

It must also be remarked that when you install a real time interrupt handler, RTAI already calls either rt_mask_and_ack_irq(), for level triggered interrupts, or rt_ack_irq(), for edge triggered interrupts, before passing control to you interrupt handler. hus generally you should just call rt_unmask_irq() at due time, for level triggered interrupts, while nothing should be done for edge triggered ones. Recall that in the latter case you allow also any new interrupts on the same request as soon as you enable interrupts at the CPU level.

Often some of the above functions do equivalent things. Once more there is no way of doing it right except by knowing the hardware you are manipulating. Furthermore you must also remember that when you install a hard real time handler the related interrupt is usually disabled, unless you are overtaking one already owned by Linux which has been enabled by it. Recall that if have done it right, and interrupts do not show up, it is likely you have just to rt_enable_irq() your irq.

int rt_free_linux_irq | ( | unsigned | irq,
|  | void * | dev_id
| ) |

Uninstall shared Linux interrupt handler.

Parameters:

  | dev_id | is to pass to the interrupt handler, in the same way as the standard Linux irq request call.
  | irq | is the IRQ level of the interrupt handler to be freed.

Return values:

  | 0 | on success.
  | EINVAL | if irq is not a valid IRQ number.

int rt_free_srq | ( | unsigned | srq | ) |

Uninstall a system request handler.

rt_free_srq uninstalls the specified system call srq, returned by installing the related handler with a previous call to rt_request_srq().

Return values:

  | EINVAL | if srq is invalid.

void rt_free_timer | ( | void |  | ) |

| Uninstall a timer interrupt handler. rt_free_timer uninstalls a timer previously set by rt_request_timer().

void rt_mask_and_ack_irq | ( | unsigned | irq | ) |

Mask and acknowledge and IRQ source.

No * other interrupts can be accepted, once also the CPU will enable interrupts, which ones depends on the PIC at hand and on how it is programmed.

The above function allow you to manipulate the PIC at hand, but you must know what you are doing. Such a duty does not pertain to this manual and you should refer to your PIC datasheet.

Note that Linux has the same functions, but they must be used only for its interrupts. Only the above ones can be safely used in real time handlers.

It must also be remarked that when you install a real time interrupt handler, RTAI already calls either rt_mask_and_ack_irq(), for level triggered interrupts, or rt_ack_irq(), for edge triggered interrupts, before passing control to you interrupt handler. hus generally you should just call rt_unmask_irq() at due time, for level triggered interrupts, while nothing should be done for edge triggered ones. Recall that in the latter case you allow also any new interrupts on the same request as soon as you enable interrupts at the CPU level.

Often some of the above functions do equivalent things. Once more there is no way of doing it right except by knowing the hardware you are manipulating. Furthermore you must also remember that when you install a hard real time handler the related interrupt is usually disabled, unless you are overtaking one already owned by Linux which has been enabled by it. Recall that if have done it right, and interrupts do not show up, it is likely you have just to rt_enable_irq() your irq.

void rt_pend_linux_irq | ( | unsigned | irq | ) |

Pend an IRQ to Linux.

rt_pend_linux_irq appends a Linux interrupt irq for processing in Linux IRQ mode, i.e. with hardware interrupts fully enabled.

Note:
  rt_pend_linux_irq does not perform any check on irq.

void rt_pend_linux_srq | ( | unsigned | srq | ) |

Append a Linux IRQ.

rt_pend_linux_srq appends a system call request srq to be used as a service request to the Linux kernel.

Parameters:

  | srq | is the value returned by rt_request_srq.

Note:
  rt_pend_linux_srq does not perform any check on irq.

int rt_request_linux_irq | ( | unsigned | irq,
|  | void(*)(int irq, void *dev_id, struct pt_regs *regs) | handler,
|  | char * | name,
|  | void * | dev_id
| ) |

Install shared Linux interrupt handler.

rt_request_linux_irq installs function handler as a standard Linux interrupt service routine for IRQ level irq forcing Linux to share the IRQ with other interrupt handlers, even if it does not want. The handler is appended to any already existing Linux handler for the same irq and is run by Linux irq as any of its handler. In this way a real time application can monitor Linux interrupts handling at its will. The handler appears in /proc/interrupts.

Parameters:

  | handler | pointer on the interrupt service routine to be installed.
  | name | is a name for /proc/interrupts.
  | dev_id | is to pass to the interrupt handler, in the same way as the standard Linux irq request call.

The interrupt service routine can be uninstalled with rt_free_linux_irq().

Return values:

  | 0 | on success.
  | EINVAL | if irq is not a valid IRQ number or handler is `NULL`.
  | EBUSY | if there is already a handler of interrupt irq.

int rt_request_linux_irq | ( | unsigned | irq,
|  | irqreturn_t(*)(int irq, void *dev_id, struct pt_regs *regs) | handler,
|  | char * | name,
|  | void * | dev_id
| ) |

Install shared Linux interrupt handler.

rt_request_linux_irq installs function handler as a standard Linux interrupt service routine for IRQ level irq forcing Linux to share the IRQ with other interrupt handlers, even if it does not want. The handler is appended to any already existing Linux handler for the same irq and is run by Linux irq as any of its handler. In this way a real time application can monitor Linux interrupts handling at its will. The handler appears in /proc/interrupts.

Parameters:

  | handler | pointer on the interrupt service routine to be installed.
  | name | is a name for /proc/interrupts.
  | dev_id | is to pass to the interrupt handler, in the same way as the standard Linux irq request call.

The interrupt service routine can be uninstalled with rt_free_linux_irq().

Return values:

  | 0 | on success.
  | EINVAL | if irq is not a valid IRQ number or handler is `NULL`.
  | EBUSY | if there is already a handler of interrupt irq.

int rt_request_srq | ( | unsigned | label,
|  | void(*)(void) | k_handler,
|  | long long(*)(unsigned) | u_handler
| ) |

Install a system request handler.

rt_request_srq installs a two way RTAI system request (srq) by assigning u_handler, a function to be used when a user calls srq from user space, and k_handler, the function to be called in kernel space following its activation by a call to rt_pend_linux_srq(). k_handler is in practice used to request a service from the kernel. In fact Linux system requests cannot be used safely from RTAI so you can setup a handler that receives real time requests and safely executes them when Linux is running.

Parameters:

  | u_handler | can be used to effectively enter kernel space without the overhead and clumsiness of standard Unix/Linux protocols. This is very flexible service that allows you to personalize your use of RTAI.

Returns:
  the number of the assigned system request on success.

Return values:

  | EINVAL | if k_handler is `NULL`.
  | EBUSY | if no free srq slot is available.

int rt_request_timer | ( | void(*)(void) | handler,
|  | unsigned | tick,
|  | int | use_apic
| ) |

| Install a timer interrupt handler. rt_request_timer requests a timer of period tick ticks, and installs the routine handler as a real time interrupt service routine for the timer. Set tick to 0 for oneshot mode (in oneshot mode it is not used). If apic has a nonzero value the local APIC timer is used. Otherwise timing is based on the 8254.

void rt_shutdown_irq | ( | unsigned | irq | ) |

Shut down an IRQ source.

No further interrupt request irq can be accepted.

The above function allow you to manipulate the PIC at hand, but you must know what you are doing. Such a duty does not pertain to this manual and you should refer to your PIC datasheet.

Note that Linux has the same functions, but they must be used only for its interrupts. Only the above ones can be safely used in real time handlers.

It must also be remarked that when you install a real time interrupt handler, RTAI already calls either rt_mask_and_ack_irq(), for level triggered interrupts, or rt_ack_irq(), for edge triggered interrupts, before passing control to you interrupt handler. hus generally you should just call rt_unmask_irq() at due time, for level triggered interrupts, while nothing should be done for edge triggered ones. Recall that in the latter case you allow also any new interrupts on the same request as soon as you enable interrupts at the CPU level.

Often some of the above functions do equivalent things. Once more there is no way of doing it right except by knowing the hardware you are manipulating. Furthermore you must also remember that when you install a hard real time handler the related interrupt is usually disabled, unless you are overtaking one already owned by Linux which has been enabled by it. Recall that if have done it right, and interrupts do not show up, it is likely you have just to rt_enable_irq() your irq.

unsigned rt_startup_irq | ( | unsigned | irq | ) |

start and initialize the PIC to accept interrupt request irq.

The above function allow you to manipulate the PIC at hand, but you must know what you are doing. Such a duty does not pertain to this manual and you should refer to your PIC datasheet.

Note that Linux has the same functions, but they must be used only for its interrupts. Only the above ones can be safely used in real time handlers.

It must also be remarked that when you install a real time interrupt handler, RTAI already calls either rt_mask_and_ack_irq(), for level triggered interrupts, or rt_ack_irq(), for edge triggered interrupts, before passing control to you interrupt handler. hus generally you should just call rt_unmask_irq() at due time, for level triggered interrupts, while nothing should be done for edge triggered ones. Recall that in the latter case you allow also any new interrupts on the same request as soon as you enable interrupts at the CPU level.

Often some of the above functions do equivalent things. Once more there is no way of doing it right except by knowing the hardware you are manipulating. Furthermore you must also remember that when you install a hard real time handler the related interrupt is usually disabled, unless you are overtaking one already owned by Linux which has been enabled by it. Recall that if have done it right, and interrupts do not show up, it is likely you have just to rt_enable_irq() your irq.

void rt_unmask_irq | ( | unsigned | irq | ) |

Unmask and IRQ source.

The related request can then interrupt the CPU again, provided it has also been acknowledged.

The above function allow you to manipulate the PIC at hand, but you must know what you are doing. Such a duty does not pertain to this manual and you should refer to your PIC datasheet.

Note that Linux has the same functions, but they must be used only for its interrupts. Only the above ones can be safely used in real time handlers.

It must also be remarked that when you install a real time interrupt handler, RTAI already calls either rt_mask_and_ack_irq(), for level triggered interrupts, or rt_ack_irq(), for edge triggered interrupts, before passing control to you interrupt handler. hus generally you should just call rt_unmask_irq() at due time, for level triggered interrupts, while nothing should be done for edge triggered ones. Recall that in the latter case you allow also any new interrupts on the same request as soon as you enable interrupts at the CPU level.

Often some of the above functions do equivalent things. Once more there is no way of doing it right except by knowing the hardware you are manipulating. Furthermore you must also remember that when you install a hard real time handler the related interrupt is usually disabled, unless you are overtaking one already owned by Linux which has been enabled by it. Recall that if have done it right, and interrupts do not show up, it is likely you have just to rt_enable_irq() your irq.

## Variable Documentation

int unsigned long used_apic`[static]`

| Install a timer interrupt handler. rt_request_timer requests a timer of period tick ticks, and installs the routine handler as a real time interrupt service routine for the timer. Set tick to 0 for oneshot mode (in oneshot mode it is not used). If apic has a nonzero value the local APIC timer is used. Otherwise timing is based on the 8254.