Author Topic: Arduino and interrupts for a NOOB  (Read 1765 times)

0 Members and 1 Guest are viewing this topic.

Offline medical-nerdTopic starter

  • Regular Contributor
  • *
  • Posts: 198
  • Country: gb
  • What's that coming over the hill?
Arduino and interrupts for a NOOB
« on: July 16, 2018, 12:37:35 pm »
Hiya

I 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 there  ;)

Cheers
'better to burn out than fade away'
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9886
  • Country: us
Re: Arduino and interrupts for a NOOB
« Reply #1 on: July 16, 2018, 02:01:13 pm »
Here's a good description of how it works

https://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
 
The following users thanked this post: medical-nerd

Offline medical-nerdTopic starter

  • Regular Contributor
  • *
  • Posts: 198
  • Country: gb
  • What's that coming over the hill?
Re: Arduino and interrupts for a NOOB
« Reply #2 on: July 16, 2018, 05:53:26 pm »
Thank you

I 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.
'better to burn out than fade away'
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9886
  • Country: us
Re: Arduino and interrupts for a NOOB
« Reply #3 on: July 18, 2018, 12:27:05 am »
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...
 
The following users thanked this post: medical-nerd

Offline Naguissa

  • Regular Contributor
  • *
  • Posts: 114
  • Country: es
    • Foro de electricidad, electrónica y DIY / HUM en español
Re: Arduino and interrupts for a NOOB
« Reply #4 on: July 18, 2018, 08:39:09 am »
Thank you

I 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.

Yes, 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/src

It'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).
 
The following users thanked this post: medical-nerd

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4196
  • Country: us
Re: Arduino and interrupts for a NOOB
« Reply #5 on: July 18, 2018, 10:09:35 pm »
Quote
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?
for 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
STM32:    attachInterrupt(<PIN>, <FUNCTION>, <MODE>); ---    attachInterrupt(PB8, interruptFunction, CHANGE);
"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.)
 
The following users thanked this post: medical-nerd


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf