Determine device at build time?

Is there a way to determine the micro device at build time? Perhaps a #define'd flag or somesuch?

eg, is there a way to tell if it's on a '168 or '328 and so on...

Thanks!

Is there a way to determine the micro device at build time? Perhaps a #define'd flag or somesuch?

This is a hardware question, isn't it? The compiler would have to ask the hardware what it is, wouldn't it?

They way that the IDE is set up, YOU have to pick the device type.

Or perhaps I've not understood what you want to do with the device type information.

Nope. It's not really a hardware question. I want my program to have different capabilities/settings depending on how much space there is on the device. For example

#ifdef ATMEGA_168
#define kBufSize  512
#endif

#ifdef ATMEGA_328
#define kBufSize  1024
#endif

unsigned char buffer[kBufSize];

And so on....

I want my program to have different capabilities/settings depending on how much space there is on the device.

Based on what you tell the IDE at compile time?

Look at io.h. It decides what other files to include, based on the selected board type.

Some processor-related #defines are actually passed to the compiler. So

#if defined(__AVR_ATmega328P__)
#define kBufSize  1024
#endif

may do the trick. Check this:

Yes it is possible to detect the processor type that is currently plugged into the host computer.
However, you would not be able to use the Arduino IDE and you would need
an ISP programmer to query the AVR chip for its signature.

The Arduino IDE is a typical Windows-ish like GUI. It is a GUI that provides
a certain level of capabilities but can't really be easily extended much because it does
not play well with the commandline.

If you are using makefiles or some other command line based set of tools,
and also have an ISP programmer, it could be done.
You would have to write a script (which also could be invoked by the makefile)
that would call avrdude to query the AVR through the ISP interface to determine
which chip was attached. Then the script could use the signature information to set
up variables/defines that could be passed in and used by other parts of the build
environment.

The Arduino IDE GUI and build methodology is just too wimpy to support anything like this.


What you can do is use the board type that the user selects to help you.
Unfortunately, the Arduino IDE does not create a define for the board type selected in the IDE
so it is not as easy as simply using a board type define.
But in your case it looks like all you want to know the processor type and that information is
available at compile time.
Here are some defines you might find useful. They are defined if in use otherwise not defined.
AVR_ATmega168
AVR_ATmega328P

Simply change your ifdefs to use this and you will be ok.
However, I will caution you that once you start to look at processor types,
you can run into issues. For example,
What about on a leaonardo?
That uses AVR_ATmeta32U4 processor type.

What about Mega:
AVR_ATmega1280
AVR_ATmega2560

Sanguino:
AVR_ATmega644P
AVR_ATmega644

Teensy2++:
AVR_AT90USB646
AVR_AT90USB1286

Just keep that in mind.
Should the code only work on the processors you have specific ifdefs for?

Should it create a compiler error on supported processors?
or should it have a default so that it works on all processor types?

you may want to use a #if/#else construct to allow better control such as a default or an error.
Some examples:

#if defined(__AVR_ATmega168__)
#define kBufSize  512
#elif defined (__AVR_ATmega328P__) 
#define kBufSize  1024
#else
#error "unsupported processor type"
#endif

OR

#if defined(__AVR_ATmega168__)
#define kBufSize  512
#else
#define kBufSize  1024 // all others get large buffer
#endif

OR

#if defined(__AVR_ATmega168__)
#define kBufSize  512
#elif defined (__AVR_ATmega328P__) || define(__AVR_ATmeta32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
#define kBufSize 1024
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__)
#define kBufSize  2048
#else
#define kBufsize 512 // perhaps non optimal but should work for all others.
#endif

etc....

--- bill

PaulS, spatula, bperrybap THANKS! Those were the definitions I needed. I'm still looking for io.h, but this has the key bits to help me find what I'm looking for.

bperrybap, I was planning on doing something like that. #ifdef/#elif/#else It's for my BASIC interpreter, to make it easier for the end users to get it running on their particular platform, without them needing to manually configure anything. I plan on adding load/save to eeprom shortly (I already have load/save to SD card, but that's an expensive option for some), and i'd like to have it auto-set the proper values for max program ram, max eeprom space, and so on. Just check out the code/download the .ino, and build/run.

fwiw, GitHub - BleuLlama/TinyBasicPlus: A C implementation of Tiny Basic, with a focus on support for Arduino I've gotten some bugfixes and such, and am about to dive back in to getting it working better in general, if my time allows for it, as I expect. :slight_smile:

Again, Thanks muchly y'all. :smiley:

-scott/yorgle/bleullama

Now that I've (finally) had a chance to peek at the .h files, it would appear that my work is done for me already in this regard:

eg:

#define SPM_PAGESIZE 128
#define RAMEND      0x4FF
#define XRAMEND     0x4FF
#define E2END       0x1FF
#define E2PAGESIZE  4
#define FLASHEND    0x3FFF

So... yeah. Perfect!

for later reference, on Mac, these io*.h files are in: Arduino.app/Contents/Resources/Java/hardware/tools/avr/avr/include/avr/

Couldn't the sketch once running read the signature bytes and then set upper limits on how much room it had for creating an array or storing data in EEPROM or enabling serial ports?

Sure. It certainly could, but that would use program space that could just be dealt with at compile time, consuming no program space at all. And considering that when it gets compiled/sent down to the device, it's already been tailored for that specific device, it makes sense to just use the #defines already there.

If you had code that compiled the exact same for multiple devices, say all the parts that are on the '328 datasheet - 48, 88, 168, 328 - couldn't you have 1 compiled hex file that could be burned into any of the parts, and then let sketch make adjustments as needed?
Or does the smaller memory size of each device impact where it gets loaded in memory? (as in, not start from address 0 all the time)

The smaller memory size determines the size of a few buffers so that everything can fit, and so that i can maximize space on larger devices. I also prefer to distribute this as source code, rather than compiled hex files. I do see the advantages of your method if I were distributing binaries.

So are you using the io defines as expressions in the pre-processor to help determine things?
That's probably better than looking at specific CPU types.

I'm guessing you won't get those same defines for DUE or teensy 3 (ARM processor) or chipkit (mips processor)
"arduino" boards so you will have to do some additional pre-processor checks for processor types to ensure
that the code builds those processors or at least errors off predictably.

--- bill

yorgle:
Is there a way to determine the micro device at build time? Perhaps a #define'd flag or somesuch?

eg, is there a way to tell if it's on a '168 or '328 and so on...

Thanks!

You can't determine the board at build time, but you can make your code work with different boards like this (example from one of my sketches):

#if ((defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)))
  #define _PORT PORTL // for MEGA2560
  #define _DDR  DDRL
#else
  #define _PORT PORTB // for UNO
  #define _DDR  DDRB
#endif

If you look in arduino-1.0.x/hardware/tools/avr/lib/avr/include/avr/io.h you will see lots of different strings as they relate to different devices.

Usually, it's enough to distinguish between UNO and MEGA, but if you need even more, just extend the conditional tests as shown above to include the other AVR devices.

Hope this helps.

bperrybap:
you may want to use a #if/#else construct to allow better control such as a default or an error.

Oops... I posted mine before I saw yours. Sorry.

Off Topic...
Comment on krupski's tag line...

Wouldn't it be easier to make assault and murder illegal rather than trying to have a law against every and any type of weapon?

What a concept.. Think We can Sell it? God didn't... "Thou Shalt Not Kill" is present in one form or another in all the mainstream religions... Or So I've Been Told.

Robert Khayyam Johnson Sr.

My deep personal belief is that any references to guns is best left in forums devoted to that purpose, they serve little purpose in this forum. IMNSHO.

Note that current trends in the Arduino core and etc are AWAY from checking for specific cpu types, and toward checking for specific features that you're using instead.
So instead of

#if defined(__AVR_ATmega1280__)
// m1280 has more timers to initialize
	sbi(TCCR3B, CS31);		// set timer 3 prescale factor to 64
	sbi(TCCR3B, CS30);
	sbi(TCCR3A, WGM30);		// put timer 3 in 8-bit phase correct pwm mode
	sbi(TCCR4B, CS41);		// set timer 4 prescale factor to 64
	sbi(TCCR4B, CS40);
	sbi(TCCR4A, WGM40);		// put timer 4 in 8-bit phase correct pw
#endif

One would check whether the individual timers instead:

#if defined(TCCR3B) && defined(CS31) && defined(WGM30)
	sbi(TCCR3B, CS31);
	sbi(TCCR3B, CS30);
	sbi(TCCR3A, WGM30);
#endif
	
#if defined(TCCR4B) && defined(CS41) && defined(WGM40)
	sbi(TCCR4B, CS41);
	sbi(TCCR4B, CS40);
	sbi(TCCR4A, WGM40);
#endif

this way, you can compile on essentially similar cpus without having to go and find all the places where the code checks for CPU type. (m328 vs m328p, or m1280 vs m2560, for instance!)

#define RAMEND      0x4FF

Exactly! It's much better to check for having more than a minimum amount of RAM, than to make the size of an array dependent on CPU type.
Some things are documented here: <avr/io.h>: AVR device-specific IO definitions

Docedison:
Off Topic...
Comment on krupski's tag line...

Wouldn't it be easier to make assault and murder illegal rather than trying to have a law against every and any type of weapon?

What a concept.. Think We can Sell it? God didn't... "Thou Shalt Not Kill" is present in one form or another in all the mainstream religions... Or So I've Been Told.

Robert Khayyam Johnson Sr.

My deep personal belief is that any references to guns is best left in forums devoted to that purpose, they serve little purpose in this forum. IMNSHO.

Who said anything about guns?