Fehler: Konstanter Wert beim Kompilieren mit avr-as in Linux erforderlich

Ich versuche, das folgende einfache Assemblerprogramm zu kompilieren, aber es gibt ein Problem mit dem Compiler, dass ich seinen Grund nicht finden und beheben kann.

Also hier ist der Code:

  1 #define __SFR_OFFSET 0 
  2 #include <avr/io.h> 
  3 
  4 
  5 rjmp Init 
  6 
  7 .global Init 
  8 
  9 Init:   sbi _SFR_IO_ADDR(PORTB),5 
 10         rjmp In

und wann ich es mit kompilieren werde
avr-as -c -mmcu=atmega168a -o ledON.o ledON.s

Ich bekomme diesen Fehler:

ledON.s: Assembler messages:  
ledON.s:9: Error: constant value required
ledON.s:9: Error: `,' required  
ledON.s:9: Error: constant value required
ledON.s:9: Error: garbage at end of line

Ich habe auch den Code ein wenig geändert, wie Sie oben sehen können, aber es gibt immer noch einen Fehler

  1 ;#define _SFR_OFFSET 0 
  2 #include <avr/io.h> 
  3 
  4 rjmp Init
  5 
  6 .global Init
  7 
  8 Init:   sbi PORTB,0x05
  9         rjmp Init

ledON.s: Assembler-Meldungen:

ledON.s:8: Fehler: konstanter Wert erforderlich

Irgendwelche Ideen?

Welche Version avr-asverwenden Sie, meine unterstützt das -cFlag nicht, was macht es?
Auch ohne -cFlag bekomme ich den gleichen Fehler :s
Offensichtlich werden die Include-Dateien überhaupt nicht verarbeitet, jetzt nur um herauszufinden, woran das liegt.
Und wo kann man suchen, um das festzustellen? Können Sie mir einen Hinweis geben?
Ich habe ein bisschen experimentiert und die Include-Dateien werden eindeutig nicht verarbeitet. Es hat damit zu tun, dass as den C-Präprozessor nicht aufruft, aber ich weiß nicht, wie ich die Verarbeitung der Dateien erzwingen kann

Antworten (1)

Ich habe herausgefunden, wie man ohne Fehlermeldungen zusammenbaut.

Die angezeigten Fehlermeldungen werden dadurch verursacht, dass der C-Präprozessor nichtavr-as aufgerufen wird und die Zeilen daher als normale Kommentare gelesen werden.#include

Erstellen Sie eine Datei ledON.Sund achten Sie auf das GROSSBUCHSTABEN Sim Dateinamen. Der Großbuchstabe Szeigt an, dass der C-Präprozessor zuerst aufgerufen werden muss. Erstellen Sie die Datei mit folgendem Inhalt:

#include <avr/io.h> 

init:   sbi     _SFR_IO_ADDR(DDRB),0x05         ; Configure port B pin 5 as output
        ret

.global main

main:
        call init

loop:
        sbi     _SFR_IO_ADDR(PORTB),0x05        ; Toggle output pin HIGH
        cbi     _SFR_IO_ADDR(PORTB),0x05        ; Toggle output pin LOW
        rjmp loop

Der mainTeil wird im Quellcode benötigt, dort befindet sich normalerweise das Hauptprogramm. Wenn Sie es entfernen, wird niemals richtiger Code ausgeführt und der Compiler wird sich darüber beschweren. Code in einer aufgerufenen Routine initsollte explizit von aufgerufen werden main. Obwohl der Stift umschaltet, ist dies in der Praxis zu schnell, um es mit bloßem Auge zu sehen. Wenn Sie mit einem Oszilloskop überprüfen, sehen Sie eine Rechteckwelle (ich schätze auf 25% Arbeitszyklus).

Dann assemblieren Sie den Quellcode mit:

avr-gcc -mmcu=atmega168a ledON.S -o ledON.o

Wiederum avr-gccist es erforderlich, den C-Präprozessor aufzurufen.

Um das Ergebnis des zusammengestellten Programms zu überprüfen, führen Sie den folgenden Befehl aus:

avr-objdump -C -d ./ledON.o

Und die resultierende Disassemblierungsliste sieht so aus:

./ledON.o:     file format elf32-avr


Disassembly of section .text:

00000000 <__vectors>:
   0:   0c 94 34 00     jmp     0x68    ; 0x68 <__ctors_end>
   4:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
   8:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
   c:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  10:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  14:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  18:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  1c:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  20:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  24:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  28:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  2c:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  30:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  34:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  38:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  3c:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  40:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  44:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  48:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  4c:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  50:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  54:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  58:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  5c:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  60:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  64:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>

00000068 <__ctors_end>:
  68:   11 24           eor     r1, r1
  6a:   1f be           out     0x3f, r1        ; 63
  6c:   cf ef           ldi     r28, 0xFF       ; 255
  6e:   d4 e0           ldi     r29, 0x04       ; 4
  70:   de bf           out     0x3e, r29       ; 62
  72:   cd bf           out     0x3d, r28       ; 61
  74:   0e 94 42 00     call    0x84    ; 0x84 <main>
  78:   0c 94 47 00     jmp     0x8e    ; 0x8e <_exit>

0000007c <__bad_interrupt>:
  7c:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>

00000080 <init>:
  80:   25 9a           sbi     0x04, 5 ; 4
  82:   08 95           ret

00000084 <main>:
  84:   0e 94 40 00     call    0x80    ; 0x80 <init>

00000088 <loop>:
  88:   2d 9a           sbi     0x05, 5 ; 5
  8a:   2d 98           cbi     0x05, 5 ; 5
  8c:   fd cf           rjmp    .-6             ; 0x88 <loop>

0000008e <_exit>:
  8e:   f8 94           cli

00000090 <__stop_program>:
  90:   ff cf           rjmp    .-2             ; 0x90 <__stop_program>

INTERMEZZO

Sie werden feststellen, dass der Assembler automatisch den Stapelzeiger und das Statusregister in initialisiert __ctors_end. Außerdem wird rjmpam Ende des Codes automatisch ein hinzugefügt. Das Standardverhalten eines von gcc-avr zusammengestellten Programms beim Beenden ist:

  • Unterbrechungen ausschalten ( _exit, cli)
  • endlose leere Schleife, die nichts tut ( __stop_program, rjmp .-2)
Ja. Ich habe das .S bereits ausprobiert, aber es gibt mir wieder einen Fehler zurück und es erstellt keine Objektdatei. ledON.S: Assembler messages: ledON.S:8: Error: number must be positive and less than 32Solche Fehler bedeuten meiner Meinung nach, dass das I/O-Register nicht editierbar ist.
Kopieren Sie die genaue Quelle wie in meiner Antwort und arbeiten Sie von dort aus. Meine vorgeschlagene Quelle baut auf meinem System auf, sonst könnte ich Ihnen die Disassemblierungsliste nicht zeigen.
OK. Die Objektdatei wird jetzt erstellt, aber warum passiert das alles? Ich kann es nicht verstehen. Auch in Ihrem Code wird der rjmp to main niemals ausgeführt, da sich oben die Endlosschleife von init befindet. Übrigens kann ich nicht upvoten, weil ich ein neuer Benutzer bin und keinen Ruf habe.
Fair genug, ich entfernte die letzte rjmp. Das mainEtikett ist ein erforderlicher Bestandteil des Programms, wenn Sie es entfernen, erhalten Sie eine Fehlermeldung. Normalerweise befindet sich dort das Hauptprogramm.
@FN Ich habe die Antwort aktualisiert, um einen etwas nützlichen Proof of Concept widerzuspiegeln.
Ja, ich habe es gesehen. Ich habe es kompiliert, gelinkt und getestet. Led hat funktioniert. Vielen Dank. Das Problem liegt also im Assembler, aber glauben Sie, dass es eine Möglichkeit gibt, es zu beheben, oder nicht?
Laut Dokumentation funktioniert das so. Sie möchten, dass der C-Präprozessor aufgerufen wird, dann rufen Sie gcc auf.
aber dieser Typ hier? wie hat er es mit avr-as zum laufen gebracht? avr-wie
@FN Weiß nicht. Seit dem 8. April 2008 haben sich die Dinge jedoch geändert. Die Toolchain hat völlig unterschiedliche Hauptversionen (die erste Ziffer der Versionsnummer). Unter Wasser avr-gccruft avr-asnach dir.
@FN Beachten Sie auch, dass dieses Beispiel nicht die Einbeziehung der C-Header-Dateien erfordert.
Ja ich habe es verstanden. Ohnehin. Ich werde einige andere Dinge ausprobieren und wenn ich etwas finde, werde ich Sie informieren :) Nochmals vielen Dank.