What's beneath the Arduino library?

I was looking at the SPI library source files and saw some constructions I wasn't familiar with. My guess it is something that is called AVR (?).

I want to learn how the software layers fit together and what I can do to customize/replace them. I seek information that documents the complete stack from hardware (I found the datasheet for the mcu) up to the Arduino libraries.

Can anyone direct me to some resources (links) I can read up on?

Thanx very much.

and saw some constructions I wasn't familiar with

So post them and ask, or are we supposed to guess what you are familiar with and what you aren't?

I didn't wanna get into specifics. I'm just looking for the information on the software layer that is 'under' the Arduino 'language'/statements/functions.

But since you've asked :smiley:

Here's the transfer method of the SPI class:

byte SPIClass::transfer(byte _data) {
  SPDR = _data;
  while (!(SPSR & _BV(SPIF)))
    ;
  return SPDR;
}

I don't get the SPDR and SPSR and _BV(SPIF) stuff. What are those and where are they defined? Is that what is called AVR?

SPDR and SPSR are registers (SPI Data and Status) in the Arduino processor. That processor is an AVR ATmegaXXX chip made by Atmel.

_BV is a macro to get a "bit value"

So that code loops until the SPIF (Interrupt Flag) bit in the SPSR (Status Register) is set indicating that the byte has been transmitted.

If you look at the ATmega328 or ATmega2560 data sheet you will find all these acronyms and register names.


Rob

Ah, so these keywords are recognized by the compiler directly?

obiwanjacobi:
Ah, so these keywords are recognized by the compiler directly?

Well not directly. I believe the arduino core files have a AVR support library somewhere where the constant names are defined. Can't think of it's name right now but it's there somewhere.

Lefty

The bootstrap header file is <avr/io.h>. That header file includes a processor specific header file from the same directory.

Things like SPDR and SPSR are macros that expand to reference specific memory addresses. In the general case, the compiler simply generates code to access the memory location. There are at least two specific optimizations the compiler can perform. If the memory location is low enough then I/O machine instructions are used instead of memory access machine instructions. If the C expression references a single bit and the memory location is low enough then bit manipulation machine instructions are used.

Yes, I've found io.h that includes the actual io definitions for a specific device/mcu.
I also encountered '_SFR_IO8(x)' that is defined in sfr_defs.h. All those register names are defined as _SFR_IO8(x) where x is unique to the specific case.

So basically if you write this code :

0x01 = 0x00;

The compiler interprets the 0x01 as a port address and the 0x00 as data the port is set to??

It is slowely becoming clear to me. Its just that I've never seen this type of construct before. I always programmed on the PC (windows) using Microsoft tools :smiley:

So basically if you write this code :

0x01 = 0x00;

The compiler interprets the 0x01 as a port address and the 0x00 as data the port is set to??

Of course not. "0x01" is an integer constant; it is not a reference to a memory location. This is a reference to a memory location... (*(volatile uint8_t *)(0x01)) = 0x00; ...even on a PC using Microsoft tools.

The point I'm trying to make is that the compiler used by the Arduino IDE does not use a special C++ like dialect. It is a C++ compiler. You've heard the phrase, "not your father’s Oldsmobile." Well, it "IS your father's compiler." The "special" thing about the compiler is that it is very compliant with C++ standards; which means the language does not deviate from the Microsoft compiler you used on a PC.

sfr_defs.h is split into two halves; _SFR_IO8 has two definitions. The definition for assembly files expands to a simple constant. The definition for C files expands to a memory reference like the one above.

Phjew, the world is round again :wink: Although I must say I must have missed the '(*(volatile uint8_t *)' part... :smiley:

Thanx. So the cpu addresses IO pins just as it would normal memory addresses.

Meantime I've looked around in the include files of the avr branch. Is there any docs on what is in there or should I read each .h separately? (hope not)

Thanx for explaining it to me.

http://www.nongnu.org/avr-libc/
http://www.nongnu.org/avr-libc/user-manual/modules.html