MicroCore
MicroCore copied to clipboard
```delayMicroseconds``` fails to compile with a non-constant argument
Hi,
While developing a small ATtiny13 based servo motor control,
I found out that delayMicroseconds
fails to compile with non constant argument!
void setup()
{
delayMicroseconds(1000); // compiles with constant argument
delayMicroseconds(random(1000)); // fails to compile with non constant argument
}
The error message:
C:\Users\User\AppData\Local\Temp\cci0wRhE.s: Assembler messages:
C:\Users\User\AppData\Local\Temp\cci0wRhE.s:87: Error: register r24, r26, r28 or r30 required
lto-wrapper.exe: fatal error: C:\Users\User\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7/bin/avr-gcc returned 1 exit status
compilation terminated.
c:/users/user/appdata/local/arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/../lib/gcc/avr/7.3.0/../../../../avr/bin/ld.exe: error: lto-wrapper failed
collect2.exe: error: ld returned 1 exit status
exit status 1
Error compiling for board ATtiny13.
I found out that this line cause the error.. Also this line looks bad- what if the function is called with argument smaller than 2? Note that the above code compiles for other ATtiny using their delayMicroseconds.
As a workaround I wrote this function, but it is not uS accurate..
void delay_microseconds(uint16_t us)
{
while (us--)
_delay_us(1);
}
@MCUdude your help here will be highly appreciated!
@nerdralph any idea why this suddenly turned out to be a problem? It did work previously...
https://github.com/MCUdude/MicroCore/blob/f1b7e292a0ed4ebdf79cfa5d044102e953c83b74/avr/cores/microcore/Arduino.h#L118-L143
I've been busy with other work for the past several months, so haven't tried testing this. It certainly didn't happen with the versions of the Arduino IDE I had tested with (1.8.9 & 1.8.13). Whenever I get back to playing with embedded coding, I'll try to duplicate the problem.
Same issue here with delayMicroseconds. I'm not a big guru of all that c-language things but looks like asm sbiw
dont like +d constraint. And as I understand from this avr-libc man sbiw
expects either +w or +I constraints. Anyway, in my case I can compile mine code either with debug mode or with +w contraint here https://github.com/MCUdude/MicroCore/blob/f1b7e292a0ed4ebdf79cfa5d044102e953c83b74/avr/cores/microcore/Arduino.h#L141
I finally got the time to look into this, and @Bravo13 is correct. I used the wrong constraint "+d", which is for any upper register (r16-r31), but sbiw only works with the upper register pairs starting with r24, which require the "+w" constraint. When the compiler happens to pick one of those registers, it works fine, so the bug slipped through testing. I used the same code in ArduinoShrink and PicoCore, so I've got to fix it in a few places. Perhaps I should've used a git submodule for common code...
p.s. the latest constraints are here: https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
There was another doc referenced on avrfreaks that had more inline asm details, but I can't find it...
Hans, have you put any thought into using submodules (or some other technique) to share common code across github repos? Just copying and pasting the text is coming back to bite me since now it needs to be fixed in at least 3 places.
I'm using subtrees for the bootloaders and corefiles for my other Arduino cores. Personally, I wouldn't bother if you only need to change the code in two separate repos. It's pretty straight forward to set up, but if you already consider your code stable and mature, you won't save much time. I always bring up a cheat sheet every time I need to update the Arduino corefiles or bootloaders because I always forget how the command for updating a specific subtree.
At first, I tried to use a submodule, which is more straightforward than a subtree, but the issue with this approach was that the submodule wasn't downloaded when the repo was downloaded as ZIP file from github.com. Cloning the repo was the only way to get everything.