How do I know what processor I am using?

Lets say that I am writing a program that uses interrupts. If I want to write the program for a variety of processors, I need to know what the processor is that I am compiling for. In the Arduino IDE, under tools, you make a selection as to what processor you are using. Is this information somehow conveyed to the program by means of defines? Does the IDE automatically generate these defines?

Specifically, I am playing with a RFM69 module. In the header file are some statements like..

(this is not the correct syntax but I hope you see what I am saying)

if defined Uno then Int0 = 1
if defined mega then int0 = 2
etc.

Whee would Uno and Mega be defined and exactly what are the defines?

have a look at how WInterrupts.c is written

you'll see things such as

#if defined(__AVR_ATmega32U4__)
	// I hate doing this, but the register assignment differs between the 1280/2560
	// and the 32U4.  Since avrlib defines registers PCMSK1 and PCMSK2 that aren't 
	// even present on the 32U4 this is the only way to distinguish between them.

or if you look in HardwareSerial.h you will see things like

#if !defined(SERIAL_TX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_TX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 64
#endif
#endif

that should give you ideas

The compiler provides the specific processor as a define, here’s a sample line section from Arduino.h header that uses them:

#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
#define DEFAULT 0
#define EXTERNAL 1
#define INTERNAL 2
#else  
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
#define INTERNAL1V1 2
#define INTERNAL2V56 3
#else
#define INTERNAL 3
#endif
#define DEFAULT 1
#define EXTERNAL 0
#endif

The Arduino IDE also provides some defines in the command line, here’s a sample screenshot compiled with the board set to Uno:

screenshot.4.jpg

F_CPU=16000000L is the frequency of the CPU
ARDUINO=10611 is the IDE version
ARDUINO_AVR_UNO should be self explanatory
ARDUINO_ARCH_AVR is to distinguish between the ones built with an AVR chip (most) and other kinds of chip (the Due had an ARM chip, for example).

barryjo:
Lets say that I am writing a program that uses interrupts. If I want to write the program for a variety of processors, I need to know what the processor is that I am compiling for.

That isn't necessarily always true. There are ways to use interrupts using Arduino that do not require knowing the specific processor.

In the Arduino IDE, under tools, you make a selection as to what processor you are using.

The IDE does not let you select a processor type, it merely lets you select a board type.
And while a given board does contain a particularly processor, the board type and the processor type are not the same thing.

When diving down really low, there can be reasons to know:

  • board type
  • processor type
  • core

The 3 are not the same but depending on what is being done there can be needs for any of that information.

Where things can get really messy is that the variant files are allowed to map things like pins in any crazy way they want to. And the variant file is per board type.
So depending on what you are doing, just knowing the processor type may not be good enough.

In many cases there are low level Arduino macros in the variant file that can be used or at least help in avoiding having to write processor specific code.

If those macros are not good enough, things will quickly get complicated.
The main reason is that the IDE does not provide information about the core being used or the processor.
It only provides information about the board being used.
And the information available varies quite a bit between IDE versions.

So if you are writing processor specific code it is unwise to use defines like ARDUINO_AVR_UNO as designator for m328 as the UNO is only one of many boards that have that processor on it and defines like that only exist in the more recent IDEs.

I've done stuff like this in my openGLCD library, and it is a total bear to do especially when looking at other cores like the 1284 or the chipKit pic32 cores.
I would advise against it unless there is some compelling reason to do so - like no other way of handling it.

What specifically are you doing that needs to drive down to touching h/w registers within specific processors?
that cannot be done in some other more portable way?
i.e. there are ways to use interrupts without having to dive down and touch h/w registers.

--- bill

"What specifically are you doing that needs to drive down to touching h/w registers within specific processors?
that cannot be done in some other more portable way?"

I am trying to get two RFM69HCW transceiver modules to work with each other. I have an Arduino Uno and an Arduino Mega2560. When I go to the support pages for the Uno there issome but not complete wiring documentation. I can go to a SparkFun web page hookup guide and get what I think is better documentation.

I cannot get the Arduino examples to work at all. I can get the SparkFun example to work through one cycle.

I am wondering if I have the wiring correct considering the interrupts and so far have not found any clear wiring documentation and example software.

In the Arduino example software there is a line of code that sets up what the interrupt pin and number is when the RFM69 class is instantiated. This is not done in the SparkFun demo software.

Anyway, I am getting off the subject of interrupts but I tend to think the problem is here.

There are macros in the variant file to convert from arduino pin numbers to various interrupt information.
It is hard to tell exactly what you are doing as you haven't really told us (shown any code) but so far it doesn't seem like anything you are needing to do would need to directly touch h/w and could likely be done in a portable way across processors.

--- bill

The problem is so confusing to me that I am having a hard time explaining it so I can get help but.

I have example software and library that says to connect a hardware interrupt line to digital pin 2 of the Uno (board) and that this is interrupt number 0. I have a Uno and a Mega2560 so my question is..

Should I be able to connect the same wire to pin 2 of the Mega2560 (board)?

There are other SPI lines, 4 of them, that are used to transfer data. These seem to be working as messages are in fact transferred but only one time and then things hang up.

From this, I assume that the issue is that when I use the Mega, I am not connecting the wire to the correct pin or there is some other interrupt issue.

I guess I am going to have to dig into the libraries that are supplied to fine the answer. I do understand C++ programming but as an amateur not a professional so I worry that I will cause other problems and may not be able to figure out the answer. I know from past experience when I did do a lot of programming that interrupts always cause many problems.

barryjo:
I know from past experience when I did do a lot of programming that interrupts always cause many problems.

If that was the case then there were some general concepts that have not been understood.

Once you have interrupts you have to understand some of the issues to do with multiprocessing,
like atomic operations and race-conditions.

I have example software and library that says to connect a hardware interrupt line to digital pin 2 of the Uno (board) and that this is interrupt number 0. I have a Uno and a Mega2560 so my question is..

Should I be able to connect the same wire to pin 2 of the Mega2560 (board)?

Yes, if you use the Arduino IDE, and the syntax

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);

See attachInterrupt() - Arduino Reference

The arduino IDE provides a level of abstraction. Pin 2 is Int0 on the AT328 and Int4 on the AT2560, but attachInterrupt() knows what to do.

I am still puzzled. I am using the example code from the Arduino web site that implements a transmitter and receiver running on two different Arduinos.

For a long time, the example would not work. Then by chance I removed the statement,
"RFM69 radio = RFM69(RFM69_CS, RFM69_IRQ, IS_RFM69HCW, RFM69_IRQN);" and replaced it with
"RFM69 radio;
and now the example works. I do not know why.

For a long time, the example would not work. Then by chance I removed the statement,
"RFM69 radio = RFM69(RFM69_CS, RFM69_IRQ, IS_RFM69HCW, RFM69_IRQN);" and replaced it with
"RFM69 radio;
and now the example works. I do not know why.

if "radio" is a global variable, I think the first statement will call the constructor for the object BEFORE the arduino initialization code gets to run. Depending on ... dependencies, this is unlikely to work. It's generally recommended that arduino objects be simply DEFINED by their declaration, and initialized by a "begin" method:

RFM68 radio;
void setup() {
radio.begin(RFM69_CS, RFM69_IRQ, IS_RFM69HCW, RFM69_IRQN);
}

(I'm not sure what this has to do with the original subject?)