Cduino Manual
Architecture Overview
First take a look at the abstract on the
home page.
The common code (make plus a bit of perl) required to compile and upload
programs lives in the top-level directory. Modules live in their own
subdirectories and link into the top level directory and each other as needed.
For example, if a module needs to use serial communication, it will contain
symbolic links to the serial communication implementation and headers in the
uart module. The uart module itself contains both the uart interface and
implementation, and a demonstration program showing how to use the interface.
The overall architecture is thus more prototypal
than hierarchical. This is a convenient arrangement for microcontrollers,
where the target is often a self-contained or mostly self-contained system.
Basic Strategies for Using and Modifying
To start making your own stand-along program without caring about the rest of
Cduino:
- Do
cp --recursive --dereference some_module ~/new_program
where some_module is the one that already comes closest to doing
what you want.
- Grab code from other modules as needed and mix it in. Note that you are
responsible for keeping track of the dependencies of this additional code.
Generally this means checking for included headers, which should appear as
symbolic links in the other module's subdirectories.
To add a new module to Cduino (a nice thing to do for others):
- Make a new subdirectory for it.
- Give it its own minimal Makefile that includes generic.mk (see for
example the simple_blink module Makefile).
- Link (
ln -s) to existing headers and sources in other
modules as needed.
- Write a program that exercises the module using the simplest possible
hardware setup. This is the program that the writeflash target will put on
the chip when built in your module's subdirectory.
- Put comments in the module Makefile or give it a README in which you say
what it does or give a pointer to that information, and describe any hardware
required to exercise the module effectively.
generic.mk: What it Assumes and What it Provides
The code in generic.mk contains most of the voodoo required to compile and
upload C code for the arduino. There are sensible defaults for all settings.
The simplest possible Makefile for a module consists of a single line:
include generic.mk (where generic.mk is a symbolic
link to the file generic.mk in the distribution top-level directory).
To disable some troublesome crufty old Make behavior, the -R option must be
passed to all make invocations that use generic.mk.
The generic.mk file provides the following targets intended for
public use:
By default, the targets in generic.mk intended for public use
behave like this:
writeflash -- Compile all .c files into object files using
settings appropriate for Arduino Duemilanove hardware, link them, and upload
them using the arduino bootloader method. All .c files are
assumed to depend on all headers and on the Makefile (so everything is
recompiled if anything has changed).
replace_bootloader -- replace the bootloader on the ATMega
on the arduino. This is useful if an upload method that nukes the bootloader
has been used (see below).
So by default, you just write your code and type make -R
writeflash in your module subdirectory. You may not need to know any
further details.
If more control is needed, there are a number of Make variables that affect how
generic.mk behaves. These occur in sections marked "Overridable" in that file.
Variable Overview
COMPILER_MCU -- The AVR microcontroller part name as known
by the avr-gcc compiler. With only minimal variable settings, other parts
besides the atmega328p that ships with newish arduinos can be
programmed using this make setup.
PROGRAMMER_MCU -- The AVR microcontroll part name as known
by the avrdude uploader program.
CPU_FREQ_DEFINE -- A define which sets the F_CPU macro,
which AVR libc uses. With some tweaking of this variable and the fuse
settings, parts running at other frequencies besides the default can be
programmed using this make setup.
PROGNAME -- The basename of the binary output file that will
be uploaded. By default the basename is program_to_upload.
OBJS -- space-delimited list of object files to be created
and linked together. By default one object file is required for each
.c file (or symbolic link to a .c file) in the
module directory.
HEADERS -- space-delimited list of headers used by the
.c files from which the object files are produced. By default,
all .c files depend on all header files found in the module
directory.
UPLOAD_METHOD -- This must be either
"arduino_bl" or "AVRISPmkII". The defualt is "arduino_bl", meaning that the
program should be uploaded over the USB/serial line using the arduino
bootloader. The AVRISPmkII method instead expects to find an AVRISPmkII
device and uses that. Note that this latter method overwrites the Arduino
bootloader, which will have to be replaced (probably using the
replace_bootloader target; see above) before the arduino_bl method can be
used again. This setting may be useful for migrating to a stand-alone
(non-arduino) design.
DTR_PULSE_NOT_REQUIRED -- If this is set to "true", the DTR
pulse that the arduino normall uses to save the user having to push the reset
button immediately after avrdude programming begins is not considered
essential (os the perl modules used to do it aren't required). Of course,
now you will have to push the reset button all the time.
- build and upload program variables -- a number of variables exist which
allow the compiler, uploader, etc. programs to bet set (e.g. CC, AVRDUDE,
etc.). These are useful if you want to test the effects of different
compiler or uploader versions.
LOCK_AND_FUSE_SETTINGS -- This variable can be used to set
the lock and fuse bytes of the arduino (normally they are left alone). Doing
so is required for the use of different clock frequencies, clock sources,
power management, brown-out detection, watchdog timer, and other hardware
features. However, certain settings are required for normal arduino
functionality, so changing them may break things. They can hopefully be
reset using the replace_bootloader target, but this is not guaranteed. For
example, setting the clock source to the low-frequency low-power internal
oscillator makes the chips unprogrammable for me.
AVRLIBC_PRINTF_LDFLAGS -- This variable can be used to get a
more feature-complete (and bigger) or more minimal (and smaller)
implementation of printf() and friends. By default, most
printf() features are supported, with the notable exception of
floating point output. See the comments in the generic.mk for
details.
CPP_DEBUG_DEFINE_FLAGS -- This can be used to pass define
options to the C preprocessor to enable conditional debugging sections or the
like.