Improving the Interrupt Service Routine

interruption
From the AVR Libc User Manual:

Another solution is to still implement the ISR in C language but take over the compiler’s job of generating the prologue and epilogue. This can be done using the ISR_NAKED attribute to the ISR() macro. Note that the compiler does not generate anything as prologue or epilogue, so the final reti() must be provided by the actual implementation. SREG must be manually saved if the ISR code modifies it, and the compiler-implied assumption of __zero_reg__ always being 0 could be wrong (e. g. when interrupting right after of a MUL instruction).

ISR is created with no prologue or epilogue code. The user code is responsible for preservation of the machine state including the SREG register, as well as placing a reti() at the end of the interrupt routine.

Here is a comparison of two interrupt routines using the ISR_NAKED attribute.

Compiler generated prologue/epilogue code:

ISR(TIMER0_COMPA_vect) {
  //incremented every 1ms
  my_timer0_millis++;
}

Disassembly:

@0000008E: __vector_14
+0000008E:   921F        PUSH      R1
+0000008F:   920F        PUSH      R0
+00000090:   B60F        IN        R0, 0x3F
+00000091:   920F        PUSH      R0
+00000092:   2411        CLR       R1
+00000093:   938F        PUSH      R24
+00000094:   939F        PUSH      R25
+00000095:   93AF        PUSH      R26
+00000096:   93BF        PUSH      R27
+00000097:   9180050F    LDS       R24, 0x050F
+00000099:   91900510    LDS       R25, 0x0510
+0000009B:   91A00511    LDS       R26, 0x0511
+0000009D:   91B00512    LDS       R27, 0x0512
+0000009F:   9601        ADIW      R24, 0x01
+000000A0:   1DA1        ADC       R26, R1
+000000A1:   1DB1        ADC       R27, R1
+000000A2:   9380050F    STS       0x050F, R24
+000000A4:   93900510    STS       0x0510, R25
+000000A6:   93A00511    STS       0x0511, R26
+000000A8:   93B00512    STS       0x0512, R27
+000000AA:   91BF        POP       R27
+000000AB:   91AF        POP       R26
+000000AC:   919F        POP       R25
+000000AD:   918F        POP       R24
+000000AE:   900F        POP       R0
+000000AF:   BE0F        OUT       0x3F, R0
+000000B0:   900F        POP       R0
+000000B1:   901F        POP       R1
+000000B2:   9518        RETI

Self-generated prologue/epilogue code using the ISR_NAKED attribute:

ISR(TIMER0_COMPA_vect, ISR_NAKED) {
  asm(
    "push r1\n"
    "in r1,0x3f\n"
    "push r1\n"
    "push r24\n"
    "push r25\n"
    "push r26\n"
    "push r27\n"
    "clr r1\n"
  );
  //incremented every 1ms
  my_timer0_millis++;
  asm(
    "pop r27\n"
    "pop r26\n"
    "pop r25\n"
    "pop r24\n"
    "pop r1\n"
    "out 0x3f,r1\n"
    "pop r1\n"
    "reti\n"
  );
}

Disassembly:

@0000008E: __vector_14
+0000008E:   921F        PUSH      R1
+0000008F:   B61F        IN        R1, 0x3F
+00000090:   921F        PUSH      R1
+00000091:   938F        PUSH      R24
+00000092:   939F        PUSH      R25
+00000093:   93AF        PUSH      R26
+00000094:   93BF        PUSH      R27
+00000095:   2411        CLR       R1
+00000096:   9180050F    LDS       R24, 0x050F
+00000098:   91900510    LDS       R25, 0x0510
+0000009A:   91A00511    LDS       R26, 0x0511
+0000009C:   91B00512    LDS       R27, 0x0512
+0000009E:   9601        ADIW      R24, 0x01
+0000009F:   1DA1        ADC       R26, R1
+000000A0:   1DB1        ADC       R27, R1
+000000A1:   9380050F    STS       0x050F, R24
+000000A3:   93900510    STS       0x0510, R25
+000000A5:   93A00511    STS       0x0511, R26
+000000A7:   93B00512    STS       0x0512, R27
+000000A9:   91BF        POP       R27
+000000AA:   91AF        POP       R26
+000000AB:   919F        POP       R25
+000000AC:   918F        POP       R24
+000000AD:   901F        POP       R1
+000000AE:   BE1F        OUT       0x3F, R1
+000000AF:   901F        POP       R1
+000000B0:   9518        RETI
About these ads

About Jim Eli

µC experimenter
This entry was posted in Uncategorized and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s