Academic Company Events NI Developer Zone Support Solutions Products & Services Contact NI MyNI

Document Type: Tutorial
NI Supported: Yes
Publish Date: Jun 12, 2008


Feedback


Yes No

Related Categories

Technology

Related Links - Developer Zone

Related Links - Products and Services

Interrupt Driven Programming for ARM Microcontrollers using LabVIEW

3 ratings | 5.00 out of 5
Read in | Print | PDF

Overview

This tutorial will introduce interrupt driven programming and demonstrate the steps required to manage interrupts using the NI LabVIEW Embedded Module for ARM Microcontrollers. Also covered are design decisions to be addressed when using interrupts within applications. This tutorial assumes that you have already installed LabVIEW 8.5, the LabVIEW Embedded Module for ARM Microcontrollers and have familiarity with building and running applications for ARM microcontrollers.

Introduction to interrupts and interrupt handlers

There are two components of any interrupt driven system – the interrupt and the interrupt handler.  An interrupt is a signal that is generated by hardware which indicates an event has occurred that should halt the currently executing program.   Interrupt handlers (also referred to as interrupt service routines) are portions of code that are registered with the processor to execute once a particular interrupt has occurred.  Once the processor is made aware of an interrupt, it will halt the currently executing process, perform a context switch where the state of the system is saved, and then execute the interrupt handler.  Once the interrupt handler code has completed execution, the processor will then return control to the program that was previously running.

Using interrupts can be useful for periodically reading and writing to data locations.  For example, let’s assume that we’re designing a digital music player.  Our system would comprise of three elements – inputs (various analog dials that adjust audio levels and filters), a processor, and an output (a digital to analog converter - DAC).  Our system would operate as follows: the processor would read the values of the dials, stream an audio file from memory, apply the filtering algorithm on the data and then writes a value to the DAC.  Using a timer interrupt, we can periodically read the values of the dials to determine the parameters of our filtering algorithm.  A second timer interrupt can then be set to periodically write to the DAC.  Our processor would then be free to continuously apply filtering algorithms to our sound file, only being interrupted to read and write registers.

 

Managing interrupts

Interrupts for an ARM application are handled through the Build Specifications of the project.  Through the Build Specifications Properties dialog box, developers have two methods to create and assign interrupt handlers – using a VI or using a timed loop.  Both methods can be used within a single project and allow multiple hardware interrupts to be handled within the application.

In the following sections, how to create interrupt handlers using both a VI and a timed loop will be illustrated.   In the given example, we will be using Figure 1: Project View for ARM Interrupts, to show an ARM project containing a top-level VI and a build specification.

Figure 1: Project View for ARM Interrupts

This project contains a single VI that will create our main application and target the MCB2300 ARM hardware.  The application will print a string to the Processor Status window.  Figure 2: ARM Main Application VI shows the block diagram for our VI.  It consists on a timed loop that will print a string to the Processor Status window.

 

Figure 2: ARM Main Application VI

 

Using a VI as an interrupt handler

The following steps demonstrate how to create a new VI that will be an interrupt handler.

1.       In the project explorer right-click on the ARM target and select New » VI.  This will add a new VI to the project.  This VI will be used as our interrupt handler.  Save your this file by selecting File » Save As.   In this example the file will be renamed ISR1.vi.

 

2.       Now the code for handling interrupts can be written.  Open the newly created VI’s block diagram and place the Console Output.vi from the ARM Palette.  Create a string constant that will be displayed to the Processor Status window.  This VI will print to the console indicating that code has been executed.  Notice that there is no loop structure surrounding the code.  This will demonstrate the periodic nature of timer interrupts.

 

 

 

3.       Now that the interrupt handler code has been completed, the handler now needs to be assigned to an interrupt. In the project explorer, under Build Specifications right-click the Application and choose Properties.

4.       This will bring up the Build Specification Properties window.

 

5.       Under Category select Manage Interrupts.  The hardware used in this example provides three timer interrupts.  Timer 1 will be used for this demonstration.  Select Timer 1 from the interrupt list and click the checkbox Use interrupt.

 

 

6.       In the Interrupt Handler box, select the VI radio button.  Use the arrow to select ISR1.vi to be the interrupt handler.  Any VI within the project can be used as the interrupt handler with the exception of the Top-Level VI.

 

 

7.       For this example, the start-up state will be Enabled.  Optionally, the interrupt can be Disabled at startup and programmatically enabled in the application.  This topic will be discussed later in the tutorial.  Additionally, the Timer 1 interrupt frequency can be configured using the Configure button and Timer Configuration dialog.

 

 

8.       Click the OK button.  The interrupt handler setup is now complete.  Build and Run the project.  The Processor Status window should appear similar to the image below.  The interrupt handler is called periodically, interrupting the execution of the main loop and outputting the string to the Processor Status window.

 

 

Using a timed loop as an interrupt handler

Alternatively, a timed loop can be used as the interrupt handler. This section will outline the steps necessary to create a timed loop to act as an interrupt handler.  Again, Figure 1 and Figure 2 will be used as the basis of this application.

1.       Starting with the Main ARM Application.vi a timed loop will be added, and subsequently used as our interrupt handler.  From Programming » Structures» Timed Loop palette select Timed Loop.   Create a second timed loop in the VI that will output to the Processor Status window.

 

2.       The timed loop needs to be configured to respond to an external timing source.  Right-click the input node and select Configure Input Node.  Select Use Timing Source Terminal.   

3.       Now, from the Programming » Timed Loop palette, use the Create External Timing Source.vi.   Name the timing source and connect it to input node of the timed loop. This will be the name of the timed loop structure to be used as our interrupt handler.

 

4.       As seen previously in creating the Using a VI as an interrupt handler section, open the Build Specification Properties window.  In the project explorer, under Build Specifications right-click the Application and choose Properties.  Under categories select Manage Interrupts.  In this example Timer 2 will be used.  Select Timer 2 from the interrupt list and click the checkbox Use interrupt.

 

5.       In the Interrupt Handler box select the Timed Loop radio button.

 

6.       Enter the name of the Timed Loop that was specified earlier – “Interrupt Handler” for this example.  Additionally, the Startup State and frequency of the interrupt can be configured.

 

 

 

7.       Click the OK button. Our timed loop is now configured to handle interrupts. Build and Run the application.  Once again the interrupt handler is called periodically.  The timed looped will execute once per interrupt.  Once the loop has completed a single iteration, control is given back to the processor.

 

 

 

There is one important difference in using a timed loop when compared to a VI as your interrupt handler – a timed loop interrupt handler may be interrupted by VI interrupt handler.  This could occur if you have 2 or more interrupts handlers in the system. If the timed loop interrupt handler is executing and interrupt occurs that is handled by a VI interrupt handler, the timed loop will be interrupted.

Using the timed loop method can be advantageous in applications using only a single interrupt.  This can allow code to be simplified by having the timed loop within the same VI as main application logic instead of developing multiple VIs.

Using the Interrupt VI Palette

 In addition to the ability to assign interrupt handlers, LabVIEW provides a mechanism to programmatically enable and disable interrupts through the following VIs located on the ARM » Interrupts Palette.

 

ARM Interrupt Enable is used to enable a previously disabled interrupt.  The interrupt may be disabled programmatically or the interrupt may be disabled from startup through the Manage Interrupts window.  This VI acts on a single interrupt as specified by the interrupt number.   

ARM Interrupt Disable allows programmers to disable a single interrupt as specified by the interrupt number.

ARM Global Interrupt Enable will cause all interrupts that have been disabled either programmatically or through the interrupt manager window to be enabled.

ARM Global Interrupt Disable will disable all interrupts within the system.  This is useful when performing operations that are time critical and absolutely must not be interrupted for any external event.

Design Considerations when using Interrupts in ARM Applications

Each interrupt in the system has a priority that cannot be assigned programmatically.  For the MCB2300 hardware, Timer 1 is the highest priority interrupt, Timer 2 is the second highest priority, and Timer 3 has the lowest priority of available interrupts.  If 2 or more interrupts fire at exactly the same time, the highest priority interrupt is executed.  While handling an interrupt, an interrupt handler cannot be interrupted except in the aforementioned case of using timed loops for interrupts.  Interrupts that occur while another interrupt handler is executing will be queued, however only the last interrupt from each external trigger will be serviced.  For example, while an interrupt handler for Timer 1 is executing five interrupts for Timer 2 occur, only the fifth interrupt for Timer 2 will be handled after Timer 1’s interrupt handler has completed.

It is important to take into account the potential for losing interrupts while designing your applications.  There are two common architectures that programmers implement in order to minimize this potential for lost interrupts.  Method one is to limit the time spent within an interrupt handler.  Limit their use to only reading or writing to a variable, while the main application performs all the processor intensive computation.  Alternatively, the software can be architected to use a single interrupt and perform the processor intensive computations within the interrupt handler.   The main application then simply waits for interrupts to be generated.  This architecture can be used when the desired functionality is meant to periodically operate on data each interrupt.  In this architecture, the programmer needs to ensure that the interrupt handler executes is less time that the period of the interrupt to ensure that no interrupts are lost.

 

3 ratings | 5.00 out of 5
Read in | Print | PDF

Reader Comments | Submit a comment »

 

Legal
This tutorial (this "tutorial") was developed by National Instruments ("NI"). Although technical support of this tutorial may be made available by National Instruments, the content in this tutorial may not be completely tested and verified, and NI does not guarantee its quality in any way or that NI will continue to support this content with each new revision of related products and drivers. THIS TUTORIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND AND SUBJECT TO CERTAIN RESTRICTIONS AS MORE SPECIFICALLY SET FORTH IN NI.COM'S TERMS OF USE (http://ni.com/legal/termsofuse/unitedstates/us/).