Forum: Compiler & IDEs LGT8F328P avr, gcc, Timer3-Vect


von Harald P. (haraldp)


Angehängte Dateien:

Lesenswert?

Ich teste gerade den weitgehend zum Mega328 kompatiblen Baustein 
LGT8F328P. Die im Originalbaustein (Mega328) enthaltenen Funktionen 
funktionieren - bis auf wenige Ausnahmen, wie z.B. SPI, auch beim 
LGT8F328P. Jedoch enthält er z.B. einen zusätzlichen Timer 3, der auch 
mit den in lgtx8p.h deklarierten Adressen ansprechbar ist. Nicht jedoch 
funktioniert der Timer3_vect(29). Statt dessen wird der bad-interrupt 
angesprungen.
Im beigefügten Minimalprogramm kann man in TestLGT.lss sehen, dass kein 
entsprechendr Interrupt-Vektor hinterlegt ist. Die Tabelle hört bei (25) 
auf, obwohl in lgtx8p.h
#define _VECTORS_SIZE (30 * 4)
hinterlegt ist.
Ich habe zum Test auch schon mal die Datei iom328p.h angepasst, jedoch 
ohne Erfolg. Irgeendwo muss die _VECTORS_SIZE mit (26*4) fest hinterlegt 
sein.
Wie bekomme ich also den Interrupteinsprung (29) hinterlegt.
Das Beispielprogramm ist mit Avr-Studio 4 erstellt.
Harald

von Achim M. (minifloat)


Lesenswert?

Harald P. schrieb:
> Das Beispielprogramm ist mit Avr-Studio 4 erstellt.

Also werden sonst die Header vom Mega328 benutzt? Dann ist es da 
festgelegt. Entweder damit als copy-Template einen eigenen Prozessortyp 
sauber anlegen oder den Vektor mit inline-Assembler mit org und dc.w (?) 
händisch in den Speicher einhängen. Mit Linkerfile ginge sogar, die 
ganze Vektortabelle selbst in C-code zu definieren und den Linker am 
passender Stelle ins hex reinstempeln lassen. Gibt sicher noch andere 
Methoden...

mfg mf

von Harald P. (haraldp)


Lesenswert?

Achim M. schrieb:
> Also werden sonst die Header vom Mega328 benutzt?

Ja, die die iom328p.h wird includiert. Aber selbst eine modifizierte 
iom328p.h mit den Headern für LGT8 führt nicht zum gewüschten Erfolg. 
Irgendwo wird noch die  _VECTORS_SIZE auf Mega328 begrenzt.
Harald

von Oliver S. (oliverso)


Lesenswert?

Harald P. schrieb:
> Nicht jedoch
> funktioniert der Timer3_vect(29). Statt dessen wird der bad-interrupt
> angesprungen.
> Im beigefügten Minimalprogramm kann man in TestLGT.lss sehen, dass kein
> entsprechendr Interrupt-Vektor hinterlegt ist. Die Tabelle hört bei (25)
> auf,

Der Interruptvector 29 steht bei 0x6e, das ist mitten in <__ctors_end>, 
und von dort geht es dann ein paar Befehle später per call zu main. Das 
sieht dann nur so aus, als ob das Programm wie im bad-interrupt neu 
startet.

Die Vectortabelle zu verlängern wäre ja nur der erste Schritt, du musst 
auch noch dafür sorgen, daß da die passenden ISR-Vectoren eingetragen 
werden. Dazu brauchst du ein angepasstes linkerscript.

Oliver

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Harald P. schrieb:
> Aber selbst eine modifizierte iom328p.h mit den Headern für LGT8
> führt nicht zum gewüschten Erfolg.

Ist ja auch klar.  Durch Ändern des Headers passt sich ja nicht auf 
magische Weise der Startup-Code daran an... Der ändert sich nur, wenn 
man ihn neu generiert.

Für ein neues Device braucht man:

1) Ein header ioxxx.h

2) Startup Code in crtlgt8f328p.o

3) Device Specs file specs-lgt8f328p

4) Device-Lib liblgt8f328p.a.

Ein extra Linker Script wird NICHT benötigt.

Außerdem würde ich davon absehen, Beschreibungen für ein bestehendes 
Device wie ATmega328P zu verunstalten.

1) Hast du bereits, und für 3) nimmst du ein Specs eines ähnlichen 
Devices, hier bietet sich specs-atmega328p an.  Wie ein neues Specs auf 
Grundlage eines bestehenden erstellt werden kann entnimmt man einem 
bestehenden Specs wie specs-atmega328p.  Device Support wird auch 
erläutert im GCC Wiki:

https://gcc.gnu.org/wiki/avr-gcc#Using_avr-gcc

2) löst man am einfachsten, indem man in AVR-LibC ein neues Device 
supportet und damit neu generiert / installiert.  Ein neues Device ist 
eine Zeile in

./devtools/gen-avr-lib-tree.sh

https://github.com/avrdudes/avr-libc/blob/main/devtools/gen-avr-lib-tree.sh

Insbesondere braucht configure.ac nicht geändert zu werden! Gleiches 
gilt für avr/io.h.

Bei der Wahl des Dateinamens für 1) hast du freie Wahl (wird am Ende des 
Specs eingetragen, siehe dortige Kommentare), ebenso beim Device-Name 
bei -mmcu=xyz.  Einzige Nebenbedingung ist, dass dann Specs specs-xyz 
heissen muss, Startup-Code crtxyz.o und Device-Lib libxyz.a. Was sich 
anbietet ist xyz=lgt8f328p, so dass der Support für ATmega328P unberührt 
bleibt und man intuitiv -mmcu=lgt8f328p hat.

Prinzipiell kann man das crt*.o auch "von Hand" assemblieren, allerdings 
ist AVR-LibC in dieser Beziehung nicht benutzerfreundlich, d.h. 
./crt1/gcrt1.S hat einiges an Abhängigkeiten.

4) Kann man einfach von libatmega328p.a kopieren, oder wenn man die Lib 
nicht braucht dann Linken mit -nodevicelib.  Weitere Lösung ist das neue 
Device in der Device-Lib zu unterstützen, wie das geht hab ich mir aber 
noch nicht angeschaut, evtl. muss garnix extra gemacht werden.

Das alles gilt für avr-gcc v5+.  Für ältere Versionen bis v4.9 läuft die 
Anbindung neuer Devices nicht über Specs, sondern der Compiler selbst 
muss angepasst werden.  Auch mit AVR-LibC muss dann etwas anders 
verfahren werden.

von Harald P. (haraldp)


Lesenswert?

Hallo Georg,
danke für deinen ausführlichen Beitrag. Ich hatte es mir schon gedacht, 
dass eine einfache Änderung von _VECTORS_SIZE in der Header-Datei nicht 
genug ist (wofür ist eigentlich diese Festlegung da?).
An das komplexe Thema kann ich ich mich erst nach meinem Urlaub dran 
machen. Bei Erfolg melde ich mich.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

_VECTORS_SIZE wird u.a. in gcrt1.S gebraucht für die Anzahl der Einträge 
in der Vector Tabelle.

von Harald P. (haraldp)


Lesenswert?

Mit den gnu-gcc Kommandos komme ich nicht klar. Ich wollte zuerst einmal 
den bereits vorhandenen startup-code für atmega328p neu erzeugen. So bin 
ich vorgegangen:
1) Code von https://github.com/avrdudes/avr-libc/ local heruntergeladem
2) Mein WinAVR-Ordner befindet sich in D:\Prog\WinAVR
3) Im WinAVR Ordner "crt1" von "avr-libc-main" kopiert
4) laut https://gcc.gnu.org/wiki/avr-gcc#Using_avr-gcc sollte der 
startup-code folgendermaßen kompiliert werden können:
"avr-gcc -mmcu=avr5 -D__AVR_ATmega328p__ -c gcrt1.S -o 
crt0-atmega328p.o"
Das funktioniert nicht:
gcrt1.S:28:10: error: #include expects "FILENAME" or <FILENAME>
 #include IOSYMFILE
5) Trage ich statt dessen in gcrt1.S den gültigen include-Pfad #include 
"D:\Prog\WinAVR\crt1\iosym\atmega328p.S" ein, so kommt folgende 
Fehlermeldung:
In file included from macros.inc:39:0,
                 from gcrt1.S:31:
d:\prog\winavr\avr\include\avr\io.h:581:6: warning: #warning "device 
type not defined" [-Wcpp]
 #    warning "device type not defined"
      ^
gcrt1.S: Assembler messages:
gcrt1.S:46: Error: non-constant expression in ".if" statement
gcrt1.S:47: Error: non-constant expression in ".if" statement
...
gcrt1.S:172: Error: non-constant expression in ".if" statement

6) Änderung von mmcu-Parameter in atmega328p statt avr5:
avr-gcc -mmcu=atmega328p -D__AVR_ATmega328p__ -c gcrt1.S -o 
crt0-atmega328p.o
gcrt1.S: Assembler messages:
gcrt1.S:359: Error: junk at end of line, first unrecognized character is 
`S'
Diesen "junk" kann ich nicht finden. Laut 
https://gcc.gnu.org/wiki/avr-gcc#Using_avr-gcc klingt alles ganz 
einfach, jedoch läuft bei mir irgendetwas grundsätzlich falsch. Die 
gcc-Version ist übrigens 5.3.0.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Nimm ein gültiges specs anstatt Optionen von Hand zu setzen.

Pfadtrenner in C ist /, nicht  \\.

Lies gcrt1.S und was da includiert wird. Sieht man nicht unbedingt an 
den Fehlermeldungen.

Ich würd immer noch dringend anraten ein eigenes neues Device zu 
verwenden.

: Bearbeitet durch User
von Harald P. (haraldp)


Angehängte Dateien:

Lesenswert?

Johann L. schrieb:
> Ich würd immer noch dringend anraten ein eigenes neues Device zu
> verwenden.

Diesen Ratschlag habe ich befolgt. Unter vielen Mühen ist es mir 
gelungen, das Device "lgt8f328p" zu erstellen.
Sollte jemand das auch gebrauchen können, so findet er eine 
Kurzanleitung in der beigefügten zip-Datei. Dort befinden sich auch die 
Dateien, die WinAVR benötigt. Es ist auch beschrieben, wie das Device 
erstellt wurde.

An die gnu-Spezialisten: Die Vorgehensweise genügt wahrscheinlich nicht 
der reinen Lehre. Trotzdem hat es funktioniert und in meiner Anwendung 
wird jetzt der Timer3-Interrupt ausgeführt.
Harald P.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

habe den Controller zwar nicht, möchte dennoch sagen - Respekt!

von Frank O. (frank_o)


Lesenswert?

Harald P. schrieb:
> Trotzdem hat es funktioniert und in meiner Anwendung
> wird jetzt der Timer3-Interrupt ausgeführt.
> Harald P.

Was sagst du mittlerweile zu diesem µC?
Kann man ihn benutzen?
Allein die 12Bit-ADC finde ich sehr reizvoll.

von Harald P. (haraldp)


Lesenswert?

Frank O. schrieb:
> Harald P. schrieb:
>> Trotzdem hat es funktioniert und in meiner Anwendung
>> wird jetzt der Timer3-Interrupt ausgeführt.
>> Harald P.
>
> Was sagst du mittlerweile zu diesem µC?
> Kann man ihn benutzen?
> Allein die 12Bit-ADC finde ich sehr reizvoll.

Man kann ihn benutzen, aber
- der Baustein ist nicht 100% kompatibel zum AtMeg328
- Es gibt kein umfassendes (und in allen Dingen korrektes) Datenblatt
- Kein echtes EEPROM
. Programmierung nur sinnvoll über den vorprogrammierten  Bootloader 
Optiboot
- Programmierung über andere als UART-Pins schwierig
- Programmierung über SWC/SWD nicht beschrieben
- Timer 3 arbeitet fehlerhaft; ein SW-Uart, wie mit Timer 1 funktioniert 
nicht (wahrscheinlich Fehler im  internen Reload-Registern).
Fazit: AtMega328 ist besser handhabbar. Ansonsten verwenden kann man ihn 
schon. Hauptmanko ist für mich, dass der geniale Bootloader von P. 
Dannengger hier nicht genutzt werden kann. Vielleicht könnte man ihn 
umschreiben, aber bisher war das für mich zu aufwendig.
Harald

von Hadmut F. (hadmut)


Lesenswert?

Schade auch dass der interne DAC zuwenig strom liefert.
Das dings läuft mit der entsprechenden board-lib auch mit arduino 
bestens.

von Frank O. (frank_o)


Lesenswert?

Harald P. schrieb:
> Man kann ihn benutzen, aber

Vielen Dank Harald!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.