Forum: Mikrocontroller und Digitale Elektronik Rücksprung aus Bootloader bei >64k Flash


von Peter Hildebrand (Gast)


Lesenswert?

Hallo Experten,

ich habe folgendes Problem:

Ich habe einen Bootloader, der auf kleinen AVRs mit <64k Flash 
problemlos geht. Programmiert in C mit AVR-Studio 4 und GCC.

Nach dem Portieren auf 128k-Flash kann ich auch problemlos das Flash 
beschreiben, nur der Rücksprung an die Adresse 0x000000 geht 
offensichtlich nicht.

Für den Rücksprung rufe ich am Ende des Bootvorgangs start() auf. Das 
habe ich so definiert:

void (*start)( void ) = 0x0000;

Ich vermute, dass es hier ein Sprungproblem gibt, da der Bootloader 
jetzt außerhalb der bisherigen 64k Grenze ist.

Hat jemand einen Tip, wie ich den Sprung lösen kann?

Danke und Grüße,
Peter

von Ulrich F. (Gast)


Lesenswert?

Meine Glaskugel sagt:
1
goto *0;
Müsste zu einem Long Jump werden..

von Mein grosses V. (vorbild)


Lesenswert?

Peter Hildebrand schrieb:
> Ich vermute, dass es hier ein Sprungproblem gibt, da der Bootloader
> jetzt außerhalb der bisherigen 64k Grenze ist.

>64KByte  ist erstmal nicht das Problem. Das taucht erst bei >128KByte auf. Das 
Flash ist 16 Bit breit und die Adressierung geschieht mit Word-Adressen. Das 
Adress-Register ist aber nur 16 Bit breit. Daher gibt es bei >128K das 
EIND-Register als Offset.

1
void Restart(void)
2
{
3
  #if (FLASHEND > 0x1FFFF)
4
   EIND = 0x00;
5
  #endif
6
  #if (FLASHEND > 0x1FFF)
7
   asm volatile ("jmp 0");
8
  #else    
9
   asm volatile ("ldi  r30, 0x00");
10
   asm volatile ("ldi  r31, 0x00");
11
   asm volatile ("ijmp");
12
  #endif
13
}

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Mein grosses V. schrieb:
> Das Adress-Register ist aber nur 16 Bit breit. Daher gibt es
> bei >128K das EIND-Register als Offset.

Deer Compiler geht davon aus, dass EIND immer den gleichen Wert hat. 
Dieser wiederum wird vom StartUp-Code gesetzt:
1
#ifdef __AVR_3_BYTE_PC__
2
  ldi  r16, hh8(pm(__vectors))
3
  out  _SFR_IO_ADDR(EIND), r16
4
#endif  /* __AVR_3_BYTE_PC__ */

http://svn.savannah.nongnu.org/viewvc/trunk/avr-libc/crt1/gcrt1.S?revision=2459&root=avr-libc&view=markup

Am einfachsten erledigt man den Sprung zu einer bestimmten Adresse per
1
extern void Restart (void);

und ruft dieser Funktion dann auf.  Das Symbol kann dann definiert 
werden per Linkeroption:
1
-Wl,--def-sym,Restart=0

Und falls mann sich mit Assembler wohler fühlt:  Es gibt keinen Grund 
für IJMP; ein normaler (R)JMP genügt vollkommen und kann auch den ganze 
Flash adressieren.

von Peter Hildebrand (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

erst einmal ganz herzlichen Dank für die Tips und Ratschläge!

Ich habe alle drei Varianten probiert, leider ohne Erfolg:

Bei den ersten beiden Varianten erfolgt kein Sprung zu Adresse 0. Das 
passiert aber nur auf dem ATmega1284P, auf einem ATmega328 hingegen geht 
alles wunderbar mit allen Varianten.

Variante 3 kann ich nicht kompilieren, dort bekomme ich eine 
Fehlermeldung, mit der ich nichts anfangen kann. Siehe Anhang. Dazu 
reicht leider mein Anfängerwissen nicht aus! Die Linkeroption habe ich 
hinzugefügt.

viele Grüße,
Peter

von Peter D. (peda)


Lesenswert?

asm volatile ("jmp 0");

muß gehen, kann bis 4MWords adressieren.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Peter Hildebrand schrieb:
> [unzitierbar]
> Variante 3 kann ich nicht kompilieren, dort bekomme ich eine
> Fehlermeldung, mit der ich nichts anfangen kann. Siehe Anhang. Dazu
> reicht leider mein Anfängerwissen nicht aus!

Mein Fehler. Die Option heißt --defsym, nicht --def-sym.

von Peter Hildebrand (Gast)


Lesenswert?

Hallo Peter und Johann,

vielen Dank für die Geduld und Tips!

Jetzt geht es wunderbar (mit beiden Methoden von Euch!)

Dank auch an alle anderen für die Tips!

Peter

von c-hater (Gast)


Lesenswert?

Johann L. schrieb:

> Und falls mann sich mit Assembler wohler fühlt:  Es gibt keinen Grund
> für IJMP; ein normaler (R)JMP genügt vollkommen und kann auch den ganze
> Flash adressieren.

Nö, von jeder beliebigen "Start"adresse genügt ein rjmp natürlich nicht, 
das tut nur der jmp. Wenn man aber gedanklich mal das "(R)" in deinem 
Posting entsorgt, wird immer noch hinreichend klar, warum man sich mit 
Asm wohler fühlt: Man weiss, was geht und wie es geht. Man ist nicht 
davon abhängig, was irgendwelche Compilerbauer jeweils meinen, verwenden 
zu müssen (und damit immer mal wieder auf die Schnauze fallen). Und die 
Sache mit dem ijmp wird auch spätestens dann akut, wenn man mit 
Funktionspointern hantiert, was nur in dieser überaus primitiven 
Anwendung eines Bootloaders nicht relevant ist...

Das Grundproblem ist nämlich einfach, dass C keinesfalls so "portabel" 
ist, wie die C-ler immer suggerieren. Und das liegt u.a. daran, dass C 
als Sprache bereits einen Haufen Annahmen über das Zielsystem macht. Und 
nur C-Fetischisten finden diese, durch nichts (ausser ein paar eher 
historischen µP-Systemen) begründeten Annahmen "logisch".

Tatsächlich ist das aber ungefähr so logisch, wie Annahme der 
Scheibengestalt der Erde und ihrer Position im Zentrum des Universums. 
Man muss das einfach nur glauben, dann gewinnt der ganze unendliche 
Fuck, der sich um diese Fehlinterpretation der Realität herum entwickelt 
hat, den Status von Gottes Wort. Ein unabänderliches Axiom.

Aber genau so, wie die Wissenschaft die Axiome der katholischen Kirche 
hinweggefegt hat, wird irgendwann eine sinnvolle Programmiersprache das 
C-Axiom hinwegfegen. Das Problem dabei ist eigentlich nur: Es wird 
verdammt lange dauern und Opfer kosten. Aber der Kampf gegen die 
Katholen tat das auch...

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Gaaaanz ruuuuhig....!

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

c-hater schrieb:
> Johann L. schrieb:
>
>> Und falls mann sich mit Assembler wohler fühlt:  Es gibt keinen Grund
>> für IJMP; ein normaler (R)JMP genügt vollkommen und kann auch den ganze
>> Flash adressieren.
>
> Nö, von jeder beliebigen "Start"adresse genügt ein rjmp natürlich nicht,
> das tut nur der jmp. Wenn man aber gedanklich mal das "(R)" in deinem
> Posting entsorgt,

Das "R" ist so zu lesen, dass auf Devices, die kein JMP kennen, ein RJMP 
zu verwenden ist.  In asm-Sprech:
1
__asm__ __volatile__ ("%~jmp":::"memory");

> warum man sich mit Asm wohler fühlt:
> Man weiss, was geht und wie es geht. Man ist nicht
> davon abhängig, was irgendwelche Compilerbauer jeweils meinen,
> verwenden zu müssen (und damit immer mal wieder auf die
> Schnauze fallen).

Ersetzt "man" durch "c-hater".

Bei diesem Kenntnisstand und Weltbild wirt du natürlich in Assembler 
programmieren.  Wer Compilerbauer als seine natütlichen Feinde ansieht, 
wird keinen Compiler einsetzen.

> Und die Sache mit dem ijmp wird auch spätestens dann akut,
> wenn man mit Funktionspointern hantiert, was nur in dieser
> überaus primitiven Anwendung eines Bootloaders nicht relevant ist...

Zu einem IJMP gehört aber EIND.  Wie sollte denn ein Callee EIND wieder 
zurück auf den richtigen Wert setzen?

Natürlich wären auch Lösungen ohne EIND denkbar gewesen, dieses Register 
ist kompletter Blödsinn.

> Das Grundproblem ist nämlich einfach, dass C keinesfalls so "portabel"
> ist, wie die C-ler immer suggerieren. Und das liegt u.a. daran, dass C
> als Sprache bereits einen Haufen Annahmen über das Zielsystem macht. Und
> nur C-Fetischisten finden diese, durch nichts (ausser ein paar eher
> historischen µP-Systemen) begründeten Annahmen "logisch".

Na dann lass die Finger von C.  Warum tust du dich so ereifern?

> Tatsächlich ist das aber ungefähr so logisch, wie Annahme der
> Scheibengestalt der Erde und ihrer Position im Zentrum des Universums.
> Man muss das einfach nur glauben, dann gewinnt der ganze unendliche
> Fuck, der sich um diese Fehlinterpretation der Realität herum entwickelt
> hat, den Status von Gottes Wort. Ein unabänderliches Axiom.
>
> Aber genau so, wie die Wissenschaft die Axiome der katholischen Kirche
> hinweggefegt hat, wird irgendwann eine sinnvolle Programmiersprache das
> C-Axiom hinwegfegen. Das Problem dabei ist eigentlich nur: Es wird
> verdammt lange dauern und Opfer kosten. Aber der Kampf gegen die
> Katholen tat das auch...

bla bla bla.  Du hättest Prediger werden sollen.  Bzw. du bist es 
offenbar...

von c-hater (Gast)


Lesenswert?

Johann L. schrieb:

> Na dann lass die Finger von C.

Genau das ist der Punkt: Ich kann die Finger nicht von C lassen, weil 
mich das böse RL dazu zwingt, diesen Vollscheiss wider besseren Wissens 
doch immer wieder zu verwenden. Irgendwie muss ich ja schliesslich meine 
Brötchen verdienen...

> Warum tust du dich so ereifern?

Weil ich es so abgrundtief hasse, nur zum Überleben etwas tun zu müssen, 
von dem ich ganz sicher weiss, dass es de facto ziemlicher Unsinn ist, 
den man viel besser machen könnte.

Das ist nicht mal ein Vorwurf gegen die ursprünglichen Entwickler von C. 
Damals war deren Lösung, naja, halt das Machbare, um den 
Asm-Abstinenzlern doch irgendwie das Programmieren zu ermöglichen. Und 
die Randbedingungen wurden halt so gewählt, dass sie recht gut auf die 
damals relevanten Systeme gepasst haben.

Nur hat sich die Bandbreite der Zielsysteme ganz anders entwickelt, als 
die C-Erfinder es erwartet haben. Und um die heilige Kuh nicht zu 
opfern, wurde dann gefrickelt ohne Ende...

von Ulrich F. (Gast)


Lesenswert?

c-hater schrieb:
> Weil ich es so abgrundtief hasse, nur zum Überleben etwas tun zu müssen
Sehr interessant.

Mein Tipp:
Tue nur das, was du gerne tust.

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.