PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wo sind die Ports des ATmega8L im Code definiert?



ehenkes
13.05.2007, 13:45
Wenn man sich von oben nach unten im Code durchwühlt, trifft man im low level Bereich auf Code wie diesen:


inline void MotorSpeed (unsigned char left_speed, unsigned char right_speed)
{
OCR1A = left_speed;
OCR1B = right_speed;
}

inline void MotorDir (unsigned char left_dir, unsigned char right_dir)
{
PORTD = (PORTD &~ ((1 << PD4) | (1 << PD5))) | left_dir;
PORTB = (PORTB &~ ((1 << PB4) | (1 << PB5))) | right_dir;
}
Jetzt die Frage:
Woher kennt der Compiler die Definition der Variablen OCR1A, OCR1B, PORTB, PORTD, PB4, PB5, PD4, PD5 ? Ich habe in den Files der Lib 2.70 gesucht aber nirgends etwas gefunden.

plusminus
13.05.2007, 13:59
AVR Studio --> External-Dependencies --> "iom???.h" --> "iomxx0_1.h"

uwegw
13.05.2007, 14:04
Diese Definitionen werden mit dem Compiler geliefert und liegen daher in dessen Verzeichnis.

HermannSW
13.05.2007, 14:15
Hi,
...
Jetzt die Frage:
Woher kennt der Compiler die Definition der Variablen OCR1A, OCR1B, PORTB, PORTD, PB4, PB5, PD4, PD5 ? Ich habe in den Files der Lib 2.70 gesucht aber nirgends etwas gefunden.bei mir ist <WinAVR_ROOT> = c:\WinAVR.

In asuro.h:
...
#define ASURO_H

#include <avr/io.h>
...

In <WinAVR_ROOT>\avr\include\avr\io.h:
...
#elif defined (__AVR_ATmega8__)
# include <avr/iom8.h>
...

Und in <WinAVR_ROOT>\avr\include\avr\iom8.h findest Du ALLES ... :)

HermannSW
13.05.2007, 14:20
... und das Define __AVR_ATmega8__ kommt (irgendwie magic) aus dem mcu = atmega8 im Makefile.

ehenkes
13.05.2007, 16:10
Klasse Spurensuche! Jetzt fehlen mir nur noch diese ...

_SFR_IO16
_SFR_IO8

z. B. aus
#define OCR1A _SFR_IO16(0x2A)
#define OCR1B _SFR_IO16(0x28)
#define PORTB _SFR_IO8(0x18)
#define PORTD _SFR_IO8(0x12)

... dann wäre die Kette komplett.

ehenkes
13.05.2007, 16:15
Ich habe es via google gefunden: in sfr_defs.h


#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
#define _SFR_IO16(io_addr) ((io_addr) + __SFR_OFFSET)

#ifndef __SFR_OFFSET
/* Define as 0 before including this file for compatibility with old asm
sources that don't subtract __SFR_OFFSET from symbolic I/O addresses. */
#define __SFR_OFFSET 0x20
#endif


Kann dies bitte jemand erläutern? Wann muss ich __SFR_OFFSET als 0 setzen anstelle 0x20?

uwegw
13.05.2007, 17:08
Das hängt mit der internen Architektur des AVRs zusammen. Es gibt zwei Methoden, die Hardware-Konfigurations-Register (SFRs) anzusprechen, und deswegen hat jedes SFR auch zwei Adressen. Schau dir mal in Datenbaltt die Registerübersicht an. Für PORTB steht dort z:b. 0x18 (0x38). Beide Adressen bezeichnen dasselbe Register, aber unter Verwendung der beiden Zugriffsmethoden:
die erste ist direkter Zugiff auf die Register mit speziellen Befehlen (IN/OUT). Dabei wird kein Offset benötigt. DIe Adresse von PORTB ist hier also 0x18. Mit "OUT 0x18, r16" wird daher der Inhalt von Register 16 auf PORTB ausgegeben.

Als zweite Möglichkeit werden die Register quasi ins RAM gespiegelt, haben also jedes eine eigene Speicheradresse. Da in den ersten 32 Bytes des RAMs aber schon die Multifunktionsregister leigen, fangen die SFRs erst bei 0x0020 an. Der eigentliche RAM beginnt übrigens erst bei 0x0060, weil davor halt die SFRs liegen.
"STS 0x38, r16" würde wiederum Register 16 auf PORTB ausgeben.

EDIT: stimmt wohl doch nicht!
Der C-Compiler bevorzugt grundsätzlich die zweite Methode und braucht daher den Offset.

Ich hoffe das war korrekt so, hab lange kein ASM mehr geschrieben (da muss man sowas mitunter beachten. Wenn du also neugierig bist, wie der AVR wirklich funktioniert, solltest du dich etwas mit ASM beschäftigen).

ehenkes
13.05.2007, 17:29
Danke, das ist sehr verständlich erklärt. Jetzt bleibt nur noch die offene Frage: Warum verwendet der C-Compiler die Methode via RAM? ... oder anders gefragt: kann ich den C-Compiler zwingen, direkt auf die Register (ohne Spiegelung ins RAM) zuzugreifen?

uwegw
13.05.2007, 17:45
Da hab ich wohl falsch vermutet. Hab mir grad mal nen .hex disassembliert. Es wird doch IN/OUT verwendet.

Es gibt aber bei den größeren AVRs mit vielen Funktionen auch SFRs, die sich nur als RAM ansprechen lassen. Dafür wird der Offset auf jeden Fall benötigt.

ehenkes
13.05.2007, 18:06
Wenn ich das richtig verstanden habe, sind wir jetzt beim Innenleben des Compilers angelangt. Er kann quasi entscheiden, ob er IN/OUT verwendet oder mit OFFSET 0x20 ins RAM schreibt?

linux_80
13.05.2007, 18:24
Hallo,
ob der Compiler IN/OUT oder STS erzeugt hängt auch von der Optimierung (-Ox) ab.

ehenkes
13.05.2007, 18:48
Hier ist ein interessanter Link zu dem Thema "out" oder "sts":
http://www.mikrocontroller.net/topic/8279

HermannSW
13.05.2007, 20:31
Wenn ich das richtig verstanden habe, sind wir jetzt beim Innenleben des Compilers angelangt. ...Wenn Du mehr über das Innenleben wissen willst, dann schau doch einfach in die .lss-files!

Bei den examples heißen die C-Programme meist test.c, dort wird immer auch eine Datei test.lss erzeugt, eine (einfache) Textdatei, in der abwechselnd die C-statements und die Umsetzung in Assembler zu sehen sind -- SEHR INTERESSANT!

ehenkes
13.05.2007, 21:02
Das ist ja wirklich interessant. Danke!!

inka
14.05.2007, 04:49
wieso finde ich die *.lss files nicht bei mir? Sind die nicht im projektverzeichnis, oder werden sie beim avr-studio nicht erzeugt?

ehenkes
14.05.2007, 05:22
WinAVR erzeugt diese Files. Hier ein Beispiel von First Try:

Zunächst die C-Datei:

#include "asuro.h"

int main ()
{
Init ();
while (1);
return 0; //wird nicht erreicht
}

... und hier die lss-Datei:


test.elf: file format elf32-avr

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000028a 00000000 00000000 00000074 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .bss 00000012 00800060 00800060 000002fe 2**0
ALLOC
2 .stab 0000036c 00000000 00000000 00000300 2**2
CONTENTS, READONLY, DEBUGGING
3 .stabstr 00000084 00000000 00000000 0000066c 2**0
CONTENTS, READONLY, DEBUGGING
4 .debug_aranges 00000068 00000000 00000000 000006f0 2**0
CONTENTS, READONLY, DEBUGGING
5 .debug_pubnames 00000121 00000000 00000000 00000758 2**0
CONTENTS, READONLY, DEBUGGING
6 .debug_info 0000043c 00000000 00000000 00000879 2**0
CONTENTS, READONLY, DEBUGGING
7 .debug_abbrev 0000020a 00000000 00000000 00000cb5 2**0
CONTENTS, READONLY, DEBUGGING
8 .debug_line 0000058b 00000000 00000000 00000ebf 2**0
CONTENTS, READONLY, DEBUGGING
9 .debug_frame 00000070 00000000 00000000 0000144a 2**0
CONTENTS, READONLY, DEBUGGING
10 .debug_str 000001b5 00000000 00000000 000014ba 2**0
CONTENTS, READONLY, DEBUGGING
Disassembly of section .text:

00000000 <__vectors>:
0: 12 c0 rjmp .+36 ; 0x26 <__ctors_end>
2: 2b c0 rjmp .+86 ; 0x5a <__bad_interrupt>
4: 5e c0 rjmp .+188 ; 0xc2 <__vector_2>
6: 29 c0 rjmp .+82 ; 0x5a <__bad_interrupt>
8: 2b c0 rjmp .+86 ; 0x60 <__vector_4>
a: 27 c0 rjmp .+78 ; 0x5a <__bad_interrupt>
c: 26 c0 rjmp .+76 ; 0x5a <__bad_interrupt>
e: 25 c0 rjmp .+74 ; 0x5a <__bad_interrupt>
10: 24 c0 rjmp .+72 ; 0x5a <__bad_interrupt>
12: 23 c0 rjmp .+70 ; 0x5a <__bad_interrupt>
14: 22 c0 rjmp .+68 ; 0x5a <__bad_interrupt>
16: 21 c0 rjmp .+66 ; 0x5a <__bad_interrupt>
18: 20 c0 rjmp .+64 ; 0x5a <__bad_interrupt>
1a: 1f c0 rjmp .+62 ; 0x5a <__bad_interrupt>
1c: 69 c0 rjmp .+210 ; 0xf0 <__vector_14>
1e: 1d c0 rjmp .+58 ; 0x5a <__bad_interrupt>
20: 1c c0 rjmp .+56 ; 0x5a <__bad_interrupt>
22: 1b c0 rjmp .+54 ; 0x5a <__bad_interrupt>
24: 1a c0 rjmp .+52 ; 0x5a <__bad_interrupt>

00000026 <__ctors_end>:
26: 11 24 eor r1, r1
28: 1f be out 0x3f, r1 ; 63
2a: cf e5 ldi r28, 0x5F ; 95
2c: d4 e0 ldi r29, 0x04 ; 4
2e: de bf out 0x3e, r29 ; 62
30: cd bf out 0x3d, r28 ; 61

00000032 <__do_copy_data>:
32: 10 e0 ldi r17, 0x00 ; 0
34: a0 e6 ldi r26, 0x60 ; 96
36: b0 e0 ldi r27, 0x00 ; 0
38: ea e8 ldi r30, 0x8A ; 138
3a: f2 e0 ldi r31, 0x02 ; 2
3c: 02 c0 rjmp .+4 ; 0x42 <.do_copy_data_start>

0000003e <.do_copy_data_loop>:
3e: 05 90 lpm r0, Z+
40: 0d 92 st X+, r0

00000042 <.do_copy_data_start>:
42: a0 36 cpi r26, 0x60 ; 96
44: b1 07 cpc r27, r17
46: d9 f7 brne .-10 ; 0x3e <.do_copy_data_loop>

00000048 <__do_clear_bss>:
48: 10 e0 ldi r17, 0x00 ; 0
4a: a0 e6 ldi r26, 0x60 ; 96
4c: b0 e0 ldi r27, 0x00 ; 0
4e: 01 c0 rjmp .+2 ; 0x52 <.do_clear_bss_start>

00000050 <.do_clear_bss_loop>:
50: 1d 92 st X+, r1

00000052 <.do_clear_bss_start>:
52: a2 37 cpi r26, 0x72 ; 114
54: b1 07 cpc r27, r17
56: e1 f7 brne .-8 ; 0x50 <.do_clear_bss_loop>
58: 01 c0 rjmp .+2 ; 0x5c <main>

0000005a <__bad_interrupt>:
5a: d2 cf rjmp .-92 ; 0x0 <__vectors>

0000005c <main>:

#include "asuro.h"

int main(void)
{
5c: a6 d0 rcall .+332 ; 0x1aa <Init>
5e: ff cf rjmp .-2 ; 0x5e <main+0x2>

00000060 <__vector_4>:
\par Beispiel:
(Nicht vorhanden)
************************************************** ***************************/
SIGNAL (SIG_OVERFLOW2)
{
60: 1f 92 push r1
62: 0f 92 push r0
64: 0f b6 in r0, 0x3f ; 63
66: 0f 92 push r0
68: 11 24 eor r1, r1
6a: 8f 93 push r24
6c: 9f 93 push r25
6e: af 93 push r26
70: bf 93 push r27
TCNT2 += 0x25;
72: 84 b5 in r24, 0x24 ; 36
74: 8b 5d subi r24, 0xDB ; 219
76: 84 bd out 0x24, r24 ; 36
count36kHz ++;
78: 80 91 6d 00 lds r24, 0x006D
7c: 8f 5f subi r24, 0xFF ; 255
7e: 80 93 6d 00 sts 0x006D, r24
if (!count36kHz)
82: 80 91 6d 00 lds r24, 0x006D
86: 88 23 and r24, r24
88: 99 f4 brne .+38 ; 0xb0 <__vector_4+0x50>
timebase ++;
8a: 80 91 6e 00 lds r24, 0x006E
8e: 90 91 6f 00 lds r25, 0x006F
92: a0 91 70 00 lds r26, 0x0070
96: b0 91 71 00 lds r27, 0x0071
9a: 01 96 adiw r24, 0x01 ; 1
9c: a1 1d adc r26, r1
9e: b1 1d adc r27, r1
a0: 80 93 6e 00 sts 0x006E, r24
a4: 90 93 6f 00 sts 0x006F, r25
a8: a0 93 70 00 sts 0x0070, r26
ac: b0 93 71 00 sts 0x0071, r27
b0: bf 91 pop r27
b2: af 91 pop r26
b4: 9f 91 pop r25
b6: 8f 91 pop r24
b8: 0f 90 pop r0
ba: 0f be out 0x3f, r0 ; 63
bc: 0f 90 pop r0
be: 1f 90 pop r1
c0: 18 95 reti

000000c2 <__vector_2>:
#ifdef RC5_AVAILABLE
if (enableRC5 && !(count36kHz % 8))
IsrRC5(); // wird alle 222.2us aufgerufen
#endif
}



/************************************************** **************************/
/*
\brief
Interrupt-Funktion fuer den externen Interrupt 1.

\param
keine

\return
nichts

\see switched

\par
Hier wird 'nur' in der globalen Variablen switched vermerkt, dass ein\n
Switch (Taster) gedrueckt wurde und dieser Interrupt soeben aufgetreten ist.\n
Damit dieser Interrupt aber nicht permanent aufgerufen wird, solange der\n
Taster gedrueckt bleibt, wird die Funktion, dass ein Interrupt erzeugt wird,\n
ueber StopSwitch() abgeschaltet.\n
Nach einer Bearbeitung im eigenen Hauptprogramm, muss also die Funktion\n
StartSwitch() wieder Aufgerufen werden, um einen Tastendruck wieder ueber\n
einen Interrupt zu erkennen.

\par Beispiel:
(Nicht vorhanden)
************************************************** ***************************/
SIGNAL (SIG_INTERRUPT1)
{
c2: 1f 92 push r1
c4: 0f 92 push r0
c6: 0f b6 in r0, 0x3f ; 63
c8: 0f 92 push r0
ca: 11 24 eor r1, r1
cc: 8f 93 push r24
ce: 9f 93 push r25
switched = 1;
d0: 81 e0 ldi r24, 0x01 ; 1
d2: 90 e0 ldi r25, 0x00 ; 0
d4: 90 93 66 00 sts 0x0066, r25
d8: 80 93 65 00 sts 0x0065, r24
GICR &= ~(1 << INT1); // Externen Interrupt 1 sperren
dc: 8b b7 in r24, 0x3b ; 59
de: 8f 77 andi r24, 0x7F ; 127
e0: 8b bf out 0x3b, r24 ; 59
e2: 9f 91 pop r25
e4: 8f 91 pop r24
e6: 0f 90 pop r0
e8: 0f be out 0x3f, r0 ; 63
ea: 0f 90 pop r0
ec: 1f 90 pop r1
ee: 18 95 reti

000000f0 <__vector_14>:
// StopSwitch ();
}



/************************************************** **************************/
/*
\brief
Interrupt-Funktion fuer den AD-Wandler. Kann ueber autoencode gesteuert\n
die Odometrie-Zaehler in encoder hochzaehlen.

\param
keine

\return
nichts

\see
Die globale Variable autoencode wird hier ausgewertet. Ist sie nicht FALSE,\n
dann wird der AD-Wandler-Wert zum Zaehlen der Odometriewerte in der globalen\n
Variablen encoder benutzt.\n
Es wird auch der AD-Wandler-Kanal auf die 'andere' Seite der Odometrie\n
umgeschaltete und der AD-Wandler neu gestartet.\n
Somit wird erreicht, dass zumindest die Odometriemessung automatisch erfolgt.

\par Beispiel:
(Nicht vorhanden)
************************************************** ***************************/
SIGNAL (SIG_ADC)
{
f0: 1f 92 push r1
f2: 0f 92 push r0
f4: 0f b6 in r0, 0x3f ; 63
f6: 0f 92 push r0
f8: 11 24 eor r1, r1
fa: 2f 93 push r18
fc: 3f 93 push r19
fe: 4f 93 push r20
100: 8f 93 push r24
102: 9f 93 push r25
104: af 93 push r26
106: bf 93 push r27
108: ef 93 push r30
10a: ff 93 push r31
static unsigned char tmp [2], flag [2], toggle = FALSE;
unsigned char dval, lval;

if (autoencode)
10c: 80 91 67 00 lds r24, 0x0067
110: 90 91 68 00 lds r25, 0x0068
114: 89 2b or r24, r25
116: d9 f1 breq .+118 ; 0x18e <__vector_14+0x9e>
{
tmp [toggle] = ADCH;
118: 40 91 60 00 lds r20, 0x0060
11c: 24 2f mov r18, r20
11e: 33 27 eor r19, r19
120: 95 b1 in r25, 0x05 ; 5
122: f9 01 movw r30, r18
124: ed 59 subi r30, 0x9D ; 157
126: ff 4f sbci r31, 0xFF ; 255
128: 90 83 st Z, r25
if (toggle)
12a: 44 23 and r20, r20
12c: 11 f0 breq .+4 ; 0x132 <__vector_14+0x42>
{
ADMUX = (1 << ADLAR) | (1 << REFS0) | WHEEL_RIGHT;
12e: 80 e6 ldi r24, 0x60 ; 96
130: 01 c0 rjmp .+2 ; 0x134 <__vector_14+0x44>
dval = MY_ODO_DARK_VALUE_R;
lval = MY_ODO_LIGHT_VALUE_R;
}
else
{
ADMUX = (1 << ADLAR) | (1 << REFS0) | WHEEL_LEFT;
132: 81 e6 ldi r24, 0x61 ; 97
134: 87 b9 out 0x07, r24 ; 7
dval = MY_ODO_DARK_VALUE_L;
lval = MY_ODO_LIGHT_VALUE_L;
}

if ((tmp [toggle] < dval) && (flag[toggle] == TRUE))
136: 9c 38 cpi r25, 0x8C ; 140
138: 90 f4 brcc .+36 ; 0x15e <__vector_14+0x6e>
13a: d9 01 movw r26, r18
13c: af 59 subi r26, 0x9F ; 159
13e: bf 4f sbci r27, 0xFF ; 255
140: 8c 91 ld r24, X
142: 81 30 cpi r24, 0x01 ; 1
144: 01 f5 brne .+64 ; 0x186 <__vector_14+0x96>
{
encoder [toggle] ++;
146: f9 01 movw r30, r18
148: ee 0f add r30, r30
14a: ff 1f adc r31, r31
14c: e7 59 subi r30, 0x97 ; 151
14e: ff 4f sbci r31, 0xFF ; 255
150: 80 81 ld r24, Z
152: 91 81 ldd r25, Z+1 ; 0x01
154: 01 96 adiw r24, 0x01 ; 1
156: 91 83 std Z+1, r25 ; 0x01
158: 80 83 st Z, r24
flag [toggle] = FALSE;
15a: 1c 92 st X, r1
15c: 14 c0 rjmp .+40 ; 0x186 <__vector_14+0x96>
}
if ((tmp [toggle] > lval) && (flag [toggle] == FALSE))
15e: 91 3a cpi r25, 0xA1 ; 161
160: 90 f0 brcs .+36 ; 0x186 <__vector_14+0x96>
162: d9 01 movw r26, r18
164: af 59 subi r26, 0x9F ; 159
166: bf 4f sbci r27, 0xFF ; 255
168: 8c 91 ld r24, X
16a: 88 23 and r24, r24
16c: 61 f4 brne .+24 ; 0x186 <__vector_14+0x96>
{
encoder [toggle] ++;
16e: f9 01 movw r30, r18
170: ee 0f add r30, r30
172: ff 1f adc r31, r31
174: e7 59 subi r30, 0x97 ; 151
176: ff 4f sbci r31, 0xFF ; 255
178: 80 81 ld r24, Z
17a: 91 81 ldd r25, Z+1 ; 0x01
17c: 01 96 adiw r24, 0x01 ; 1
17e: 91 83 std Z+1, r25 ; 0x01
180: 80 83 st Z, r24
flag [toggle] = TRUE;
182: 81 e0 ldi r24, 0x01 ; 1
184: 8c 93 st X, r24
}
toggle ^= 1;
186: 81 e0 ldi r24, 0x01 ; 1
188: 48 27 eor r20, r24
18a: 40 93 60 00 sts 0x0060, r20
18e: ff 91 pop r31
190: ef 91 pop r30
192: bf 91 pop r27
194: af 91 pop r26
196: 9f 91 pop r25
198: 8f 91 pop r24
19a: 4f 91 pop r20
19c: 3f 91 pop r19
19e: 2f 91 pop r18
1a0: 0f 90 pop r0
1a2: 0f be out 0x3f, r0 ; 63
1a4: 0f 90 pop r0
1a6: 1f 90 pop r1
1a8: 18 95 reti

000001aa <Init>:
1aa: 89 e7 ldi r24, 0x79 ; 121
1ac: 85 bd out 0x25, r24 ; 37
1ae: 81 e9 ldi r24, 0x91 ; 145
1b0: 83 bd out 0x23, r24 ; 35
1b2: 89 b7 in r24, 0x39 ; 57
1b4: 80 64 ori r24, 0x40 ; 64
1b6: 89 bf out 0x39, r24 ; 57
1b8: 1b b8 out 0x0b, r1 ; 11
1ba: 1a b8 out 0x0a, r1 ; 10
1bc: 96 e8 ldi r25, 0x86 ; 134
1be: 90 bd out 0x20, r25 ; 32
1c0: 8f ec ldi r24, 0xCF ; 207
1c2: 89 b9 out 0x09, r24 ; 9
1c4: 8f e3 ldi r24, 0x3F ; 63
1c6: 87 bb out 0x17, r24 ; 23
1c8: 84 ef ldi r24, 0xF4 ; 244
1ca: 81 bb out 0x11, r24 ; 17
1cc: 81 ea ldi r24, 0xA1 ; 161
1ce: 8f bd out 0x2f, r24 ; 47
1d0: 82 e0 ldi r24, 0x02 ; 2
1d2: 8e bd out 0x2e, r24 ; 46
1d4: 96 b9 out 0x06, r25 ; 6
1d6: 97 98 cbi 0x12, 7 ; 18
1d8: 80 e0 ldi r24, 0x00 ; 0
1da: 27 d0 rcall .+78 ; 0x22a <FrontLED>
1dc: 61 e0 ldi r22, 0x01 ; 1
1de: 81 e0 ldi r24, 0x01 ; 1
1e0: 2f d0 rcall .+94 ; 0x240 <BackLED>
1e2: 60 e0 ldi r22, 0x00 ; 0
1e4: 80 e0 ldi r24, 0x00 ; 0
1e6: 2c d0 rcall .+88 ; 0x240 <BackLED>
1e8: 81 e0 ldi r24, 0x01 ; 1
1ea: 0c d0 rcall .+24 ; 0x204 <StatusLED>
1ec: 60 e2 ldi r22, 0x20 ; 32
1ee: 80 e2 ldi r24, 0x20 ; 32
1f0: 43 d0 rcall .+134 ; 0x278 <MotorDir>
1f2: 60 e0 ldi r22, 0x00 ; 0
1f4: 80 e0 ldi r24, 0x00 ; 0
1f6: 37 d0 rcall .+110 ; 0x266 <MotorSpeed>
1f8: 10 92 68 00 sts 0x0068, r1
1fc: 10 92 67 00 sts 0x0067, r1
200: 78 94 sei
202: 08 95 ret

00000204 <StatusLED>:
204: 88 23 and r24, r24
206: 11 f4 brne .+4 ; 0x20c <StatusLED+0x8>
208: c0 98 cbi 0x18, 0 ; 24
20a: 03 c0 rjmp .+6 ; 0x212 <StatusLED+0xe>
20c: 81 30 cpi r24, 0x01 ; 1
20e: 19 f4 brne .+6 ; 0x216 <StatusLED+0x12>
210: c0 9a sbi 0x18, 0 ; 24
212: 92 98 cbi 0x12, 2 ; 18
214: 08 95 ret
216: 83 30 cpi r24, 0x03 ; 3
218: 19 f4 brne .+6 ; 0x220 <StatusLED+0x1c>
21a: c0 9a sbi 0x18, 0 ; 24
21c: 92 9a sbi 0x12, 2 ; 18
21e: 08 95 ret
220: 82 30 cpi r24, 0x02 ; 2
222: 11 f4 brne .+4 ; 0x228 <StatusLED+0x24>
224: c0 98 cbi 0x18, 0 ; 24
226: 92 9a sbi 0x12, 2 ; 18
228: 08 95 ret

0000022a <FrontLED>:
22a: 22 b3 in r18, 0x12 ; 18
22c: 2f 7b andi r18, 0xBF ; 191
22e: 99 27 eor r25, r25
230: 36 e0 ldi r19, 0x06 ; 6
232: 88 0f add r24, r24
234: 99 1f adc r25, r25
236: 3a 95 dec r19
238: e1 f7 brne .-8 ; 0x232 <FrontLED+0x8>
23a: 28 2b or r18, r24
23c: 22 bb out 0x12, r18 ; 18
23e: 08 95 ret

00000240 <BackLED>:
240: 98 2f mov r25, r24
242: 88 23 and r24, r24
244: 11 f4 brne .+4 ; 0x24a <BackLED+0xa>
246: 66 23 and r22, r22
248: 49 f0 breq .+18 ; 0x25c <BackLED+0x1c>
24a: 97 98 cbi 0x12, 7 ; 18
24c: 84 b3 in r24, 0x14 ; 20
24e: 83 60 ori r24, 0x03 ; 3
250: 84 bb out 0x14, r24 ; 20
252: 85 b3 in r24, 0x15 ; 21
254: 83 60 ori r24, 0x03 ; 3
256: 85 bb out 0x15, r24 ; 21
258: 99 23 and r25, r25
25a: 09 f4 brne .+2 ; 0x25e <BackLED+0x1e>
25c: a9 98 cbi 0x15, 1 ; 21
25e: 66 23 and r22, r22
260: 09 f4 brne .+2 ; 0x264 <BackLED+0x24>
262: a8 98 cbi 0x15, 0 ; 21
264: 08 95 ret

00000266 <MotorSpeed>:
266: 28 2f mov r18, r24
268: 33 27 eor r19, r19
26a: 3b bd out 0x2b, r19 ; 43
26c: 2a bd out 0x2a, r18 ; 42
26e: 86 2f mov r24, r22
270: 99 27 eor r25, r25
272: 99 bd out 0x29, r25 ; 41
274: 88 bd out 0x28, r24 ; 40
276: 08 95 ret

00000278 <MotorDir>:
278: 22 b3 in r18, 0x12 ; 18
27a: 2f 7c andi r18, 0xCF ; 207
27c: 28 2b or r18, r24
27e: 22 bb out 0x12, r18 ; 18
280: 88 b3 in r24, 0x18 ; 24
282: 8f 7c andi r24, 0xCF ; 207
284: 86 2b or r24, r22
286: 88 bb out 0x18, r24 ; 24
288: 08 95 ret

Wirklich interessant!

Im make-File findet sich dieser Abschnitt:

# Create extended listing file from ELF output file.
%.lss: %.elf
$(OBJDUMP) -h -S $< > $@

damaltor
14.05.2007, 09:39
die datei ist erst mach dem compilieren vorhanden (avr-gcc)

linux_80
14.05.2007, 19:54
Hallo,

und das auch nur, wenn man das im Makefile einrichtet, oder im AVRStudio ankreuzt (Generate List File).

Wenn man dann noch -ffreestanding bei den Custom Options mit hinzufügt, kann man sich das return am Ende von main() auch sparen, bzw. der Compiler schimpft nicht, wenn man ein void main() angibt !