Software interrupts

Hi,

I noticed that the Arduino libraries come with external interrupt (hardware) capabilities, mainly related with pinout input change.

In some microcontrollers there is access to software interrupts, does the Arduino possesses any capabilities in this area?

Cheers

LS

None that I'm aware of

Just out of curiosity... what would a software interrupt be good for?

The AVR does have several internal timers that can be used to generate interrupts. While not exactly classified as 'software', these are internal devices that you can set up and use without any external hardware.

Just out of curiosity... what would a software interrupt be good for?

Used all the time in grown-up OSs to go from user to system/supervisor mode.
Just about any user access to an OS service (I/O, memory, timing) will go through an SWI (also known as SVC - supervisor call)

However, if the processor doesn't have such a distinction (like an AVR), not much use at all!
Early 8 bit microprocessors like Z80 and 6800/6809 had such instructions, even if they didn't strictly need them (no memory or I/O controllers to protect and no specific supervisor context), so I suspect they were included because they'd always been present on larger machines.

LuisSoares:
I noticed that the Arduino libraries come with external interrupt (hardware) capabilities, mainly related with pinout input change.
In some microcontrollers there is access to software interrupts, does the Arduino possesses any capabilities in this area?

There is no specific "SWI" instruction (and, therefore no dedicated interrupt vector for a sofwtare interrupt).

However...

From the Data Sheet section on external interrupts:

"The External Interrupts are triggered by the INT0 and INT1 pins or any of the PCINT23...0 pins.
Observe that, if enabled, the interrupts will trigger even if the INT0 and INT1 or PCINT23...0 pins
are configured as outputs."

In other words, a program can trigger any one of these interrupts by writing to an interrupt-enabled pin. A "poor man's" Software Interrupt can be implemented by manipulating an otherwise-unused output pin.

Regards,

Dave

You can fudge SWIs by writing to the pins normally used for hardware interrupts, ie INT0-1 and PCI.


Rob

@bubulindo: SWI are useful for accessing fixed services from relocatable applications, without requiring linking against a particular kernel.
The SWI is called with a fixed function code, for say, character input.
The SWI ISR picks up the function code and calls the appropriate function within the kernel.
In this way, different versions of the kernel (or monitor on simpler systems) can offer an identical interface, despite the physical location of the function providing the service changing from build to build.

davekw7x:
There is no specific "SWI" instruction (and, therefore no dedicated interrupt vector for a sofwtare interrupt).

However...

From the Data Sheet section on external interrupts:

"The External Interrupts are triggered by the INT0 and INT1 pins or any of the PCINT23...0 pins.
Observe that, if enabled, the interrupts will trigger even if the INT0 and INT1 or PCINT23...0 pins
are configured as outputs."

In other words, a program can trigger any one of these interrupts by writing to an interrupt-enabled pin. A "poor man's" Software Interrupt can be implemented by manipulating an otherwise-unused output pin.

Regards,

Dave

Any chance you would be willing to expand on your "poor man's" software interrupt? It might help wrap up this thread, and I could use an example.

It might help wrap up this thread

...four years after the last post. :o

@AWOL I hope this helps, I interpreted what davekw7x said to mean something like this.

//Written 8/10/2015 by Reperio

const byte LED = 13; //LED On Arduino Uno
const byte PIN = 2; //On the Uno this can be either pin 2 or 3

// Declare Interrupt Service Routine (ISR)
void pinChange ()
{
if (digitalRead (PIN) == HIGH)
digitalWrite (LED, HIGH);
else
digitalWrite (LED, LOW);
} // end of ISR

void setup ()
{
pinMode (LED, OUTPUT); // so we can update the LED
attachInterrupt (0, pinChange, CHANGE); // attach interrupt handler to look for changes on the pin
}

void loop ()
{
delay(1500);
digitalWrite(PIN, LOW);
delay(1500);
digitalWrite(PIN, HIGH);
}

//End of program

So during the loop I am alternating the output on the PIN. This causes a CHANGE to occur initiating the ISR. In the ISR if the PIN is low then the LED cuts off and vise versa. To test this you will need to put a high value resistor from the PIN to ground. I had a 1Mohm laying around so I used that.

The problem with that (apart from the three and a half month lapse of time) is that SWI instructions are normally immediately followed by function codes to determine the operation to be carried out by the interrupt.
The interrupt service routine fetches this value very simply because it occupies the point where the ISR will return.

Having an external interrupt doesn't allow this behaviour.

I don't see what that code achieves that wouldn't be achieved by directly turning the LED on and off. I suppose it is just an example, but still.

The ATmega328P instruction set does have a Branch If Interrupt Enabled (BRIE) instruction. This is the command you would use to initiate a software interrupt. Unfortunately, I do not see an equivalent command in the Arduino command reference. However, if you're feeling bold enough, you can attempt to write some inline assembly code using the asm directive.

Here's the datasheet. The BRIE instruction is on page 282. You'll also need to call the SEI instruction to set the global interrupt flag to ENABLE.
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf.

BRIE is just a branch instruction; it is not a vectored interrupt of any kind.