Hi,
My setup is as follows:
Board: Arduino Uno
Compiler: Clang 11 (compiled from source)
I do not use the Arduino library (Arduino.h, etc...)
I am having a bit of trouble understanding why some code in an ISR seems to not be executed.
Here is a code snippet of an ISR that works as intended:
ISR(TIMER1_COMPA)
{
portb portb{};
portb.PORTB4.flip();
portb.PORTB5.flip();
}
This ISR gets called every second and switch on and off two LEDs. This goes on until the board is powered off, perfect!
Now if I add an if statement to this ISR it does not seem to get executed. The ISR now looks like this:
volatile char stop_counter = 0;
ISR(TIMER1_COMPA)
{
char counter = stop_counter;
if(counter < 16)
{
portb portb{};
portb.PORTB4.flip();
portb.PORTB5.flip();
}
stop_counter = counter + 1;
}
The type portb is a wrapper around a class containing a volatile reference to the address of portb (0x25 as per the datasheet, see p. 72 - 13.4.2 PORTB – The Port B Data Register).
Now, I know the code I wrote does not work because the LEDs should stop blinking after 16 seconds but they do not. They carry on blinking until the board is powered off.
I also know the code for the if statement is not removed by the compiler since when I use avr-objdump to see the emitted instructions I can see the instructions for the comparison.
This is the avr-objdump output (I have added the comments):
; CORE SETUP + STACK MANAGEMENT
a6: 78 94 sei
a8: 0f 92 push r0
aa: 1f 92 push r1
ac: 0f b6 in r0, 0x3f ; 63
ae: 0f 92 push r0
b0: 00 24 eor r0, r0
; USER STACK MANAGEMENT
b2: 2f 93 push r18
b4: 8f 93 push r24
b6: 9f 93 push r25
; BRANCH
b8: 80 91 60 00 lds r24, 0x0060 ; 0x800060 <__DATA_REGION_ORIGIN__>
bc: 80 31 cpi r24, 0x10 ; 16
be: 44 f4 brge .+16 ; 0xd0 <__vector_11+0x2a>
; FLIP PORTB BIT #4
c0: 90 e1 ldi r25, 0x10 ; 16
c2: 25 b1 in r18, 0x05 ; 5
c4: 29 27 eor r18, r25
c6: 25 b9 out 0x05, r18 ; 5
; FLIP PORTB BIT #5
c8: 90 e2 ldi r25, 0x20 ; 32
ca: 25 b1 in r18, 0x05 ; 5
cc: 29 27 eor r18, r25
ce: 25 b9 out 0x05, r18 ; 5
; BRANCH LANDING SPOT IF STOP_COUNTER >= 16
d0: 83 95 inc r24
d2: 80 93 60 00 sts 0x0060, r24 ; 0x800060 <__DATA_REGION_ORIGIN__>
; USER CODE STACK MANAGEMENT
d6: 9f 91 pop r25
d8: 8f 91 pop r24
da: 2f 91 pop r18
; CORE CLEAN UP + STACK MANAGEMENT
dc: 0f 90 pop r0
de: 0f be out 0x3f, r0 ; 63
e0: 1f 90 pop r1
e2: 0f 90 pop r0
e4: 18 95 reti
I know the code has a few other issues and I know I should not put too much code in an ISR however, these are not my concerns right now.
I would love it if someone could help me understand why the code seems to be ignored?
As I understand it, an ISR is a bog-standard function at a specific address therefore I assumed that an if statement would not be an issue obviously, I was wrong.
If you need more information, I will be happy to provide more.
Cheers!
