Arduino and interrupts for a NOOB - Page 1
Forum section: electronics / general

author: medical-nerd
author_rank: Regular Contributor
timestamp: July 16, 2018, 12:37:35 pm
content: HiyaI understand that when an interrupt handler is called - status registers and general purpose registers etc need to be saved then returned to their original value when the handler is finished. I recall how this was done in assembler in 8bit micros from the 80's when I was playing with Z80 and 6502 assembler (not done much since) - what is not clear is how it is done by the arduino.Is the ISR(....) a macro that does all this? or does the compiler do it? What level do I need to be concerned about this?I'm going through the book Arduino Internals and it is showing how the arduino does most things and how it can be optimised by not using the arduino commands, exposing lower levels. I find this makes using an arduino much more understandable and satisfying.I'm not quite at bare metal stage yet but getting thereCheers

author: rstofer
author_rank: Super Contributor
timestamp: July 16, 2018, 02:01:13 pm
content: Here's a good description of how it workshttps://busylog.net/arduino-timer-interrupt-isr-example/The compiler knows something about interrupts or, more specifically, the attributes of interrupt functions. It understands ISR_NAKED for example. This option causes the compiler to not save registers on entry to the interrupt handler and not restore them on the way out.Besides the article, all of the code is in interrupt.h:C:\Program Files (x86)\Arduino\hardware\tools\avr\avr\include\avr\interrupt.h

author: medical-nerd
author_rank: Regular Contributor
timestamp: July 16, 2018, 05:53:26 pm
content: Thank youI have looked at those and it is clearer. Interrupt handlers are contained within the avr-c library and do the housekeeping automatically unless as you say this is disabled and you do it yourself preferably in assembler if required.I am realising that a knowledge of the c library is essential for me to get the most satisfaction from programming arduino. So I'm reading that as well.Many thanks again.Cheers.

author: rstofer
author_rank: Super Contributor
timestamp: July 18, 2018, 12:27:05 am
content: I tend to go down one rathole at a time. When something comes up, say interrupts, I go study those. When timers are a thing, I go study those. It is simply not possible to study everything. Small steps...

author: Naguissa
author_rank: Regular Contributor
timestamp: July 18, 2018, 08:39:09 am
content: Quote from: medical-nerd on July 16, 2018, 05:53:26 pmYes, as explained, it's handled automatically except if you indicate the compiler to don't do it.Another addition: Even on Arduino ecosystem, each microcontroller can have different interrupt functionality interface.You can take a look for differences in this library I'm creating (currently supports SAMD, AVR and STM32):https://github.com/Naguissa/uTimerLib/tree/master/srcIt's for timer interrupts, but you can see different methods for attaching ISRs:AVR: ISR(<interrupt>) { }SAM: void <PORT>_Handler(void) { }, as PIOB_Handler(void) { } -- void ADC_Handler() { -- void TC3_Handler() { /* Timers */ }STM32: attachInterrupt(<PIN>, <FUNCTION>, <MODE>); --- attachInterrupt(PB8, interruptFunction, CHANGE);You can ask if you need any detail on any given architecture and/or interrupt type (ADC, Timer, internal interrupts, etc).

author: westfw
author_rank: Super Contributor
timestamp: July 18, 2018, 10:09:35 pm
content: Quotefor AVRs using avr-gcc, ISR(name) is a macro that tells the compiler to do the things necessary for the following function to work as an interrupt service routine. It's compiler and target dependent, and you have to use a correct "name" for it to be effective.Some of the AVR interrupts already have "handlers" in the Arduino core, so you won't be able to change them without editing some core source code as well. Other interrupts are NOT used by the core, and you can make your own handlers.In addition, the Arduino libraries have "attachInterrupt()" which will allow you to set up a normal C function as the target for certain types of AVR interrupts at runtime (normally, interrupt wrappers are at a fixed location in flash, not changeable at run-time. attachInterrupt() has a wrapper function at the fixed location for that interrupt that does the important context saving, and then calls the user-specified function (incurring quite a bit of overhead in the process, but that's life...)For the ARM chips, the ARM hardware saves exactly the same registers that the C ABI requires be saved, so the compiler doesn't need to do anything special. You just need to have a normal C function with the same name that the startup code puts in the vector table.Quote"attachInterrupt()" is normally a significantly different thing than defining an interrupt handler. For Arduino (incuding the above STM32 example, I think) it attaches a C function to the pin change interrupt for a particular pin, which usually involves manipulating the GPIO peripheral, and storing a pointer to the user function in a separate table. (usually there is one pin-change interrupt per port, so the actual ISR has to do some decoding to figure out which individual-pin handler to call.)