AVR Studio / avrdude: Assembler Programm in den Bootloader-Bereich schreiben

Gast #7635182
Lesenswert?

Michael S. schrieb:

Hallo; was muss ich beim Aufrufen von avrdude als Parameter angeben, wenn ich die Hex-Datei nicht an den Anfang des Programmspeichers, sondern in den Bootloader-Bereich schreiben will ?

Fehlt dir die Anleitung von Avrdude oder die Adresse an die du dein Programm laden willst?

(Firma: 1984now) #7635185
Lesenswert?

Michael S. schrieb:

Hallo; was muss ich beim Aufrufen von avrdude als Parameter angeben, wenn ich die Hex-Datei nicht an den Anfang des Programmspeichers, sondern in den Bootloader-Bereich schreiben will ?

Es genügt normalerweise nicht, ein Programm einfach nur an eine andere Stelle zu laden. Dafür müsste es auf eine spezielle Art geschreiben oder kompiliert sein, nämlich: position indipendend.

Oder es muß halt dem Compiler/Assembler die korrekte Zieladresse mitgeteilt worden sein. Dann steht die aber auch implizit im .hex/.elf. Und natürlich wird avrdude sie dann ganz automatisch auf die richtige Adresse schreiben. Ohne jeden weiteren Parameter.

Gast #7635186
Lesenswert?

Georg G. schrieb:

Wenn du das Programm nicht nur in den Bootbereich flashen willst sondern es dort auch ausführen willst, muss es vom Assembler schon passend übersetzt werden. Dann kümmert sich der Assembler / Linker darum, dass es an der passenden Stelle landet.

Genau. Normalerweise kann man ein Programm auch nicht einfach im Flash verschieben, es würde danach nicht funktionieren.

#7635202
Lesenswert?

Zuerst musst Du die benötigte Größe des Boot-Bereiches festlegen, das wird in den FUSES eingestellt. Dort stehen in der Auswahl auch die zugehörigen Einsprungadressen.

Diese Adresse nutzt Du dann per ORG nnnn als Basis beim assemblieren. Alles weitere macht der Assembler. Allerdings musst Du in den FUSES noch den BOOT-RESET-VECTOR aktivieren damit das Programm beim Reset auch direkt zum Bootloader springt.

(Firma: 1984now) #7635205
Lesenswert?

Michael S. schrieb:

Ich will einen eigenen Bootloader schreiben aber wie bekomme ich ihn an die gewünschte Stelle beim ATMEGA328P ?

Wenn in Asm, dann einfach ein ORG an der richtigen Stelle (Asm ist total einfach). Ansonsten mußt du halt ein passendes Linkerscript schreiben (und dann natürlich auch zum Linken benutzen), um die sinnlos aufgeblähte C-Toolchain passend einzunorden.

Also in Asm ist das wirklich absolut easy. Aber C soll ja alles dermaßen viel einfacher machen...

Gast #7635210
Lesenswert?

Ob S. schrieb:

Also in Asm ist das wirklich absolut easy. Aber C soll ja alles dermaßen viel einfacher machen...

In C gibt man dem gcc die Option "-Wl,-Ttext=0x1E00" mit. Kein Linkerscript. Ich brauchte auf meinem Smartphone 25 Sekunden, um das heraus zu finden.

Also sehr kompliziert, dieses C. Ganz schlimm. Unerträglich.

(Firma: 1984now) #7635212
Lesenswert?

Steve van de Grens schrieb:

Ob S. schrieb:

Also in Asm ist das wirklich absolut easy. Aber C soll ja alles dermaßen viel einfacher machen...

In C gibt man dem gcc die Option "-Wl,-Ttext=0x1E00" mit. Kein Linkerscript. Ich brauchte auf meinem Smartphone 25 Sekunden, um das heraus zu finden.

Also sehr kompliziert, dieses C. Ganz schlimm. Unerträglich.

Also ich finde: eine schlichtes ".ORG 0x1e00" direkt im Quelltext immer noch deutlich einfacher. Du nicht?

Gast #7635224
Lesenswert?

Ob S. schrieb:

Also ich finde: eine schlichtes ".ORG 0x1e00" direkt im Quelltext immer noch deutlich einfacher. Du nicht?

Soll ich dir Gegenbeispiele nennen, die in C einfacher sind? Dafür müsste ich nicht mal nach solchen Spezialfällen wie Bootloader suchen. Lassen wir das besser.

Lass uns lieber festhalten, dass alle Programmierer die nicht alles in Assembler machen, in deinen Augen dumm sind. Deine Meinung sei dir gegönnt.

(Firma: 1984now) #7635245
Lesenswert?

Steve van de Grens schrieb:

Lass uns lieber festhalten, dass alle Programmierer die nicht alles in Assembler machen, in deinen Augen dumm sind.

Nein, das keinesfalls. Dann würde ich mich ja selber für dumm halten müssen. Natürlich mache ich auch längst nicht alles in reinem Asm. Das wäre ja Wahnsinn. Aber nahezu alle Projekte mit AVR8-Target schon.

Die Architektur ist schlicht simpel genug, um das machen zu können. Oft ist es sogar so, dass sich das konsequente Asm-Konzept insofern auszahlt, dass man deutlich einfacher switchen kann (natürlich nur innerhalb der Architektur).

Z.B. eben bei sowas wie einem Bootloader. Das von den klassischen AVR8 auf die aktuellen Baureihen umzustellen, kostet in Asm nur ein kühles Arschrunzeln. In C ist der Aufwand deutlich höher. Und witzigerweise: wesentliche Teile muss man dann doch auch wieder in Asm umsetzen...

Gut, wenn man's sowieso kann, dann kommt man nicht in's Stolpern...

#7635252
Lesenswert?

Steve van de Grens schrieb:

Das ist mein Eindruck aus deinen Beiträgen der vergangenen Tage (incl. Heute).

Sorry, aber ich habe in den vergangenen Tagen kaum mal was zum Thema Assembler geschrieben. Im Grunde gar nichts. Ich bin hier eigentlich nur unbeteiligter Zuschauer, der zu verstehen versucht, wo du das Problem zu erkennen glaubst – weil ich das halt nicht sehe.

Es gab hier mal einen oder zwei Leute, für die alles außer Assembler untragbar schlecht war, und nach denen bei den AVR alles in Assembler geschrieben zu werden hätte – aber die sind nicht hier.

Gast #7635270
Lesenswert?

Ob S. schrieb:

. In C ist der Aufwand deutlich höher. Und witzigerweise: wesentliche Teile muss man dann doch auch wieder in Asm umsetzen...

Google mal nach diesem gcc Parameter den ich vorhin nannte Dann findest du ein Tutorial wie man einen generischen Bootloader für alle VR in Plain C implementiert, ohne Tricks und ohne Assembler.

#7635324
Lesenswert?

Steve van de Grens schrieb:

Da ist dieses Tutorial https://www.pocketmagic.net/simple-avr-bootloader-tutorial/

Der Link ist OK Stefan, geht aber an der eigentlichen Frage oben, etwas vorbei. Gerade bei 8-Bit-Cpus, wo die Datenblätter weitgehend vertraut sind, empfinde ich C auch etwas übertrieben. Bei ARM, oder beim ständigen Wechsel von Plattformen ist C ja OK, aber bei allseits vertrauter 8-Bit-Hardware bringt Asm doch etwas mehr Tiefen-Know-How. Und Bibs kann man auch in Asm einbinden, das braucht zwar etwas Übung, aber keine 5-10 Jahre, um mit C einigermaßen klarzukommen.

https://www.mikrocontroller.net/articles/AVR_Bootloader_in_C_-_eine_einfache_Anleitung https://de.wikipedia.org/wiki/Coreboot

Gast #7635567
Lesenswert?

Rbx schrieb:

Der Link ist OK Stefan, geht aber an der eigentlichen Frage oben, etwas vorbei ... empfinde ich C auch etwas übertrieben ... bringt Asm doch etwas mehr Tiefen-Know-How.

In Assembler gibst du die Adresse des folgenden Codes mit .ORG an.

https://onlinedocs.microchip.com/pr/GUID-E06F3258-483F-4A7B-B1F8-69933E029363-en-US-2/index.html?GUID-AAE74D1B-2E66-4C00-87F3-E62598068707

Die generierte HEX Datei beginnt dann mit der ersten Adresse, die du dort angegeben hast. Konfiguriere die Position der Interrupt-Vektor Tabelle (falls verwendet).

#7635578
Lesenswert?

Bei mir ist folgendes Problem:

  1. den Bootloader habe ich mit .org 0x3F00 erstellt und geflasht und er funktioniert.
  2. wenn ich ein Anwendungsprogramm flashe, wird der Bootloader wieder gelöscht.
  3. flashe ich das Anwendungsprogramm (mit avrdude) mit der Option "-D", dann geht das nur beim ersten Mal gut und alle beide (Bootloader und Anwendungsprogramm) funktionieren.
  4. beim zweiten Mal Flashen des Anwendungsprogramms kommt ein "verfification error" und das Anwendungprogramm läuft nicht mehr, nur noch der Bootloader.

Was muss ich tun damit ich den Bootloader resistent im Bootloader-Bereich halten und davon unabhängig das Anwendungsprogramm entwickeln und immer wieder hochladen kann ?

Gast #7635599
Lesenswert?

Peter schrieb:

wenn ich ein Anwendungsprogramm flashe, wird der Bootloader wieder gelöscht.

Womit flasht du es? Wenn der Bootloader sich selbst überschriebt, ist er fehlerhaft. Und wenn du die ISP Schnittstelle zum Flashen verwendet, ist es das normale Verhalten.

Was muss ich tun damit ich den Bootloader resistent im Bootloader-Bereich halten und davon unabhängig das Anwendungsprogramm entwickeln und immer wieder hochladen kann?

Der Punkt ist, dass der Flash Speicher (im Gegensatz zu RAM) vor dem Beschreiben gelöscht werden muss. Und das geht bei avrdude via ISP nur komplett am Stück. Ein Bootloader kann das hingegen Blockweise tun, er muss sich nicht selbst löschen (kann er auch nicht, dagegen gibt es eine Schutzmechanismus).

Du musst dich daher entscheiden: Wenn du einen Bootloader auf dem Chip haben willst, dann solltest du ihn auch benutzen. Wenn nicht, verwendest du einen Programmieradapter.

Oder (wie du bereits herausgefunden hast) du benutzt den Programmieradapter so, dass du jedes mal beides installiert. Das kann man mit einem Script automatisieren.

#7635618
Lesenswert?

Ich benutze einen Arduino Uno und avrisp um einen Standalone-ATMEGA328P zu beschreiben. Kommt man weiter, wenn man die Lockbits anders setzt ? Mein Bootloader ist noch in der Testphase, er lädt eigentlich noch gar nicht sondern zeigt nur Kontroll-LEDs an. Ich bin also noch auf den avrip angewiesen.

#7635894
Lesenswert?

mit diesen Befehlen in der Bootloader-Sektion

1
; Page Erase
2

3
ldi ZH, 0b00000010
4
ldi ZL, 0b00000000
5

6
ldi r20, 0b00000011
7
out SPMCSR, r20
8
spm
9

10
; Filling Buffer
11

12
ldi ZH, 65
13
ldi ZL, 8
14

15
ldi r20, 0b00000001
16
out SPMCSR, r20
17
spm
18

19
; Page Write
20

21
ldi ZH, 0b00000010
22
ldi ZL, 0b00000000
23

24
ldi r20, 0b00000101
25
out SPMCSR, r20
26
spm

versuche ich den Buchstaben "A" an die Stelle 2048 des Flash-Speichers zu schreiben. Warum funktioniert das nicht ?

#7636140
Lesenswert?

danke S.L. ich habe noch ein paar kleine Änderungen eingebaut uns so funktioniert es jetzt bei mir:

1
.include  "m328Pdef.inc"
2
.org 0x3F00
3

4
ldi r16,   0b00000011
5
out DDRB,  r16
6
ldi r16,   0b00000010
7
out PORTB, r16
8

9
ldi ZH,high(2048)
10
ldi ZL,low (2048)
11
ldi r20, (1<<PGERS) | (1<<SELFPRGEN)
12
call Do_spm
13
ldi r20, (1<<RWWSRE) | (1<<SELFPRGEN)
14
call Do_spm
15
ldi r20,'A'
16
mov r0,r20
17
ldi r20,'b'
18
mov r1,r20
19
ldi r20, (1<<SELFPRGEN)
20
call Do_spm
21
ldi r20, (1<<PGWRT) | (1<<SELFPRGEN)
22
call Do_spm
23
ldi r20, (1<<RWWSRE) | (1<<SELFPRGEN)
24
call Do_spm
25

26
ldi r16,   0b00000011
27
out PORTB, r16
28

29
loop:
30
rjmp loop
31

32
Do_spm:
33
in r21, SPMCSR
34
sbrc r21, SELFPRGEN
35
rjmp Do_spm
36
out SPMCSR, r20
37
spm
38
ret

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren