millis/micros timer disabled wedges DD part
xxxajk opened this issue · 10 comments
Compile with timers disabled, and the MCU wedges.
Happens on 64DD14 part, probably happens on others.
Something isn't happy :-)
void setup() {
pinMode(PIN_PC3, OUTPUT);
}
void loop() {
digitalWrite(PIN_PC3, LOW);
delay(100);
digitalWrite(PIN_PC3, HIGH);
delay(100);
}
Are you on Arduino IDE or PIO/etc?
Most PIO errors come from PIO's imperfect emulation of arduino, specifically the stuff in boards.txt that creates submenus - on PIO, you aren;t forced to select something from every menu, even if it's just leaving the default. But on PIO, people just don't specify menus where they want the default, and that has caused tons of problems lately. It has always done this, but suddenly people are noticing for some reason, and I've been having to go back and modify boards.txt to assign all default values as board defaults, instead of putting it in the menu section, and only have parameters be passed on non-default selections.
Hmm... The asm listing doesn't contain anything obviously ugly, and excludes some possibilities.
No interrupts should be happening, and I don't think any are. So what's going on? On previous versions of DxCore, you could get bizzare broken behavior on PIO by omitting menu selections, because PIO does not assign any default value to the menu (which is a cant-happen in the Arduino IDE - but not a cant-happen in arduino-cli (!!!).
void loop() {
digitalWrite(PIN_PC3, LOW);
1e2: 80 e0 ldi r24, 0x00 ; 0 //<---------------- The rjmp at the end points here
1e4: 74 df rcall .-280 ; 0xce <digitalWrite.constprop.3>
_delay_ms():
c:\arduino-1.8.13_azd5test\hardware\tools\avr\avr\include\util/delay.h:187
#else
//round up by default
__ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
#endif
__builtin_avr_delay_cycles(__ticks_dc);
1e6: 2f ef ldi r18, 0xFF ; 255
1e8: 82 e5 ldi r24, 0x52 ; 82
1ea: 97 e0 ldi r25, 0x07 ; 7
1ec: 21 50 subi r18, 0x01 ; 1
1ee: 80 40 sbci r24, 0x00 ; 0
1f0: 90 40 sbci r25, 0x00 ; 0
1f2: e1 f7 brne .-8 ; 0x1ec <main+0xd4>
1f4: 00 c0 rjmp .+0 ; 0x1f6 <main+0xde>
1f6: 00 00 nop
loop():
C:\Users\Spence\Documents\Arduino\sketch_sep28a/sketch_sep28a.ino:8
delay(100);
digitalWrite(PIN_PC3, HIGH);
1f8: 81 e0 ldi r24, 0x01 ; 1
1fa: 69 df rcall .-302 ; 0xce <digitalWrite.constprop.3>
_delay_ms():
c:\arduino-1.8.13_azd5test\hardware\tools\avr\avr\include\util/delay.h:187
1fc: 2f ef ldi r18, 0xFF ; 255
1fe: 82 e5 ldi r24, 0x52 ; 82
200: 97 e0 ldi r25, 0x07 ; 7
202: 21 50 subi r18, 0x01 ; 1
204: 80 40 sbci r24, 0x00 ; 0
206: 90 40 sbci r25, 0x00 ; 0
208: e1 f7 brne .-8 ; 0x202 <main+0xea>
20a: 00 c0 rjmp .+0 ; 0x20c <main+0xf4>
20c: 00 00 nop
20e: e9 cf rjmp .-46 ; 0x1e2 <main+0xca> // This RJMP goes up to the place marked above, this is the loop()
Perfectly innocuous looking.
Is that what the section of assembly listing near loop comes out looking like for you?
Using the Arduino builder via GNU Make, which is essentially identical to using the IDE directly.
Not sure what the culprit is, but latest test shows that blinking does indeed work...
...HOWEVER serial doesn't.
Here's the new sketch
void setup() {
pinMode(PIN_PC3, OUTPUT);
Serial.begin(115200);
delay(1000);
Serial.println("Output, and not wedged"); // nothing prints even if you swap the lines above.
}
void loop() {
digitalWrite(PIN_PC3, LOW);
delay(100);
digitalWrite(PIN_PC3, HIGH);
delay(100);
Serial.println("Output, and not wedged"); // nothing prints
}
Hi! I'm not sure, what I should see, but my bare metal AVR64DD32 shows:
19:01:57.759 -> Startup, and not wedged
19:01:57.958 -> Output, and not wedged
19:01:58.157 -> Output, and not wedged
19:01:58.357 -> Output, and not wedged
...
on the serial monitor and PC3 pulses with 5Hz [16MHz internal, Optiboot and millis selected on TCB1 (selected because of "14pin"), Arduino1.8.19 on 64bit Linux Mint]. Yes, I changed Output to Startup in the setup() :-)
With Optiboot it bootloops, due to crash...
DD14 pulses PD6 when it reboots.
There will be no serial output when you select disable millis/mircos (bootloop).
Set it to Disabled delay only, see what happens.
On bare metal you don't get anything printed or any activity on PC3 either.
Not sure if it's wedged, or resetting in a loop but the only way to actually tell that would be using optiboot.
Yapp, confirmed. When I disable the timer, nothing happens after uploading. Also after changing to "No Bootloader" the same. No pulses, no serial output.
This is weird as fuck, man.
It's bloody obvious in the asm what the problem is: Every callback that we provide, when compiled with millis disabled, compiles to a call to 0x0000 " 0x950E 0000 or 0e 94 00 00 in the byte order it is in in the flash. It's declared weak. I can use other weakly defined functions and choose to override or not override them. But not these functions. it's a weak symbol so you can override it, but for some reason, I can't seem to make it both function correctly as a weak function (allowing it to be overridden, and using the included weak definition if it's called when it's not defined), and not get rendered as a call to 0 when millis is disabled, and I'm still pondering why.
It seems like weak definitions weren't working properly, and calls to those functions instead of compile errors were turned into runtime ones, "handled" the same way every other unrecoverable error is - calling (or jumping) to 0, triggering a bootloop, because that's how we call the startuip callbacks
Next bug :-D, unless you managed to fix it while fixing this one ;-)