Forum: Compiler & IDEs ISR im Bootloader nutzen?


von tobiTob (Gast)


Lesenswert?

Hallo,

vielleicht bin ich hier besser aufgehoben. ;-)
Ich möchte im Bootloader Interrupts verwenden, das ganze sieht im Moment 
so aus.
1
BOOTLOADER_SECTION
2
3
int main_bootloader (void) {
4
   DDRA = 0;
5
  PORTA = (1<<PINA4)|(1<<PINA5)|(1<<PINA6)|(1<<PINA7);
6
7
   DDRC = (1<<PINC7);
8
  PORTC = (1<<PINC6);
9
10
//--- Timer 2 -------------
11
  TIMSK2 |= (1 << TOIE2);         // Interupt einschalten
12
  TCCR2B |= (7<<CS00);        // Vorteiler
13
14
//--- INTTERRUPT Vector in den Bootloader verschieben --------------------------
15
  /* Enable change of Interrupt Vectors */
16
  MCUCR = (1<<IVCE);
17
  /* Move interrupts to Boot Flash section */
18
  MCUCR = (1<<IVSEL);
19
  sei();
20
21
  while(1) {       /* "BOOT Programm" Schleife */
22
/* später erfolgt hier die Abbruchbedingung */
23
  }
24
  return 0;
25
26
//--- INTTERRUPT Vector in den Mainbereich verschieben ------------------------
27
  cli();
28
  CLEAR_BIT(MCUCR,IVCE);        // Disable change of interrupt vectors
29
  CLEAR_BIT(MCUCR,IVSEL);        // Move interrupts to main flash section
30
31
  asm volatile ( "jmp 0x0000" );
32
}


Nun meine Frage, wie bekomme ich eine ISR Routine für meinen Timer2 
Overflow programmiert?

Ich weiß das es eine eigene Routine sein muß, ein Versuch wie...

[c]
ISR(BOOT_TIMER2_OVF_vect)
{
  TCNT2 = TCNT2-18;        // Startwert laden

/* mach was */

}
{/c]

Führte aber nicht zum Erfolg, wie ist der richtige Weg?
Hier kam immer eine Fehlermeldung "redefiniert" logisch, ich nutze den 
ja auch im Main Programm...
Ich sehe das er auf Adress 0x10 springt aber das ist mitten im 
MAIN_BOOTLOADER Abschnitt.... :-(

Danke für eure Hilfe, Tobi...

von kosmonaut_pirx (Gast)


Lesenswert?

hallo,
du kannst ganz normal im bootloader interrupts benutzen. soe wie immer. 
verschieben tust du die interrupts ja schon in die BLS. wichtig ist dann 
nur noch, das gesamte geschütz per -Wl,--section-start=.text=0xirgendwas 
an den beginn der BLS zu verschieben.

das mit dem "refefined" ist für mich nicht logisch. da fehlt wohl noch 
etwas input.

bye kosmo

von tobiTob (Gast)


Lesenswert?

Puhh wie macht man das denn?
Ich nutze AVR Studio die aktuelle Version und "WinAVR-20070525rc2".

Ich habe ja im Mainprogramm schoneinmal eine ISR für den Timer2Ovf 
deklariert deshalb meckert er halt.

Also Main sieht so aus...
1
ISR(TIMER2_OVF_vect)
2
{
3
  TCNT2 = TCNT2-18;        // Startwert für }
4
/* mach was im main mit dem timer */
5
}
6
7
int main (void) {
8
/* was man so macht also Port's initialisieren usw. */
9
}

Das funktioniert auch soweit das es ja mein "normales" Programm ist.




Nun der Bootloader...
Dazu habe ich mir im AVR Studio unter den GCC Optionen das Segment 
".bootloader" angelegt und gesagt es ist Adress 0x7000.

Soweit so gut...

Nun springt er nach dem Start in der Tat im Quelltext auf den Eintrag 
"BOOTLOADER_SECTION"

Und beginnt mit der Abarbeitung, soweit ist mir das nun klar.

Jetz wollte ich hier in der BOOTLOADER_SECTION meine ISR Routine ablegen 
welche ja in den geschützten Bereich muß, aber das bekomme ich nich 
gebacken.... da gibt es entweder die Meldung:

../C-HelloWorld.c:1496: error: redefinition of '__vector_11'



Das dürfte wohl mein Problem sein, das ich nicht weiß wie man dem 
compiler nun bei bringt das er die im Bottsector geschribenen ISR 
Routinen nehmen soll...


Ich stell mich wohl einfach zu blöd an :(


Gruß Tobi...

von kosmonaut_pirx (Gast)


Lesenswert?

zugegeben, ich kenne mich mit avr studio und den optionen da nicht aus.

aber eine ISR kannst du nur einmal definieren (wie alles übrigens). 
warum nimmst du nicht die aus deiner main raus? zwei mains gehen schon 
gar nicht, auch wenn du da mit der main-bootloader etwas rumtrickst.

von Markus H. (mheigl)


Lesenswert?

Ich hab zwar die vorangegangenen Posts nur überflogen geb aber trotzdem 
schnell mal was in den Ideentopf.
ISR Aufrufe sind ja im Allgemeinen so realisiert, dass in einem 
bestimmten Speicherbereich die Sprungadressen zu den ISRs stehen was 
auch Interrupt Vector Table genannt wird. Meistens wird diese im 
Bootloader initialisiert was du ja wohl auch machst.
Nun kann man die Interrupt Vektoren natürlich auch zur Laufzeit ändern 
indem man einfach die Sprungadressen ändert.
1
__intvect ISR1();
2
__intvect ISR2();
3
4
5
IntteruptVektor=ISR1;
6
7
/*Bootloader Code*/
8
9
InterruptVektor=ISR2;
10
11
/*main funktion aufrufen*/

Nur so ne Idee

von Jörg X. (Gast)


Lesenswert?

@OP: Wieso willst du unbedingt_ Bootloader und Anwendung _gleichzeitig 
erstellen? Es reicht doch den Bootloader einzeln zu compilieren, zu 
flashen und anschließend die eigentliche Anwendung (die du man mit dem 
bootloader flashen kannst ;) ) -- was btw. oben schon erwähnt wurde.
 Alternativ geht auch, dass du die .hex-Dateien aneinander hängst (wurde 
hier im Forum schon besprochen, da muss die letzte Zeile gelöscht werden 
--_glaub ich_).

hth. Jörg

von tobiTob (Gast)


Lesenswert?

Hi,

also ich glaube meine Lösung ist folgende, vlt. kann mich da noch jemand 
anschubbsen?

Also nach dem WERT

BOOTLOADER_SECTION

da muß eine Aufstellung hin wo die Adressen der einzelnen Routinen 
gespeichert ist.

In Assembler wüste ich wie es geht...

.equ  BOOTGO = FOURTHBOOTSTART
.equ  reti
.equ  reti
.equ  reti
.equ  BOOT_TIMER2_OVFL
.equ  reti

...das Vergleichstück in C ist mir nicht bekannt. :-(

Also so in etwa...

BOOTLOADER_SECTION (0x7000)
BOOT_MAIN  (zum BOOT_MAIN springen)
BOOT_NO_USE (nur zurück springen)
BOOT_NO_USE (nur zurück springen)
BOOT_NO_USE (nur zurück springen)
BOOT_NO_USE (nur zurück springen)
BOOT_NO_USE (nur zurück springen)
BOOT_NO_USE (nur zurück springen)
BOOT_NO_USE (nur zurück springen)
BOOT_NO_USE (nur zurück springen)
BOOT_NO_USE (nur zurück springen)
BOOT_TIMER2_OVFL (zur BOOT_TIMER2_OVFL springen)
BOOT_NO_USE (nur zurück springen)



dann sollte es klappen... wie definiert man sowas in C?



Gruß Tobi...

von Markus H. (mheigl)


Lesenswert?

Hmm also zum einen wird ein einfaches reti nicht reichen. Du wirst für 
alle Interrupts die du aktivierst eine routine schreiben müssen die 
mindestens das Interrupt Flag zurücksetzt bevor du reti machst. Sonst 
landest du in einer Endlosschleife weil der Interrupt ständig ausgelöst 
wird.

Ansonsten sind die Speicheradressen der Interrupt Vektoren fest 
definiert.
Wo die genau sind musst du im Hardware Manual deines Controllers 
nachlesen.
Da wird eine Tabelle drin sein die so aussehen könnte:
1
Number, Adress, Source, Description
2
1 ,0x000 ,RESET ,External Pin, Power-on Reset, Brown-out Reset, Watchdog 
3
2 ,0x002 ,INT0 ,External Interrupt Request 0
4
3 ,0x004 ,INT1 ,External Interrupt Request 1
5
4 ,0x006 ,INT2 ,External Interrupt Request 2
6
5 ,0x008 ,PCINT0 ,Pin Change Interrupt Request 0
7
6 ,0x00A ,PCINT1 ,Pin Change Interrupt Request 1
8
7 ,0x00C ,TIMER3 ,CAPT Timer/Counter3 Capture Event
9
8 ,0x00E ,TIMER3 ,COMPA Timer/Counter3 Compare Match A

Und an die angegebenen Adressen musst du dann die Funktionspointer 
deiner ISRs schreiben.

Hinter den Adressen stecken übrigens meistens Register, müssen also bei 
jedem Start auf die richtigen Werte gesetzt werden.
Von daher deine Idee mit .equ nicht schlecht aber leider falsch.

wirst etwas machen müssen wie
1
ld #0x00C,R1
2
ld ISR_Adresse,@R1

von kosmonaut pirx (Gast)


Lesenswert?

hallo,

>Hinter den Adressen stecken übrigens meistens Register, müssen also bei
>jedem Start auf die richtigen Werte gesetzt werden.

das stimmt doch nicht. das sind inhalte im befehlsspeicher, und der ist 
fest/non-volatile. da wird nichts geladen, da wird einfach ein befehl 
samt operand ausgeführt.
wie im handbuch zu lesen, kann man den platz der interrupts auch für was 
anderes benutzen, so man denn nicht interrupts benutzt. sind die 
interrupts aber an, wird der befehl an der entsprechenden stelle 
gelesen, interpretiert und ausgeführt. im normalfall ein jmp.

bye kosmo

von tobiTob (Gast)


Lesenswert?

Hi Kosmo,

ja das stimmt auch... ich habe mir das file mal angesehen im 
Disassembler...

Bei normalen Betrieb erzeugt der compiler die Einsprungadressen wie 
folgt...

+00000000:   940C0169    JMP     0x00000169       Jump
+00000002:   940C0186    JMP     0x00000186       Jump
+00000004:   940C0186    JMP     0x00000186       Jump
+00000006:   940C0186    JMP     0x00000186       Jump
+00000008:   940C0186    JMP     0x00000186       Jump
+0000000A:   940C0186    JMP     0x00000186       Jump
+0000000C:   940C0186    JMP     0x00000186       Jump
+0000000E:   940C0186    JMP     0x00000186       Jump
+00000010:   940C0186    JMP     0x00000186       Jump
+00000012:   940C0186    JMP     0x00000186       Jump
+00000014:   940C0186    JMP     0x00000186       Jump
+00000016:   940C046B    JMP     0x0000046B       Jump

Das ist soweit ok!
Nun brache ich irgenwie die Befehle um folgenes zu erreichen.

Beim BOOTLOADER ist ja nicht 0x0000 der Start sonder bei mir nun 0x7000 
und da muß nun im Disasembler eine ähnklich eTabelle entstehen, tut's 
aber nicht da kommt gleich mein Quellcode der im BOOT_MAIN geschrieben 
ist... ach mano...

An Adresse +00007016 sollte stehen auf welche ISR Routine er springen 
soll.
Alle anderen einfach zurück oder mit Dummy belegen weil der Abstand 
eingehalten werden muß... hmm

Für heute reicht es... ich geh mal pennen, vielleicht hilft das 
weiter... ;-)

MfG Tobi...

von kosmonaut pirx (Gast)


Lesenswert?

bin bestimmt nicht der assembler-guru, aber gab's da nocht sowas wie 
.org, um den location-pointer zu setzen?

na denn gute nacht,
bye kosmo

von Jörg X. (Gast)


Lesenswert?

@ tobiTob:
Hast du mal in der AVR-GCC doku nach "avr/boot.h" geschaut? (Bei WinAVR 
ist die Doku auf jeden Fall dabei, bei linux-Paketen wahrscheinlich 
auch)
Außerdem kannst du dir mal den Bootloader von Peter Fleury anschauen 
(unter jump.to/fleury) -- der ist zwar nicht soo aktuell, aber eben für 
den gcc geschrieben.

hth. Jörg

von Markus H. (mheigl)


Lesenswert?

kosmonaut pirx wrote:
> hallo,
>
>>Hinter den Adressen stecken übrigens meistens Register, müssen also bei
>>jedem Start auf die richtigen Werte gesetzt werden.
>
> das stimmt doch nicht. das sind inhalte im befehlsspeicher, und der ist
> fest/non-volatile. da wird nichts geladen, da wird einfach ein befehl
> samt operand ausgeführt.

Da habe ich dann wohl zu groß gedacht. Ich hatte bei der Aussage etwas 
größere Controller im Kopf, welche ein AIC oder Ähnliches haben. Diese 
müssen nach jedem Reset neu initialisiert werden.

Also,
streiche: meistens
setze: manchmal

In der Hinsicht wäre es vielleicht hilfreich zu wissen welchen 
Controller er einsetzt um diesbezüglich klare Aussagen treffen zu 
können.

von tobiTob (Gast)


Lesenswert?

@all

Ich arbeite mit einem ATMEL ATmeag644 im Moment.
Tool's sind AVRStudio mit WinAVR.
Das ganze was ich machen möchte ist das der Gesamte Code wirklich in der 
BOOT_SECTION, also nach 0x7000 geschrieben wird.

Es ist bei den ATMEL's so vorgesehen das nach der Adresse 0x0000 eben 
alle VECTOREN definiert werden wo bei welchem Interrupt hinzuspringen 
ist. In Assembler wüste ich es, könnte es auch posten.

Nun hat man die Möglichkeit bei den ATMEL die Vectoren umzuschalten, das 
macht Sinn wenn man seinen Code komplett in der BOOT_SECTION speichern 
möchte.

Dann erwartet der µC das man seine VECTOREN nach der Statradresse 
definiert, also ab 0x7000 in meinem Fall. ;-)

Nun, in der BOOT_SECTION steht nun meine Funktion wie...
1
ISR(BOOT_TIMER2_OVF_vect)
2
{
3
  TCNT2 = TCNT2-18;        // Startwert laden
4
5
/* mach was */
6
7
}

Diese muß nun auf den VECTOR 0x7000 + 10 angemeldet werden damit der µC 
das richtig abarbeitet. An 0x7000 muß irgendwie was stehen das er meine 
"BOOT_TIMER2_OVF_vect" anspricht.

Also ich denke das es geht nur der Weg zum Ziel ist das Rätsel.

@Jörg X.

Also angesehen habe ich es mir aber verstanden würde ich nicht sagen.
Es ist immer schwer andere Quelltexte fließend zu lesen doch ich habe 
das Gefühl es läuft da anders, also nicht mit einem Bootbereich mit 
Interrupts.

Die Datei boot.h habe ich mir auch angesehen, da find ich überhaut 
nichts von Interrupts in der BOOT_SECTION... :-(

Hab ich das Prinzip nun verstanden oder nicht. :-D

Ich hoffe die Lösung ist nicht mehr weit weg.

Einen schönen Tag, Tobi...

von kosmonaut pirx (Gast)


Lesenswert?

hallo,
die lösung ist wie beschrieben ganz nahe: die .text-section nach 0x7000 
verschieben. ende, aus maus.

wie das geht, steht da:
http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_reloc_code

bye kosmo

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

kosmonaut pirx wrote:

> die lösung ist wie beschrieben ganz nahe: die .text-section nach 0x7000
> verschieben. ende, aus maus.

Für AVR Studio nimmst du dafür entweder gleich ein externes Makefile,
oder du musst das -Wl,--section-start=.text=0x7000 irgendwie in die
Optionen reinpopeln, die er zum Linken nimmt.

von tobiTob (Gast)


Lesenswert?

@Jörg Wunsch

Hi Jörg, du siehst ich bin noh nicht weiter... ich denke aber das Du 
genau der richtige bist da Du dich mit dem WinAVR Zeug's wohl bestens 
auskennst.

Verstehst Du meine Ansätze?

Ich drehe mich nun schon einen Tag im Kreis.
Nun bin ich fast soweit den Bootloader aus meinen ASM Projekt in den 
Chip zu pusten da ich es so nicht in den Griff bekomme.
Ich will es aber innerlich in C schaffen. ;-)

C finde ich einfach übersichtlicher zu schreiben, ich wollte deshalb 
auch in C den Bootloader realisiseren doch es scheint das es da 
Diferenzen gibt.

Im AVR Studio gibts ja die Möglichkeit über die Settings das .bootloader 
Segment auf 0x7000 zu setzen, das klappt auch!

Er schreibt alles was nach dem Wort BOOTLOADER_SECTION an die Position 
0x7000 was aber nicht berücksichtig wird sind die neuen 
Interruptvectoren.

Wie ist das gedacht bei WinAVR wenn man im Bootloader Bereich eigene 
Interruptvectoren verwenden möchte?


Wie sagt man in deinen Kreisen... 73 de Tobi... ;-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

tobiTob wrote:

> Im AVR Studio gibts ja die Möglichkeit über die Settings das .bootloader
> Segment auf 0x7000 zu setzen, das klappt auch!

Das ist aber genau der falsche Ansatz.  Du sollst das bitteschön
nicht in eine .bootloader-Section packen, sondern ganz normal den
kompletten Bootloader als eigenständige Applikation betrachten, der
ganz normal .text, .data und .bss hat, und dessen .text-Section
du dann per Linkeroption auf 0x7000 schiebst.  Nur so verschiebst
du alles einschließlich der Interruptvektoren.

Die eigentliche Applikation läuft dann völlig separat und weiß einfach
gar nichts davon, dass sie von einem Bootloader in den Flash gepumpt
worden ist.  Die ist ein komplett separates Projekt.

von Jogibär (Gast)


Lesenswert?

Hallo,

brauchst Du überhaupt unbedingt Interrupts im Bootloader ?

(Ich schreibe mir in C gerade selber einen, und ich optimistisch,
keine Interrupts brauchen zu müssen)


Jogibär

von tobiTob (Gast)


Lesenswert?

Naja ob man sie bracht... geht bestimmt auch ohne... ;-)

Ich habe einen in ASM geschrieben der nimt den TIMER2 Overflow INT und 
die gesamte UART Sache läuft auch mit den INT's.

Läuft eigendlich ohne Probleme, den wollte ich nun nach C portieren aber 
das ist ein schwieriges Unterfangen.

Nun ich denke ich werde meine ASM Sache anpassen auf den 644 das 
kopilieren. Wie ich es dann dauerhaft in mein C Project einbinde das das 
fertige ASM Zeugs immer an Adresse 0x7000 angehangen werden soll weiß 
ich nicht...

Ist doch noch einiges unklar...


Gruß Tobi

von Simon K. (simon) Benutzerseite


Lesenswert?

@tobiTob: Wo ist dein Problem? Willst du die Antwort nicht sehen? 
Schreibe doch einfach zwei C-Programme. Einmal den Bootloader, und 
einmal den Rest.

Das wurde hier doch schon oft genug gesagt.

von Peter D. (peda)


Lesenswert?

tobiTob wrote:

> Nun ich denke ich werde meine ASM Sache anpassen auf den 644 das
> kopilieren. Wie ich es dann dauerhaft in mein C Project einbinde das das
> fertige ASM Zeugs immer an Adresse 0x7000 angehangen werden soll weiß
> ich nicht...

Der Witz eines Bootloader ist ja, er wird nirgends nicht angehangen.

Er ist ein ganz normales Programm, was ganz für sich alleine in den AVR 
geflasht wird und gut is.

Und dann lötest Du den Chip in Deine Schaltung ein und flashst die 
Anwendung per Bootloader wie es sich gehört.


Interrupts braucht man im Bootloader nicht unbedingt, machen nur die 
Anpassung an verschiedene AVRs schwieriger.


Peter

P.S.:
Einen sorgenfreien Bootloader (ATtiny13..ATmega644) findet man übrigens 
in der Codesammlung.

von Stefan K. (_sk_)


Lesenswert?

Ich verstehe das Problem nicht ganz.
Um einen Bootloader zu erzeugen,musst Du nur 2 Dinge beachten:

* wie Jörg schon sagte:
  die .text-Section per Linkeroption auf 0x7000 schieben, bzw.
  auf die gewünschte Boot-Start-Adresse.

* die Fuse BOOTRST setzen und je nach Bedarf
  die Fuses BOOTSZ0 bzw. BOOTSZ1.

Danach ist Dein Programm im Bootloader-Bereich, alles andere kannst Du 
wie bei "normalen" Programmen auch machen.

Du kannst Interrupts extakt gleich wie in "normalen" Programmen 
verwenden, das geht sogar so weit, dass Du z.B. ein File, das die 
serielle Schnittstelle über den Interrupt anspricht, ohne eine Änderung 
auch in Deinem Bootloader verwenden kannst.

Du kannst sogar WÄHREND dem Programmieren des Flashs Interrupts 
zulassen. Dabei musst Du nur eine Sache beachten:
Die Befehle zum Beschreiben des Flashs sind Sequenzen aus 2 
ASM-Befehlen, die innerhalb von 4 Clockzyklen erfolgen müssen (Schutz 
gegen unbeabsichtigtes Beschreiben). Deshalb während diesen Sequenzen 
die IRs abschalten (sonst kann es passieren, dass ein IR GENAU zwischen 
beide Befehle hineintrifft).

Bei Verwendung der Befehle aus der AVR-LIBC:
Die Aufrufe zum Löschen und Beschreiben des Flash mit abgeschalteten IRs 
geben, z.B.:
1
  cli();
2
  boot_page_write(...);
3
  sei();
Da die Routinen zum Beschreiben des Flash den Flash-Programmiervorgang 
nur anstossen und nicht auf die Beendigung des Programmierens warten, 
sind die IRs dadurch nur sehr kurz (einige us) gesperrt.

Zum Thema Bootloader und Normal-Firmware gemeinsam übersetzen:
--------------------------------------------------------------
Vergiss es einfach!
dazu müssten nicht nur die Vektoren vom gcc doppelt angelegt werden, 
auch die komplette Initialisierung müsste doppelt - für jeden 
Programmteil separat - getätigt werden.

Die einzige Lösung, die realistisch erscheint:

* Übersetze Deinenn Bootloader separat.
* Erzeuge aus dem Output ein File, dass Du beim Linken der 
Normal-Firmware
  mit dazubinden kannst (und zwar ab der Bootloader-Startadresse).


Gruß, Stefan

von tobiTob (Gast)


Lesenswert?

Hallo Leute,

danke für Eure Geduld!!!!

Also wenn es ehh leichter ist mir 2 seperaten Programme dann mache ich 
es auch so.

Ich habe nun mein Bootloader fertig, den aber nun koplett in ASM 
gelassen weil ich da dann keinen Sinn sehe den in C zu portieren da der 
ja ehh extra in den ATMEL geschrieben wird.

Meine normale Anwendung also das "Mainprogramm" habe ich nun in C 
geschrieben, das compiliert sich und alles ist ok.

Nun würde es lediglich noch interessant sein wie ich in einem Rutsch ein 
Mainprogramm und den Bootloader flashen kann.

Bootloader ist nun in ASM. Ausgabe .HEX
Mainprogramm in C. Ausgabe .HEX

Ihr schreibt immer wieder von "linken", welche Möglichkeiten gibt es da?
Was muß man da genau machen... null Ahnung habe ich noch nie gemacht. 
:-(

Sicher kann man nur den Bootloader flashen und dann per Bootloader die 
Software. Nur der andere Weg würde mich interessieren, erspart ein 2x 
programmieren. So kann man jeweils das aktuelle Mainprogramm gleich 
mitschreiben.



Danke, einen schönen Abend, Tobi...

von Peter D. (peda)


Lesenswert?

tobiTob wrote:

> Bootloader ist nun in ASM. Ausgabe .HEX
> Mainprogramm in C. Ausgabe .HEX

Hex-Files, die an unterschiedlichen Adressen stehen, lassen sich ganz 
einfach zusammenpappen:

Man muß nur bei einem den Enderecord (letzte Zeile) löschen und dann das 
andere anfügen.


Allerdings lassen wir in der Produktion absichtlich nur den Bootloader 
brennen und dann die Applikation per Bootloader.
Damit ist gewährleistet, daß der Bootloader beim Kunden auch wirklich 
funktioniert, wenn er mal ein Update kriegt.


Peter

von tobiTob (Gast)


Lesenswert?

Ok vielen Dank für alle Infos, ich habe was dazu gelernt und hoffe nun 
das ganze gebacken zu bekommen.

verbeug danke Tobi...

von tobiTob (Gast)


Lesenswert?

Ich bins nochmal mit einem bestimmt kleinen Problem...

Ich weiß nun nur mal wieder wie man es in ASM machen würde, in C geht's 
bestimmt auch...

Ich will mir lediglich eine CRC merken die sollte aber immer am Ende im 
Flash liegen also in den letzten beiden Stellen VOR BOOTGO...

In ASM würde ich es so machen...

.org BOOTGO-1
FIRMCRC:    .db 175,194    ;CRC

Danke im voraus... Gruß Tobi...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter Dannegger wrote:

> Hex-Files, die an unterschiedlichen Adressen stehen, lassen sich ganz
> einfach zusammenpappen:

Für avrdude braucht man das nicht, man kann auch mit zwei separaten
-U Optionen beide Dateien angeben.  Gelöscht wird der Flash natürlich
dabei nur einmal. ;-)

tobiTob wrote:

> Ich will mir lediglich eine CRC merken die sollte aber immer am Ende im
> Flash liegen also in den letzten beiden Stellen VOR BOOTGO...

Eine separate .section anlegen und diese per Linkeroption
--section-start an diese Stelle schieben.

von tobiTob (Gast)


Lesenswert?

eigendlich sollte es ein extrad theard werden :( hab ich nicht 
aufgepasst sorry!

>> Eine separate .section anlegen und diese per Linkeroption
>> --section-start an diese Stelle schieben.

Ja da steh ich auf dem Schlauch.
Wie läuft das?
Habe folgenes probiert:
1
#define CRC_SECTION   __attribute__ ((section (".crcsection"))) 
2
3
CRC_SECTION
4
static void dummy_crc_section(void){
5
static const byte [] CRCL = 128;
6
static const byte [] CRCH = 96;
7
}

bei den Linker Optionen hab ich:

--section-start CRC_SECTION=0x6000 angegeben,

das klappt so nicht, was mach ich da falsch?

Habe im toturial auch nochmal nachgesehen, finde keine rechte 
Beschreibung dazu schnief


Gruß Tobi...

von kosmonaut_pirx (Gast)


Lesenswert?

hallo,

>das klappt so nicht, was mach ich da falsch?

das klappt so nicht, weil du verflixt nochmal nicht vollständig lesen 
tust :)
weder was der linker dir an fehlermeldungen ausspuckt, noch was in der 
FAQ steht. den link dahin gabs hier schon mal, von den anderen hinweisen 
hier möchte ich gar nicht reden.

>bei den Linker Optionen hab ich:
>--section-start CRC_SECTION=0x6000 angegeben

in anwendung der hinweise aus der avr-libc-FAQ: "How do I relocate code 
to a fixed address?"

--section-start=.CRC_SECTION=0x6000

sollte es tun. im tutorial habe ich auch nichts gefunden, btw.

bye kosmo

von kosmonaut_pirx (Gast)


Lesenswert?

korrektur, es muss

--section-start=.crcsection=0x6000

heissen. groß- und kleinschreibung ist bestimmt wichtig.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

1
#define CRC_SECTION   __attribute__ ((section (".crcsection"))) 
2
3
static const uint16_t crc CRC_SECTION = 24704;

Den Inhalt von .crcsection musst du mit avr-objcopy in ein eigenes
Hexfile auslagern und separat programmieren.  Das ist vergleichbar
mit dem Erstellen des EEPROM-Ladefiles, für das du zahlreiche
Beispiele finden solltest.

von tobiTob (Gast)


Lesenswert?

Ok danke Euch!
Ich gib ja zu das es Neuland ist, ich bin wohl etwas eingefahren und hab 
mich etwas schwer beim Nachvollziehen der einzelnen Passagen. :-(

Ich habe nun folgenes gemacht...
1
#define CRC_SECTION __attribute__ ((section (".crcsection")))
2
const uint8_t pgmcrcl CRC_SECTION = 12;
3
const uint8_t pgmcrch CRC_SECTION = 55;

Nicht wundern, ich will mir von der CRC einmal das low und einmal das 
high speichern, es geht sicher auch...

const int pgmcrc CRC_SECTION = 5512;

Angemeldet habe ich die Section über die Memorysettings im AVR Studio, 
scheint zu klappen. ;-)

ein "static" davor bewirkt das FF an den Speicherstellen liegt. Also 
lass ich das mal... ;-)

Danke für eure Hilfe, MfG Tobi...

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.