Hallo *,
ich hab das Forum die letzten zwei Tage durchsucht, konnte aber keine
Antwort auf meine Fragen finden.
Es geht darum, dass ich mit einem LPC2129 bzw. LPC2119 einen
CAN-Bootloader schreiben soll, d.h. dass der Controller über CAN-update
fähig gemacht wird und nicht über den eh schon vorhandenen seriellen
Bootloader.
Nun ist das mein erstes ARM-Projekt, aber ich spiele schon etwa 4 Monate
mit ihm herum.
Die Routinen für FullCAN (mit Msg-Filter) habe ich auch schon
implementiert, ebenso habe ich auch schon via IAP einen Flashbereich
beschreiben können. (Das ganze auch in Kombination: 24 Bytes via CAN
gesendet und dann irgendwo in den hinteren Flashbereich geschrieben, wo
kein Code mehr liegt, aber ich glaube der Code hierzu interessiert
aktuell eh niemanden o_O)
Doch nun zu meinen Fragen:
Der Bootloader soll durch einen Befehl, der über ein properitäres
CAN-Protokoll ankommt aufgerufen werden können. Da der Source für die
IAP-Routinen und für die CAN-Routinen in eigenen Files liegt, weiß ich
selbst sowieso schon mal nicht, wo der Compiler bzw. der Linker den
ganzen Kram im Flashspeicher ablegt.
* Wie kann ich dem Compiler/Linker mitteilen, dass genau dieser Code -
sagen wir mal - im nullten Sektor liegen soll (0x00000000 - 1FFF) und
eben
der restliche Code erst ab 0x00002000 beginnen soll?
* Muss ich dann irgendwas beachten, wenn ich von dem "normalen" Programm
in diesen Bootloader springen will? (Im RAM Ressourcen freigeben? Wenn
ja, wie?)
* Muss ich die CAN-Routinen noch mal in das Hauptprogramm
implementieren, wenn ich dort auch CAN-Kommunikation eine haben möchte?
Oder kann es vom Hauptprogramm quasi eine Verknüpfung zu diesen Routinen
im Bootloader geben?
* Muss ich generell auf meinem Board dann quasi 2 Programme einbrennen
(einmal den Bootloader und einmal das Hauptprogramm), solange ich noch
keine Gegenstelle habe, die den Bootloader bedient?
* Gibt es generelle Dinge bei dem Schreiben eines Bootloaders zu
beachten? (Stolperfallen, etc.?)
Ich möchte hier von niemandem eine Entwicklung abverlangen, ich werd das
alles schön selbst schreiben um es zu erlernen, aber ich bin für jeden
Hinweis sehr dankbar!
P.S. Ich bin auch mit dem Manual vertraut, aber dort steht nur der
UART-Bootloader drin beschrieben sowie die IAP Fkt, bzw. die
CAN-Register.
--Magnus
Hardware:
Olimex LPC212X-B Board Rev. 2, später soll jedoch ein LPC2119 eingesetzt
werden; ARM-USB-OCD
Toolchain:
RapidiTTY Lite 1.5 (mit Gnu-ARM-Compiler, Eclipse IDE und ARM-USB-OCD
JTAG Debugger)
Programmiert wird über die
Also der Bootloader gehört an den Anfang 0x00000000.
Die Applikation in einen höheren Bereich. z.B. ab 0x00002000
Es handelt sich dabei wirklich um zwei unterschiedliche Programme,
die auch einiges doppelt haben müssen. Wie bei dir z.B. die CAN-
Funktionen. Erzeugen kannst du Bootloader und Applikation natürlich
auch aus einem Quellcode, den du über den Präprozessor und unter-
schiedliche Linker-Files steuerst.
Beim Sprung vom Bootloader in die Applikation mußt du beim ARM
schauen, dass du die Interruptvektoren passend verbogen kriegst.
Zurück zum Bootloader gehts per Reset oder Sprung an 0.
Vielen Dank für die beiden Antworten:
Nun ist es in meinem Kopf schon mal ein wenig sortierter, was die
Trennung von Bootloader und eigentlicher Applikation betrifft ;)...
Das Beispiel werde ich mir gleich mal anschauen, bin zwischenzeitlich
auch auf die folgende Seite gestoßen:
http://water.cse.unsw.edu.au/esdk/lpc2/boot-loader.html
Unklar ist mir jedoch noch immer gänzlich, wie man Interruptvektoren
verbiegen kann o_O...
Wie gesagt, ist mein erster Bootloader.
Magnus wrote:
> Unklar ist mir jedoch noch immer gänzlich, wie man Interruptvektoren> verbiegen kann o_O...
Man kann sie via Steuerregister an den Anfang vom RAM legen. Wie das
geht steht irgendwo in der Doku.
Ok, ich werde nachsehen. Das Manual ist ja eigentlich gar nicht mal
soooo schlecht ;)..
Noch eine Frage bleibt über:
Also ich mach mich zunächst ran und brenne den Bootloader dann in den
ARM.
* Wenn ich später dann die Apllikation über CAN uploaden will, muss ich
dann vorher irgendwo (make-file? sonst wo?) dem Compiler oder Linker
sagen, dass das Programm erst ab 0x00002000 beginnt? Oder muss der
Bootloader diese Anpassung übernehmen? (Was ich mich schwierig
vorstelle, da im Maschinencode ja bestimmt ausreichend direkte Adressen
drin stehen werden, oder?)
Das erzählst du deinem Linker.
Ich habe für meinen Bootloader (LPC2368), der über ein proprietäres
Protokoll sowohl CAN, USB, als auch UART versteht, folgendes als groben
Einstieg - insbesondere was Interruptvektoren angeht - hergenommen, ohne
dabei die Funktionen von TNKernel zu betrachten oder zu nutzen.
http://www.tnkernel.com/usb_fw_upgrader.html
@Magnus,
zuerst ein sehr gut gemeinter Rat, benuetze auf jeden Fall die internen
ISP Routinen, also tue dir selbst einen Gefallen und schreibe den Kern
des Bootloaders nicht neu. (Damit beschaeftigt sich die Seite, die Du
gefunden hast)
Das Interface des Bootloaders ist eine andere Sache, CAN anstelle von
UART zu benuetzen hat mit dem Kern nichts zu tun und stellt keine
grundsaetzliches Problem dar, also nur Mut, wird schon schiefgehen.
Das Program muss zwar nicht auf Adresse 0 stehen aber es muss mindestens
ein Sprung zum Programm dort stehen, dort gibt es eine Abfrage auf
Status ob es ein Reset war, ob ein Bootloaderstart wirklich gewuenscht
ist oder ob der Chip bereits programmiert ist und keine Programmierung
erfolgen soll.
Ich bin sicher die bereits beschriebenen Links erlaeutern das.
Gruss, Robert
Hej Robert!
Als ich gestern dann die eine Seite gelesen hatte wurde mir das mit dem
Neuschreiben, der eigentlich IAP/ISP Befehle auch klar. Klang sehr nett,
aber ich glaube, dass ich mittlerweile bei der Bootloader Version 1.65
nicht mehr unbedingt nötig. (Der Autor hatte ja schon Probleme mit dem
eigentlich Bootloader selbst.)
Aktuell bin ich dabei einen IAP Treiber zu schreiben/portieren, beruhend
auf dem IAP-Treiber von Andreas Weschenfelder, der im Artikel
Beitrag "LPC2148 IAP USB Bootloader"
seine Sourcen zur Verfügung gestellt hat.
Die CAN-kommunikation selbst habe ich schon von den yahoogroups quellen
an mein Board angepasst (da mussten einige Datentypen geändert werden).
Und wie ich dem Linker sage, dass er das Hauptprogramm (hab das ganze
jetzt als 2 verschiedene Projekte angelegt) dann an die 0x2000 legen
soll, bekomme ich (hoffentlich) auch noch raus, wenn ich den Bootloader
fertig hab ;)...
@all:
Vielen Dank für die Aufklärung von euch allen ;).
Hallo Andreas,
da ich ja grade mit deinen Quellen arbeite, eine kurze Frage:
Beim Beschreiben des Flashes sollten alle Interrupts disabled sein.
Ist die Erase-Funktion nicht ebenso eine Schreibfunktion? Bei dieser
werden die Interrupts nicht deaktiviert.
Ist das korrekt so? Oder sollte man auch hier die Interrupts einfrieren?
@Magnus,
mal angenommen die Interrupts sind nicht remapped ins SRAM, dann ist es
sehr empfehlenswert Interrupts auch beim Erase zu sperren, das Programm
wuerde sonst ins Niemandsland springen.
Solange alle fraglichein Routinen im SRAM sind, koennten meines Wissens
nach auch Interrupts waehrend des Loeschens / Schreibens ausgefuehrt
werden. Sobald jedoch eine Verzweigung ins Flash stattfindet ist es
undefined.
Gruss, Robert