NetBurner 3.5.0
PDF Version
 
Interrupt Handling

Overview

An interrupt is a hardware or software request to interrupt the currently executing code and jump to a routine/code to process the event. After the interrupt processing is complete, the execution of non-interrupt code will resume. The code that processes an interrupt is commonly called an Interrupt Service Routine (ISR) or Interrupt Handler. Although it varies by platform, NetBurner devices commonly handle interrupts from sources such as timers, serial port, Ethernet ports, external hardware inputs, and software traps.

As mentioned, interrupt handling varies by processor hardware. In some cases, such as ColdFire, NetBurner provides macros to make the more involved ISR entry and exit much easier. ARM platforms tend to be much simpler, requiring only the Interrupt Service Routine function.






Recommended Interrupt Functions

The three recommended interrupt functions that work on all NetBuner platforms are listed below. There are also lower level functions for situations that require fine tuning. The PinIO object was created to make the configuration of a processor pin easier than having to configure all the required processor registers.

Configure a pin to handle an external interrupt by specifying the pin number as a PinIO object, the polarity (high/low), and the Interrupt Service Routine that will be called to process the interrupt:
bool SetPinIrq( PinIO pin, int polarity, PinIrq_t func);

Enable the interrupt:
void EnableIrq( PinIO pin );

Disable the interrupt:
void DisableIrq( PinIO pin );






Functions That Cannot Be Called in an ISR

Warning
The code within an ISR can be called at any time, therefore certain RTOS and I/O functions cannot be called from within the ISR.

All nbrtos init and pend functions (all OsxxPendNoWait functions are okay):

  • OSxxPend
  • OSCritEnter
  • OSChangePrio
  • OSTaskDelete
  • OSLock
  • OSUnlock
  • OSTaskCreate
  • OSTimeDly

I/O functions:

  • write
  • writeall
  • read
  • printf
  • fprintf
  • fdprintf
  • iprintf
  • scanf
  • gets
  • puts

Memory management functions:

  • malloc
  • free
  • new
  • delete






MODM7AE70 and SBE70LC Platforms (SAME70)

Any GPIO pin on the SAME70 processor can be used as an interrupt source. Pin IRQs are inputs on General Purpose I/O (GPIO) ports. The Cortex M7 architecture is structured in a way that all pins on the same port share the same GPIO priority. In other words, there is one IRQ per port.

Configure the interrupt request (IRQ) priority for a PIO pin

Configure a port priority by specifying a PinIO object.

Synopsis

bool SetPortIrqPriority( PinIO pin, int priority);
GPIO Pin Class.
Definition coldfire/cpu/MCF5441X/include/cpu_pins.h:14

Description

The PIO controller on the SAME70 configures the IRQ priority by PIO ports. Therefore, configuring the priority of an IRQ for a specific pin will change the IRQ priority for the entire PIO port. SetPinIrq() will set the pin IRQ with the priority that is configured with SetPortIrqPriority(). Therefore, SetPortIrqPriority() should be called before SetPinIrq().

Name Description
pin A PinIO object that is to be configured as an IRQ Pin.
priority Priority of the interrupt. A priority value of 1 being the highest priority IRQ, and 7 being the lowest.

Returns true if successfully if the PIO port's IRQ priority was successfully configured, otherwise false.



Configure the interrupt request (IRQ) priority for a PIO port

Configure a port priority by specifying a port number.

Synopsis

bool SetPortIrqPriority( int portNum, int priority);

Description

The PIO controller on the SAME70 configures the IRQ priority by PIO ports. Therefore, configuring the priority of an IRQ for a specific pin will change the IRQ priority for the entire PIO port. SetPinIrq() will set the pin IRQ with the priority that is configured with SetPortIrqPriority(). Therefore, SetPortIrqPriority() should be called before SetPinIrq().

Name Description
portNum PIO port number. Where PIOA = 0, and PIOE = 4.
priority Priority of the interrupt. A priority value of 1 being the highest priority IRQ, and 7 being the lowest.

Returns true if successfully if the PIO port's IRQ priority was successfully configured, otherwise false.



Set up an interrupt request (IRQ) pin

Synopsis

bool SetPinIrq( PinIO pin, int polarity, PinIrq_t func);

Description

Set up a PinIO object pin with polarity and pointer to an ISR function.

Name Description
pin A PinIO object that is to be configured as an IRQ Pin.
polarity Polarity and edge vs. level sensitivity configuration. 2: high level sensitive
1: positive edge sensitive
0: (either) edge sensitive
-1: negative edge sensitive
-2: low level sensitive
func A function pointer of type PinIrq_t to register as the service handler (ISR) for the given PinIO.

Returns true if PinIO was successfully registered for IRQs, otherwise false.



Enable the interrupt for the given PinIO

Synopsis

void EnableIrq( PinIO pin );

Description

Enable the interrupt for the given PinIO

Name Description
pin The PinIO object to enable interrupts for.



Disable the interrupt for the given PinIO

Synopsis

void DisableIrq( PinIO pin );

Description

Disable the interrupt for the given PinIO

Name Description
pin The PinIO object to disable interrupts for.






MOD54415, MOD54417, NANO54415 and SB800EX Platforms (MCF5441x)

The MCF5441x processor requires more setup and configuration than ARM platforms. To simplify implementation, the NetBurner platform implements the following functions:

  • An INTERRUPT() Macro to provide the Interrupt Service Routine entry and exit.
  • The SetIntC() function to configure the Interrupt Controller hardware.

Each are described in the following sections.

INTERRUPT() Macro

MCF5441x platforms use the INTERRUPT() macro as described below, which handles the ISR entry and exit coding. The header file to include is cfinter.h, located in: "\nburn\arch\coldfire\include\cfinter.h". ColdFire interrupts have values from 1 to 7, with 7 being the highest priority.

Note
Once you use the INTERRUPT macro to define the interrupt function, you will need to use the SetIntc(), set interrupt controller function, to set up your interrupt controller variables to point the processor's interrupt vector at that function. Please refer to the appropriate NXP hardware reference manual, located in "\nburn\docs\nxp" for your specific interrupt source number and controller number (some ColdFire's have more than one interrupt controller).

Header Files

#include <nbrtos.h>
#include <cfinter.h>
ColdFire Interrupt Macro.
NetBurner Real-Time Operating System (NBRTOS) API.

Synopsis

INTERRUPT( FunctionName, sr_value )

Description

The INTERRUPT macro sets up an interrupt function and the code block to save and restore the CPU registers. In addition, this macro tells the RTOS that an interrupt is occurring.

Note
Level 7 interrupts are unmaskable, which means they will interrupt any other processing, including the level 7 ISR itself. Therefore, any level 7 ISR used in an application must ensure it can complete its processing before another level 7 interrupt occurs.

Parameters

Name Description
FunctionName The name of the Interrupt Service Routine, to be used with the SetIntC() function. This is the name of a C/C++ function in an application created to process the interrupt.
SR_Value The ColdFire Status Register (SR) value that the processor will have during the interrupt. This is used as a mask to specify which, if any higher priority interrupts can interrupt the ISR. The mask bits define the current interrupt level. Interrupt requests are inhibited for all priority levels less than or equal to current level, except edge-sensitive level 7 requests, which cannot be masked.For example, if a level 5 interrupt is currently executing, specifying a value of 0x2500 will allow a IRQ level 6 or higher to interrupt.

Status Register Values

The status register is 32-bits. The mask bits are 24-26 and range from 000 to 111. The eight permitted SR register values are shown below. Bit 29 is the supervisor bit, which should always be set.

  • 0x2000 - Allows all interrupts
  • 0x2100 - Blocks all interrupts below level 2
  • 0x2200 - Blocks all interrupts below level 3
  • 0x2300 - Blocks all interrupts below level 4
  • 0x2400 - Blocks all interrupts below level 5
  • 0x2500 - Blocks all interrupts below level 6
  • 0x2600 - Blocks all interrupts below level 7
  • 0x2700 - Blocks all interrupts below level 7


SetIncC() function (Set Interrupt Controller)

MOD54415, MOD54417, NANO54415 and SB800EX SetIncC() functions are located in Hardware Abstraction Layer (HAL) cpp file for the particular platform. For example, for the MOD5441x it is located in "\nburn\platform\MOD5441x\hal.cpp". The SetIntC() function must be declared as an extern in your application .cpp file, it is not available in a header file. For example:

void SetIntc(int intcnum, long func, int vector, int level)

Parameters:

Name Description
intcnum Interrupt Controller Number. For MCF5441x processors there are two: 0 and 1.
func Pointer to ISR function name.
vector Interrupt Vector Number. There are 256 exception vectors; the first 64 are defined for the core and the remaining 192 are device-specific peripheral interrupt vectors. See Chapter 17, “Interrupt Controller Modules (INTC)” for details on the device-specific interrupt sources, and table 17.2.9.1 Interrupt Sources. For example, the UART 0 vector number is 26, and the PIT2 timer is 15.
level Interrupt level. Range is from 0 (disabled) to 7, with 7 being the highest level/priority. For example, a level 6 interrupt request can interrupt a level 1 Interrupt Service Routine.

Example, OneWire Interrupt Configuration

extern void SetIntc(int intc, long func, int vector, int level);
// Interrupt Service Routine
void OWMasterIsr()
{
// ISR code...
}
// INTERRUPT macro to set vector ISR function and mask to level 6
INTERRUPT( ow_master_int_routine, 0x2600 )
{
OWMasterIsr();
}
// Initialization call to use in UserMain() of application. The purpose of this example is only
// to demonstrate the use of SetIntC().
void OWInit()
{
// Initialize 1-Wire module registers (MCF5441x Reference Manual Chapter 36.3: 1-Wire Memory Map/Register Definitions)
sim1.ow.cr = 0;
sim1.ow.div = 0x7C; // Divides the peripheral bus clock to run at 1 MHz
sim1.ow.cmd = 0;
sim1.ow.ier = OW_IER_ERBF;
// 63 is the interrupt source number for the 1-Wire module, and we're using IRQ level 3
SetIntc(0, ( long ) &ow_master_int_routine, 63, 3 /* IRQ 3 */);
ow_struct.state = OK;
}




SOMRT1061 Platform