Hallo, zusammen,
ich habe hier ein Problem, das mich langsam in den Wahnsinn treibt,
vielleicht
kann mir von Euch jemand zeigen, wie ich aus diesem Film herauskomme.
Bin versierter Entwickler, aber das hier ist mir zuviel Neuland:
Hardware: Ein Crumb 128-Board von Chip45, aufgesetzt auf ein eigenes
Eva-Board,
Programmer: Ein STK200 kompatibler ISP-Dongle, selbstgeschnitzt,
funktioniert soweit ganz gut
Entwicklungsumgebung ist die WINAVR-Suite mit AVRDude als Pgm.-Software
Diverse Progrämmchen zum Betrieb von RS232, eines LC-Grafikdisplays etc.
funktionieren soweit gut. Das Testsystem läuft also grundsätzlich
Jetzt das Problem: Für spätere Anwendungen brauchts einen Bootloader.
Um einen Einstieg ins Thema zu kriegen habe ich einen Bootloader von
CHIP45.COM (ATMEGABOOT) heruntergeladen
und kompiliert.
Und geflasht.
Und geht nicht.
Warum?
Makefiles sind mir noch etwas fremd, aber alle zur Kompilierung nötigen
Info, Parameter und Flags sollten sich dort
finden.
OK, die Fuses des AVR:
LFUSE = 0xFF (im wesentlichen Taktparam., geht auch gut so),
HFUSE = 0x98, d. h. BOOTSZ1=BOOTSZ0=0, BOOTRST=0 -> Der Bootvektor
sollte also auf 0x1E00 zeigen.
Setze ich das BOOTRST-Bit probehalber auf 1 (-> HFUSE=0x98) starten
Programme auch ganz normal bei 0x00000.
Das Makefile enthält die Zeilen:
ifeq ($(PRODUCT),CRUMB128) // OK, ist oben definiert
MCU_TARGET = atmega128 // falsch, aber vorläufig
OKgibts noch Probleme mit dem CAN128
#MCU_TARGET = at90can128 // noch nicht in devlist
LDSECTION = --section-start=.text=0x1E000 // GENAU! Hierhin muss es
ISPFUSES = avrdude -c $(ISPTOOL) -p m128 -P $(ISPPORT) $(ISPSPEED) -u
-U efuse:w:0xff:m -U hfuse:w:0xc8:m -U lfuse:w:0xdf:m
ISPFLASH = avrdude -c $(ISPTOOL) -p m128 -P $(ISPPORT) $(ISPSPEED) -V
-U flash:w:$(PROGRAM)_$(PRODUCT)_$(BUILD).hex
Ein Blick aufs Hexfile mit Galep zeigt auch einen ab 0x0000 leeren
Puffer, aber Code an der richtigen Stelle:
1E000: 0C 94 46 F0 0C 94 63 F0...............................
Schätze, das ist der Startup-Code.
OK, um die Funktion des Bootloader-Codes mal grundsätzlich zu
überprüfen, habe ich den Loader abgekürzt, und schlicht
folgende Zeilen eingefügt:
/* main program starts here */
int main(void)
{
// 'vorhandener Code..unwichtig:
uint8_t ch,ch2;
uint16_t w;
asm volatile("nop\n\t");
/* set pin direction for bootloader pin and enable pullup */
/* for ATmega128, two pins need to be initialized */
#ifdef _AVR_ATmega128_
BL_DDR &= ~_BV(BL0);
BL_DDR &= ~_BV(BL1);
BL_PORT |= _BV(BL0);
BL_PORT |= _BV(BL1);
#else
BL_DDR &= ~_BV(BL);
BL_PORT |= _BV(BL);
#endif
////////////////////////////////////////////////////////////////////////
/////////////////////////
Hier nun mein Code, der nicht funktioniert:
#define LEDRD_PORT PORTG
#define LEDRD PG0
#define LEDRD_DDR DDRG
#define LEDRDON LEDRD_PORT |= _BV(LEDRD)
#define LEDRDOFF LEDRD_PORT &=~_BV(LEDRD)
LEDRD_DDR |= LEDRD;
while (1)
{
LEDRDON;
LEDRDOFF;
}
Und jetzt frage ich mich, warum ich am Port G0 nichts messen kann.
Der Code läuft, wenn ichs mit normalem Resetvektor 0x0000 flashe.
Eine merkwürdige Sache: Der AVRDude bringt NACH der Programmierung die
Meldung
"avrdude.exe: 123578 bytes of flash written"
1. Warum soviele. Bootloader hat doch nur ein paar kB und sollte ab
1E000 geflasht werden?
2. Ist das normal, dass der STK200/AVRDude für 123578 Bytes 90sec(!).
brauchen?
3. Wieso ausgerechnet ca 8kB weniger als ins FlashROM passt (128kB)?
4. Warum aber sinds nicht exakt 8kB (8192Byte) sondern nur 7940 Byte
weniger?
Liegt da der Hund begraben? Aber warum? Ich komm nicht drauf. Hab schon
alle Foren etc. abgegrast....
Wer kann hier helfen? Ich danke im voraus vielmals für Tips.
Grüßle
Andreas Paulin
hallo,
ideen jede menge, aber imo recht konfus, was so geschrieben steht. aber
der reihe nach.
>Setze ich das BOOTRST-Bit probehalber auf 1 (-> HFUSE=0x98) starten>Programme auch ganz normal bei 0x00000.
das ist falsch ( und hoffentlich ein tippfehler).
hfuse sollte dafür 0xC9 werden.
>Eine merkwürdige Sache: Der AVRDude bringt NACH der Programmierung die>Meldung>"avrdude.exe: 123578 bytes of flash written">1. Warum soviele. Bootloader hat doch nur ein paar kB und sollte ab>1E000 geflasht werden?
ist bei avrdude so, da wird von 0x0000 bis zum ende geflash-ed. leider.
2. Ist das normal, dass der STK200/AVRDude für 123578 Bytes 90sec(!).
brauchen?
das ist normal.
> 3. Wieso ausgerechnet ca 8kB weniger als ins FlashROM passt (128kB)?
keine ahnung, bin grad zu faul, nachzurechnen :)
4. Warum aber sinds nicht exakt 8kB (8192Byte) sondern nur 7940 Byte
weniger?
möglicherweise ist der bootloader nicht größer.
wie testest du den port g?
bye kosmo
Hallo, Joe,
danke fürs Feedback. Die Punkte:
"das ist falsch ( und hoffentlich ein tippfehler)."
hfuse sollte dafür 0xC9 werden."
Stimmt. Tippfehler. Bit 0 Muss 1(!) sein, dann ist Reset bei 0x00000.
War Tippfehler, Unterschied 0x99<->0xC9 ist unwesentlich, ist nur das
JTAGEN-Bit, das hat imho nichts mit dem reset zu tun..werds aber auch
mal checken.
"ist bei avrdude so, da wird von 0x0000 bis zum ende geflash-ed.
leider."
OK, das erklärt das.
Da kommt so oder so ein Zeitproblem bei der Entwicklung auf mich: zu
lange Turnaround-Zeiten.
Gibts eine andere Pgm-SW, die mit STK200 arbeitet und nur die zu
flashenden Bereiche brennt? Sonst wird das Herumprobieren am Bootloader
zur Mühsal bis unmöglich
Oder würdest Du eine komplett andere Prommer/Software-Kombination
empfehlen?
OK, zur Sache:
Den Port schaue ich mir mit dem Oszi an. Da muss sich (bei
Bootloader-modus, HFUSE = 0xC8) im us-Bereich was tun.
Tut sich aber nichts.........
Ich habe auch Probleme, die Fragestellung zu verstehen ;-)
Das glaube ich verstanden zu haben:
Target ist AT90CAN128, der aber als ATMEGA128 programmiert wird.
Usercode nach 0x0000 geladen, funktioniert.
Abgespeckter Bootloadercode nach 0x1E00 geladen, funktioniert nicht.
Abgespeckter Bootloadercode nach 0x0000 geladen, funktioniert
(BOOTRST-Bit probehalber auf 1)
Funktionieren heisst LED an PORTG lässt sich toggeln.
> 3. Wieso ausgerechnet ca 8kB weniger als ins FlashROM passt (128kB)?
Hast du schon probiert die Boot-Fuses erst NACH dem Flashen zu setzen?
Nicht dass durch die gesetzte Boot-Fuses der genau 8 KB grosse
Bootloaderbereich schreibgeschützt ist...
Ansonsten mach nach dem Flashen einen Memdump und schau nach, was im
Bootloaderbereich drin steht.
@ Stefan: Danke Dir.
Ja, das IST so durcheinander. Schlag mich nicht, wenns nachher was ganz
simples war.....
Joes Posting scheint mir den Grund für "8kb weniger" zu erklären: Der
AvrDude flasht echt ALLES mit Nullen voll bis 0x1e000, dann den
'Loader'.
Da der aber nur ein paar hundert Byte hat, siehts FAST so aus wie wenns
128kB - 8kB wären.
Die Bootsize-Fuses haben damit nichts zu tun, für programmierbarkeit
oder nicht sind die Lock-Fuses zuständig, und die sind alle '1' (=freier
R/W-Zugriff).
Oki, einen Memdump könnte ich mal machen.....NEIN, der Avrdude HAT doch
schon erfolgreich verifiziert!
@ Joe: Die HFUSE sollte WIRKLICH 0xD8/0xD9 sein, nicht 0xC8, 0xC9.
Der Unterschied liegt im Watchdog: Wenn diese Fuse (Bit4) als '0'
programmiert wird, ist der Watchdog eingeschaltet.
Wichtige Erkentnisse:
- Watchdog MUSS ausgeschaltet bleiben (HFUSE =0xD8/9)
- Der Avrdude im Terminalmode MUSS mit 'quit' verlassen werden, ERST
dann startet der AVR neu.
Bleibt noch ein anderes Problem:
Warum führt der Avrdude IMMER einen Chip erase durch?
Per AvrdudeGUI lasse ich nun erst den 'Bootloader' MIT Chip-Erase (Param
-e) nach 0x1e000 brennen und dann OHNE Chip-Erase die 4K
Standardfirmware @0x00000.
Der AvrdudeGUI schiebt zu letzterem folgende Kommandozeile raus:
"E:\Programme\WinAVR\bin\avrdude.exe" -p m128 -c stk200 -C
"E:\Programme\WinAVR\bin\avrdude.conf" -P lpt3 -U flash:w:"E:\CSS
Projekte\RolliX\Firmware\HelloCSS\HelloCSS.hex":i -v -V -E reset,novcc
Stimmt, der Parameter '-e' ist nicht da. :)
Der Bootloader wird aber trotzdem gelöscht :( wie ein Memdump ab
0x1E000 zeigt (Danke, Stefan :)
Warum???
warum nicht? das ist ein chip erase, da wird nun einmal alles platt
gemacht (naja, fast alles). auszuschalten via -D option
warum lädst du die firmware nicht über den bootloader? da solltest du
das problem nicht haben. und dafür ist der auch gedacht, ist kein
selbstzweck, das ding.
bye kosmo
ach ja: von welcher mcu reden wir denn überhaupt? doch wohl dem mega128,
oder?
>Die HFUSE sollte WIRKLICH 0xD8/0xD9 sein, nicht 0xC8, 0xC9.>Der Unterschied liegt im Watchdog: Wenn diese Fuse (Bit4) als '0'>programmiert wird, ist der Watchdog eingeschaltet.
man, das hättst ja mal konkret herausstellen könnnen.
bin_grad_tierisch_bedient>Hardware: Ein Crumb 128-Board von Chip45, aufgesetzt auf ein eigenes
was du meinst, ist ein
"Crumb128-CAN"
da sich diese in der hfuse unterscheiden, hat mich das erst stutzig
gemacht. ja klar, watchdog aus, was'n sonst.
junge junge :)
@ kosmo:
Der Sinn eines Bootloaders ist mir schon klar, kosmo.
Ich lade die Firmware nicht über den Bootloader, weil das schlicht nicht
funktioniert.
Der Bootloader ist der bei www.chip45.com herunterladbare 'ATMegaBoot'.
Hierzu gibts auch Makefiles für alle Varianten der dort angebotenen
Prozessormodule.
Fast alle.
Ich habe ein Crumb128-CAN.
Für Crumb128-CAN gibts da noch GARNICHTS.
Also behelfe ich mir mit Code für den ähnlichsten Controller. Den
'Crumb128'.
Es passt aber keins der Makefiles so richtig, weil nirgends die
Konstante F_CPU auf 16000000 steht: Es sind Makefiles für den CRUMB128
mit 14.75 MHz und 20.0MHz vorhanden, aber keines für einen CRUMB128-CAN
mit 16MHz.
Davon hängt aber wiederum die Baudrate der ser. Schnittstelle ab.
Und darüber soll ja die Software geladen werden.
Also: Falsche Taktangabe bei Compilierrung macht download unmöglich.
ergo: Rein ins Getümmel und die Sache ändern. Und wenns dann nicht läuft
speckt man normalerweise den Code auf rudimentäre Reste ab und geht
zurück zur Badstraße.........
Im zugehörigen Makefile werden übrigens auch auch die Fuses (hier:
HFUSE)definiert. Siehe oben.
Genauso, wie Du oben vorgeschlagen hast: 0xC8
Soweit sind Dr. Lins und Du also einer Meinung im Bit#4
Was den ATMEGA128 betrifft, voll OK.
Was leider für meinen Fall anders ist: Das Bit #4 der HFUSE ist beim
ATMega128 die 'CKOPT', bei meinem AT90CAN128 aber das 'WDTEN'-Bit.
Da läuft bei mir also der Watchdog.........
Ergo: ATMega128 und AVR90CAN128 haben unterschiedliche HFUSEs.
In EINEM Bit unterschiedlich. Eben im Datasheet gesehen.
Und ich renne voll ins Messer.
Thanks a lot. Ich tret dem blöden Lins die Eier blau. Ich hab das
Crumb128CAN gekauft um nen leichten Einstieg zu kriegen, und nicht in
Makefiles zu stochern!
OK, jedenfalls 1 Schritt weiter.........
Aber zum Avrdude. Du schreibst:
"warum nicht? das ist ein chip erase, da wird nun einmal alles platt
gemacht (naja, fast alles). auszuschalten via -D option"
Weil ich die Option "-e: perform a chip erase" ausgeschaltet hatte.
Deshalb sollte er keinen chip erase durchführen.
Das war meine Frage.
Aber Du sagst da was Gutes: '-D' gibts auch noch.
Ich war hier auf die Option '-e' fixiert.
Wieder ein Schritt....... wichtig für später.......
Jetzt nehme ich mal alle erkentnisse zusammen, und schau, obs nicht
langsam klappt. Bleiben Sie dran ;-)
OK, Kosmo, danke für den Tip, hab die 0.81 mal runtergelden, und werde
gleich die Fuses mal checken.....
Aaaaaaaaaaaaber:
Grundsätzlich möchte ich schon aus eigener Kraft ein Winzprogramm
hinkriegen, das es schafft
- mittels Bootvektor auf 0x1E000
- nach einem Reset
- den dort vorhandenen Code auszuführen.
Und der geht mittlererweile so:
DDRD |= 0x40;
while (1)
{
PORTD |=0x40;
PORTD &=~0x40;
}
SOWEIT möchte ich als Entwickler die Maschine schon in den Griff
kriegen.
Wenn DAS dann mal grundsätzlich läuft ists ok, dann werde ich klar den
vorhandenen Bootloader verwenden. Den Teufel werde ich die ganzen
Flash-Algorithmen neu erfinden, das braucht ja ewig ;-)
Aber erstmal müssen die wesentlichen Grundlagen stimmen.
Du hast bereits sichergestellt, dass dein main() Code grundsätzlich
lauffähig ist (Test als Programm ab 0x0000 - LED blinkt).
Du hast bereits sichergestellt, dass dein Programm von AVRDUDE in den
Bootloaderbereich geflasht wird (Memdump).
Du musst jetzt kontrollieren, ob das Bootloader-Programm auch in dem
Bootloaderbereih lauffähig ist.
D.h. ob dein bewusst geschriebener Code (main()) und der dazugebundene
Code (C Startupcode) von der Toolchain korrekt für die Adresse 0x1E00
übersetzt sind.
Dafür würde ich Option der Toolchain benutzen, die mir ein ASM-Listing
(*.LSS) erzeugt. Dieses Listing würde ich dann mit dem Datenblatt "8-bit
Microcontroller with 32K/64K/128K Bytes of ISP Flash and CAN Controller
- AT90CAN32 AT90CAN64AT90CAN128" und dem Bereich über den Bootloader
(S. 61ff und 320ff) vergleichen.
Hi, Stefan,
danke für den Tip. Die Listings enden aber mit *.LST ;-)
Egal, ich habs gefunden: Ich hab das Listing mal komplett angehängt. Bin
kein Assemblerkenner, aber ich sehe da ein Programm, das bei 0x1E000
anfängt, eine Vektortabelle, irgendwelches Startupzeugs, einen Sprung
mach main...
und dann:
0001e278 <main>:
1e278: cf ef ldi r28, 0xFF ; 255
1e27a: d0 e1 ldi r29, 0x10 ; 16
1e27c: de bf out 0x3e, r29 ; 62
1e27e: cd bf out 0x3d, r28 ; 61
1e280: 00 00 nop
Das hier ist wohl mein Code:
1e282: 8e 9a sbi 0x11, 6 ; 17
1e284: 96 9a sbi 0x12, 6 ; 18
1e286: 96 98 cbi 0x12, 6 ; 18
1e288: 96 9a sbi 0x12, 6 ; 18
1e28a: 96 98 cbi 0x12, 6 ; 18
1e28c: fb cf rjmp .-10 ; 0x1e284 <main+0xc>
OK, da werden Bits in den IO-Adressen 0x11 und 0x12 gesetzt und
gelöscht.
???????? HÄ???
Laut Datasheet AT90CAN128, IOMemory:
0x11: PORTF
0x12: PING
Mein Source MEINTE aber PORTD, bzw. DDRD. Sollte da etwa....
Blick ins ATMEGA128-Datasheet, IO-Memory::
0x11: DDRD
0x12: PORTD
So. Danke. Das wars. Mein Standardprogram@0x00000 hat schon die
AT90CAN128-Header eingebunden, den Bootloader von Chip45 habe ich mit
'ATMEAG128-Option kompiliert, weils für das Crumb128-CAN von Chip45.com
gar keinen expliziten Bootloader gibt. Und für mich als AVR-Newbie der
ATMEGA128 sehr ähnlich dem AT90CAN128 schien.
Und als AVR-Newbie portier ich halt nicht mal kurz den ganzen Bootloader
auf einen anderen Controller, ne?!
Fazit: Den ganzen Code für das Crumb128-Modul kann sich der Herr Dr.
Lins in seinen Doktorarsch schieben, weil das ganze Zeug nicht für sein
CRUMB128-CAN-Modul taugt!!
Die zwei Controller unterscheiden sich GRAVIEREND!
Muss man wissen, ich komme aus dem PIC-Lager, da sind alle SFR-Adressen
ungefähr gleich...............
Danke, Stefan, danke, Kosmo, schätze jetzt komme ich weiter.
Und jetzt mache ich mit dem Bootloader von Martin Thomas weiter, der
Lins hat verschissen!
tut mir leid, aber mit deinem ton hast du dich grade rausgekickt :(
wenn du im makefile nicht siehst, dass das für den mega128 gemacht ist:
selber schuld.
sicher steht auf der website, dass der bootloader auch für den
at90can128 gemacht ist. dann aber bitte gehirn einschalten, das ändern
und bei chip45.com bescheid geben, damit andere nicht auch da rein
stolpern.
bye kosmo
@ kosmo: Dochdoch, Kosmo, der Ton ist berechtigt. Aber voll.
Du hast keine Ahnung, wie lange ich an dem Thema schon rumnage.........
Schließlich haben wir die zwei Crumbs ja bestellt, um uns den Einstig
ins Thema einfacher zu machen. Um Softwareunterstützung zu erhalten, um
schneller mit diesem neuen Controller starten zu können ;-)
Das Resultat war ne kleinere Doktorarbeit. Als Anfänger...........
Das MCU_TARGET im Makefile habe ich schon gesehen. Es gab aber keine
Alternative, also habe ich das genommen, was meinem Crumb am ähnlichsten
schien:
Crumb128 statt Crumb128CAN. Die Ähnlichkeit ist frappierend, ne?!
Und wenns keine andere Firmwarevariante vom Hersteller für mein Produkt
gibt, gehe ich mal davon aus, dass das schon passen wird.
Wie gesagt: JETZT weiß ich, dass auch ähnlich erscheinende AVR
gravierende Unterschiede, auch in der SFR-Belegung, haben.
Aber dem Lins mal Bescheid sagen, das werde ich ;-)
@kosmo: Danke. Guter Background
Naja, das Material von Chip45 ist auch nicht sooo schlecht. Ohne diese
Zusammenstellung von Software hätts noch länger gedauert. Das meiste IST
ja auch für alle Produktvarianten brauchbar.
Ich hab mir nur prompt den Bootloader rausgesucht, der nicht für den
AT90CAN128 angepasst hat und bin halt in die Falle gelaufen..........
mit ner neuen uC-Familie im Gepäck, IDE-verwöhnt in der
Kommandozeilen-Welt unterwegs, Makefiles und CFLAGS... gg