MicroCore icon indicating copy to clipboard operation
MicroCore copied to clipboard

```delayMicroseconds``` fails to compile with a non-constant argument

Open arduino12 opened this issue 2 years ago • 3 comments

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!

arduino12 avatar Apr 30 '22 22:04 arduino12

@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

MCUdude avatar May 01 '22 06:05 MCUdude

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.

nerdralph avatar Jul 07 '22 21:07 nerdralph

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

Bravo13 avatar Aug 26 '22 10:08 Bravo13

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

nerdralph avatar Jan 03 '23 17:01 nerdralph

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

nerdralph avatar Jan 03 '23 18:01 nerdralph

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.

nerdralph avatar Jan 03 '23 18:01 nerdralph

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.

MCUdude avatar Jan 03 '23 19:01 MCUdude

Fixed in 3c5cb93.

Thanks @nerdralph!

MCUdude avatar Jan 04 '23 19:01 MCUdude