RISC OS Open
A fast and easily customised operating system for ARM devices
ROOL
Home | News | Software | Bugs | Bounties | Forum | Documents | Photos | Contact us
Account

Interrupts Introduction

Programmer's Reference Manuals
» Part 1 - Introduction
» Interrupts
» Introduction

Overview

When a hardware device sends a signal to the ARM processor indicating that it needs attention, this is called an interrupt. The actual process of sending an interrupt is known as an interrupt request.

When an interrupt is received, RISC OS temporarily halts the active task, and enters an interrupt routine. The routine deals with the interrupting device very quickly so it can continue with the previous task as quickly as possible. Often, interrupts are handled so quickly that users never realise their task was temporarily halted.

Interrupts are an efficient method of dealing with hardware devices because the devices inform the system that it needs attention, rather than the system regularly checking all the devices. Because external hardware such as expansion cards can generate new interrupts, it is possible to install new routines to deal with them.

Some examples of devices that are handled by interrupts are:

  • Keyboard
  • Printer
  • Mouse
  • Disc drives
  • Serial port
  • Built-in timers
  • Expansion cards

Each device that can generate interrupts has a device number. Similar to Software Vectors and Hardware Vectors, there are corresponding device vectors. Installed on each vector is a default device driver that receives only interrupts from that device.

Interrupt types

There are two different types of interrupt requests; IRQs (interrupt requests_) and FIQs (_fast interrupt requests). As the name suggests, FIQs are generated by devices that require their request be serviced more quickly than the normal IRQ request.

The ARM processor has a separate mode, its own hardware vector and range of device numbers for dealing with FIQs.

System Device Numbers

A range of different RISC OS computers are available which uses different interrupt generating hardware. The very early Archimedes range of computers used a variety of different peripheral control chips, whereas later Archimedes computers used the 82C710 or 82C711 chip. Because different controllers have been used, device numbers differ between models of RISC OS computers.

The complete list of current RISC OS System Device Numbers is available.

Device vectors

It is possible to claim the device vectors and call a routine of your choosing, instead of the default one. With the exception of the Expansion Card interrupts (8 & 13), all device vectors call the most recent routine that claimed the vector. Previous routines that claimed the vector remain on the vector chain, unless they are released. If the most recent routine is released, then the previous owner of the vector is re-installed as the routine that is called.

Claiming and releasing IRQ vectors

To claim and release vectors, two SWI calls are used. They are as follows:

  • Claim a vector by calling OS_ClaimDeviceVector (provides more details)
  • Release a vector by calling OS_ReleaseDeviceVector (provides more details)

When a routine claims a vector, RISC OS first checks the vector chain to see if there are any earlier instances of the same routine claiming this vector. If found, it removes them from the chain before claiming the vector.

When releasing a device vector, RISC OS checks the vector chain for any earlier claimants of the vector. If none are found, it will automatically disable interrupts from the corresponding device. No attempt to manually disable interrupts should be made.

Interrupt handling routines

As mentioned earlier, the routine dealing with the interrupting device must do so very quickly, so it can continue with the previous task as quickly as possible. Often, interrupts are handled so quickly that users never realise their task was temporarily halted.

If a routine cannot deal with a device quickly, it should re-enable interrupts (as they are disabled automatically when entering a routine). Any routine that re-enables interrupts must be able to cope with further interrupts if they occur, and hence the routine being entered for the second time. This is called reentrancy.

Error Handling

Routines that handle interrupts must only call the error-returning SWI calls. That is SWI calls that have their X bit set. i.e. either add the value &20000 to the SWI number, or add the letter ‘X’ in front of the SWI name.

If an error is returned to the routine, appropriate action must be taken within the routine. It may be useful to store an error indicator within the routine, so that the next call to an appropriate SWI (one in the module that provides the routine) will generate an error.

SWI re-entrancy

Some SWI are defined as being re-entrant, that is, they can safely be called even though they are currently in the process of being used already. Some SWIs are deemed to be not re-entrant when it cannot handle more than one simultaneous call.

As a result of this, non re-entrant SWIs should not be called from within an interrupt handling routine. An example of why this is the case is shown below:

  1. A non re-entrant SWI is called from within a task. It stores some values in its own private workspace
  2. An interrupt occurs. The interrupt routine calls the same non re-entrant SWI
  3. The previous values in the workspace is overwritten
  4. When the interrupt has been serviced and control is returned to the original task, the SWI workspace is corrupt and so the routine does not work as expected

Clearing interrupt conditions

Once the routine has serviced the interrupt, it must also clear the interrupt so that it does continue to generate the same interrupt. The interrupt is cleared by accessing the hardware that is generating the interrupt.

FIQ specifics

As mentioned earlier, there are two types of interrupts; IRQs and FIQs. Devices that issue FIQs require them to be handled more quickly, and unlike IRQs no SWI can be called within the handler routine.

The default owner of the FIQ vector is the Econet module (which is a proprietary network), and only one owner of the FIQ is supported, so any task that wishes to claim the FIQ vector must follow the process below:

  1. Claim the FIQ using OS_ServiceCall, with one of the following service calls:
    • To claim from the foreground: A service number of 12 (&0C) (Service_ClaimFIQ). This call will always be successful, but may involve a wait if any current background FIQ process must be completed first
    • To claim from the background: A service number of 71 (&47) (Service_ClaimFIQinBackground). This routine may fail, but does not signify that this was due to an error; it may be because the FIQs could not be claimed. The following should steps should then be taken:
      • You must leave your routine to allow the foreground routine to release the FIQs
      • Schedule another attempt at claiming the FIQ
  2. The fast interrupt mask register should be set to &00. This will prevent fast interrupts while changing to the FIQ code
  3. Poke your FIQ routine into addresses &1C to &100
  4. Enable FIQ generation from the device
  5. Set the bit corresponding to the device in the fast interrupt mask register
  6. Start your own FIQ operation
  7. Upon the FIQ operation completing, it must set the interrupt mask register to zero
  8. Disable FIQ generation from the device
  9. Release FIQs using OS_ServiceCall with the service number of 11 (&0B) (Service_ReleaseFIQ)

Disabling interrupts

When an interrupt routine is called, interrupts are by default disabled until the routine completes. However, there may be other times when it is desirable to manually disable interrupts (i.e. IRQs). Because interrupts are an important to the integrity of a system it is important to minimise the amount of time interrupts are disabled.

Perhaps the easiest method of enabling and disabling interrupts from user mode is to use the OS_IntOn and OS_IntOff SWIs.

Disabling devices or fast interrupts

Unlike the method of disabling IRQs, you must be in a privileged mode to disable FIQs or specific devices. To disable specific devices, all interrupts must first have been disabled, before clearing the relevant bits of the interrupt mask registers.

See also

  • OS_ClaimDeviceVector
  • OS_IntOff
  • OS_IntOn
  • OS_ReleaseDeviceVector
  • OS_ServiceCall
  • Service_ClaimFIQinBackground
  • Service_ClaimFIQ
  • Service_ReleaseFIQ
  • System Device Numbers
Created on January 23, 2010 22:11:12 by Alan Robertson (52)? (127.0.0.1)
Edit | Views: Print | Source | Linked from: Interrupts

Search the Wiki

Commercial use

For commercial enquiries, please contact the owners of RISC OS, Castle Technology Ltd.

ROOL Store

The official C/C++ Development kit and more here.

Donate! Why?

Help ROOL make things happen – please consider donating!

Navigation

  • Home Page
  • All Pages
  • Recently Revised
  • Authors
  • Feeds
Site design © RISC OS Open Limited 2011 except where indicated
The RISC OS Open Instiki theme is based on Insitki's default layout

Valid XHTML 1.0  |  Valid CSS

Instiki 0.19.1(MML+)
This site runs on Rails

Hosted by Arachsys