MCUdude / MicroCore

A light-weight Arduino hardware package for ATtiny13

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Reading multiple analog pins fails to compile

aspyra opened this issue · comments

I am trying to update an old program to the new 2.0.0 version.
Calling 'analogRead(A3)' by itself compiles, but trying to read analog channels 1-3:
'analogRead(A1); analogRead(A2); analogRead(A3);'
Fails to compile, throwing badArg("Analog pin must be a constant");

Tried to find the root of the problem, but I cannot find __builtin_constant_p() function anywhere.

commented

Can you post your code so I can have a look?

commented

Thanks for reporting BTW, it was easy enough to reproduce:

{
}

void loop()
{
  analogRead(A1);
  analogRead(A2);
  analogRead(A3);
  // It does compile if the line above is commented out
}
In function 'check_valid_analog_pin',
    inlined from 'analogRead' at /Users/hans/Documents/Arduino/hardware/MicroCore/avr/cores/microcore/wiring_analog.c:27:3:
/Users/hans/Documents/Arduino/hardware/MicroCore/avr/cores/microcore/Arduino.h:147:7: error: call to 'badArg' declared with attribute error: 
       badArg("Analog pin must be a constant");
       ^
lto-wrapper: fatal error: /Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avr-gcc returned 1 exit status
compilation terminated.
/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/../lib/gcc/avr/7.3.0/../../../../avr/bin/ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board ATtiny13.

@nerdralph do you have any idea why this is happening? The code is borrowed from picoCore.

I have looked through the code and the fuction check_valid_analog_pin(analog_pin_t pin) is already using this atribute. Adding it to AnalogRead() allows the code to be compiled. I guess the question now is, what's better: dropping/restating the check or inlining all calls to analogRead().

commented

Adding __attribute__((always_inline)) increases the compiled size quite a lot if it's used multiple times in the project. Maybe it's best to remove the check_valid_analog_pin(pin) check? The analogRead() function already requires an argument that is analog_pin_t, so we pretty much have a valid check already, since analogRead(0) won't compile.

I just did some comparisons between picoCore and MicroCore. For a basic sketch, adding a call to analogRead increases the sketch size by 46 bytes for MicroCore, vs 18 bytes for picoCore. picoCore uses always_inline, and each additional call to analogRead() takes 20 more bytes. If I remove the always_inline, and rely on the analog pin enum for ensuring a valid analog pin, the second analogRead() call takes 18 more bytes, and every subsequent takes 6 more.

Since MicroCore's analogRead is much larger, it makes sense not to inline it. I think I'll even drop the always_inline in picoCore since it can save a few extra bytes.

I also confirmed that you can call analogRead(0) in a .c file, but I don't think this is a big concern as anyone creating multi-file sketches with extern "C" functions should be smart enough to know better.

commented

adding a call to analogRead increases the sketch size by 46 bytes for MicroCore, vs 18 bytes for picoCore

How can this be? I'm looking at the source code for analogRead, and they are identical, except that MicroCore sets the ADC prescaler based on F_CPU

commented

@nerdralph I tried to compile similar sketches for MicroCore and picoCore. It turns out that analogRead increases the sketch size with MicroCore with 20 bytes. It's also 20 bytes with picoCore (on my computer, avr-gcc 7.3.0), but you do have some other neat tricks to reduce the size of a blank sketch that I haven't been able to figure out.

I've just pushed a fix for this issue, where I just remove the pin constant check. I'll release MicroCore 2.0.1 very soon

commented

A new release, v2.0.1 is now available, where I've just removed the check_valid_analog_pin check.