File: demo.dox

package info (click to toggle)
avr-libc 1%3A1.6.2.cvs20080610-2
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 14,848 kB
  • ctags: 55,619
  • sloc: ansic: 92,267; asm: 6,692; sh: 4,131; makefile: 2,481; python: 976; pascal: 426; perl: 116
file content (319 lines) | stat: -rw-r--r-- 13,574 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
/* Copyright (c) 2002,2005,2006 Theodore Roth
   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:

   * Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
   * Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
     distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  POSSIBILITY OF SUCH DAMAGE. */

/* $Id: demo.dox,v 1.16 2007/01/22 23:33:17 joerg_wunsch Exp $ */

/** \defgroup demo_project A simple project
    \ingroup demos

At this point, you should have the GNU tools configured, built, and installed
on your system. In this chapter, we present a simple example of using the GNU
tools in an AVR project. After reading this chapter, you should have a better
feel as to how the tools are used and how a \c Makefile can be configured.

\section demo_project_desc The Project

This project will use the pulse-width modulator (\c PWM) to ramp an LED on
and off every two seconds.  An AT90S2313 processor will be used as the
controller.  The circuit for this demonstration is shown in the
\ref demo_project_schematic "schematic diagram". If you have a development
kit, you should be able to use it, rather than build the circuit, for this
project.

\note Meanwhile, the AT90S2313 became obsolete.  Either use its
successor, the (pin-compatible) ATtiny2313 for the project, or perhaps
the ATmega8 or one of its successors (ATmega48/88/168) which have
become quite popular since the original demo project had been
established.  For all these more modern devices, it is no longer
necessary to use an external crystal for clocking as they ship with
the internal 1 MHz oscillator enabled, so C1, C2, and Q1 can be
omitted.  Normally, for this experiment, the external circuitry on
/RESET (R1, C3) can be omitted as well, leaving only the AVR, the LED,
the bypass capacitor C4, and perhaps R2.  For the ATmega8/48/88/168,
use PB1 (pin 15 at the DIP-28 package) to connect the LED to.
Additionally, this demo has been ported to many different other AVRs.
The location of the respective OC pin varies between different AVRs,
and it is mandated by the AVR hardware.

\anchor demo_project_schematic
\image html demo.png "Schematic of circuit for demo project"
\image latex demo.eps "Schematic of circuit for demo project" width=4in

The source code is given in \ref demo_project_src "demo.c".  For the sake of
this example, create a file called \c demo.c containing this source code.
Some of the more important parts of the code are:

\par Note [1]:
As the AVR microcontroller series has been developed during the past
years, new features have been added over time.  Even though the basic
concepts of the timer/counter1 are still the same as they used to be
back in early 2001 when this simple demo was written initially, the
names of registers and bits have been changed slightly to reflect the
new features.  Also, the port and pin mapping of the output compare
match 1A (or 1 for older devices) pin which is used to control the LED
varies between different AVRs.  The file <tt>iocompat.h</tt> tries to
abstract between all this differences using some preprocessor \c \#ifdef
statements, so the actual program itself can operate on a common set of
symbolic names.  The macros defined by that file are:

- \c OCR the name of the OCR register used to control the PWM (usually
either OCR1 or OCR1A)
- \c DDROC the name of the DDR (data direction register) for the OC
output
- \c OC1 the pin number of the OC1[A] output within its port
- \c TIMER1_TOP the TOP value of the timer used for the PWM (1023
for 10-bit PWMs, 255 for devices that can only handle an 8-bit
PWM)
- \c TIMER1_PWM_INIT the initialization bits to be set into control
register 1A in order to setup 10-bit (or 8-bit) phase and frequency
correct PWM mode
- \c TIMER1_CLOCKSOURCE the clock bits to set in the respective
control register to start the PWM timer; usually the timer runs at
full CPU clock for 10-bit PWMs, while it runs on a prescaled clock
for 8-bit PWMs

\par Note [2]:
ISR() is a macro that marks the function as an interrupt routine. In this
case, the function will get called when timer 1 overflows. Setting up
interrupts is explained in greater detail in \ref avr_interrupts.

\par Note [3]:
The \c PWM is being used in 10-bit mode, so we need a 16-bit variable to
remember the current value.

\par Note [4]:
This section determines the new value of the \c PWM.

\par Note [5]:
Here's where the newly computed value is loaded into the \c PWM register.
Since we are in an interrupt routine, it is safe to use a 16-bit assignment
to the register.  Outside of an interrupt, the assignment should only be
performed with interrupts disabled if there's a chance that an interrupt
routine could also access this register (or another register that uses
\c TEMP), see the appropriate \ref faq_16bitio "FAQ entry".

\par Note [6]:
This routine gets called after a reset. It initializes the \c PWM and enables
interrupts.

\par Note [7]:
The main loop of the program does nothing -- all the work is done by the
interrupt routine! The <tt>sleep_mode()</tt> puts the processor on sleep
until the next interrupt, to conserve power.  Of course, that probably
won't be noticable as we are still driving a LED, it is merely mentioned
here to demonstrate the basic principle.

\par Note [8]:
Early AVR devices saturate their outputs at rather low currents when
sourcing current, so the LED can be connected directly, the resulting
current through the LED will be about 15 mA.  For modern parts (at
least for the ATmega 128), however Atmel has drastically increased the
IO source capability, so when operating at 5 V Vcc, R2 is needed.  Its
value should be about 150 Ohms.  When operating the circuit at 3 V, it
can still be omitted though.

\section demo_project_src The Source Code

\include demo.c

\section demo_project_compile Compiling and Linking

This first thing that needs to be done is compile the source. When compiling,
the compiler needs to know the processor type so the \c -mmcu option is
specified. The \c -Os option will tell the compiler to optimize the code for
efficient space usage (at the possible expense of code execution speed). The
\c -g is used to embed debug info. The debug info is useful for disassemblies
and doesn't end up in the \c .hex files, so I usually specify it. Finally, the
\c -c tells the compiler to compile and stop -- don't link. This demo is small
enough that we could compile and link in one step. However, real-world
projects will have several modules and will typically need to break up the
building of the project into several compiles and one link.

\verbatim
    $ avr-gcc -g -Os -mmcu=atmega8 -c demo.c
\endverbatim

The compilation will create a \c demo.o file. Next we link it into a binary
called \c demo.elf.

\verbatim
    $ avr-gcc -g -mmcu=atmega8 -o demo.elf demo.o
\endverbatim

It is important to specify the MCU type when linking. The compiler uses the \c
-mmcu option to choose start-up files and run-time libraries that get linked
together. If this option isn't specified, the compiler defaults to the 8515
processor environment, which is most certainly what you didn't want.

\section demo_project_obj Examining the Object File

\addindex disassembling

Now we have a binary file. Can we do anything useful with it (besides put it
into the processor?) The GNU Binutils suite is made up of many useful tools
for manipulating object files that get generated. One tool is \c avr-objdump,
which takes information from the object file and displays it in many useful
ways. Typing the command by itself will cause it to list out its
options.

For instance, to get a feel of the application's size, the \c -h option can be
used. The output of this option shows how much space is used in each of the
sections (the \c .stab and \c .stabstr sections hold the debugging information
and won't make it into the ROM file).

An even more useful option is \c -S. This option disassembles the binary file
and intersperses the source code in the output! This method is much better, in
my opinion, than using the \c -S with the compiler because this listing
includes routines from the libraries and the vector table contents. Also, all
the "fix-ups" have been satisfied. In other words, the listing generated by
this option reflects the actual code that the processor will run.

\verbatim
    $ avr-objdump -h -S demo.elf > demo.lst
\endverbatim

Here's the output as saved in the \c demo.lst file:

\verbinclude demo.lst

\section demo_project_map Linker Map Files

\c avr-objdump is very useful, but sometimes it's necessary to see information
about the link that can only be generated by the linker. A map file contains
this information. A map file is useful for monitoring the sizes of your code
and data. It also shows where modules are loaded and which modules were loaded
from libraries. It is yet another view of your application. To get a map file,
I usually add <tt><b>-Wl,-Map,demo.map</b></tt> to my link command. Relink the
application using the following command to generate \c demo.map (a portion of
which is shown below).

\verbatim
    $ avr-gcc -g -mmcu=atmega8 -Wl,-Map,demo.map -o demo.elf demo.o
\endverbatim

\dontinclude demo.map

Some points of interest in the \c demo.map file are:

\skip .rela.plt
\until __ctors_start

The \c .text segment (where program instructions are stored) starts at
location 0x0.

\skipline *(.fini2) 
\until __eeprom_end

The last address in the \c .text segment is location \c 0x114 ( denoted by \c
_etext ), so the instructions use up 276 bytes of FLASH.

The \c .data segment (where initialized static variables are stored) starts
at location \c 0x60, which is the first address after the register bank on an
ATmega8 processor.

The next available address in the \c .data segment is also location \c 0x60,
so the application has no initialized data.

The \c .bss segment (where uninitialized data is stored) starts at location
\c 0x60.

The next available address in the \c .bss segment is location 0x63, so the
application uses 3 bytes of uninitialized data.

The \c .eeprom segment (where EEPROM variables are stored) starts at
location 0x0.

The next available address in the \c .eeprom segment is also location 0x0,
so there aren't any EEPROM variables.

\section demo_ihex Generating Intel Hex Files

We have a binary of the application, but how do we get it into the processor?
Most (if not all) programmers will not accept a GNU executable as an input
file, so we need to do a little more processing. The next step is to extract
portions of the binary and save the information into \c .hex files. The GNU
utility that does this is called \c avr-objcopy.

The ROM contents can be pulled from our project's binary and put into the file
demo.hex using the following command:

\verbatim
    $ avr-objcopy -j .text -j .data -O ihex demo.elf demo.hex
\endverbatim

The resulting \c demo.hex file contains:

\verbinclude demo.hex

The \c -j option indicates that we want the information from the \c .text and \c .data
segment extracted. If we specify the EEPROM segment, we can generate a \c .hex
file that can be used to program the EEPROM:

\verbatim
    $ avr-objcopy -j .eeprom --change-section-lma .eeprom=0 -O ihex demo.elf demo_eeprom.hex
\endverbatim

There is no \c demo_eeprom.hex file written, as that file would be
empty.

Starting with version 2.17 of the GNU binutils, the \c avr-objcopy
command that used to generate the empty EEPROM files now aborts
because of the empty input section \c .eeprom, so these empty files
are not generated.  It also signals an error to the Makefile which
will be caught there, and makes it print a message about the empty
file not being generated.

\section demo_make Letting Make Build the Project

Rather than type these commands over and over, they can all be placed in a
make file. To build the demo project using \c make,
save the following in a file called \c Makefile.

\note This \c Makefile can only be used as input for the GNU version of \c
make.

\include demo/Makefile

\section demo_sourceref Reference to the source code

\htmlonly
<ul>
  <li><a href="../examples/demo/demo.c">demo.c</a></li>
  <li><a href="../examples/demo/iocompat.h">iocompat.h</a></li>
  <li><a href="../examples/demo/Makefile">Makefile</a></li>
</ul>
\endhtmlonly

\latexonly
The source code is installed under

\texttt{\$prefix/share/doc/avr-libc/examples/demo/},

where \texttt{\$prefix} is a configuration option.  For Unix
systems, it is usually set to either \texttt{/usr} or
\texttt{/usr/local}.
\endlatexonly

*/