Hallo,
ich möchte den LPC11C24 über CAN booten. Das Programm schreibe ich in C.
Nun ist meine Frage, ob sich jemand mit der write to RAM Funktion
auskennt. Denn ich weiß zwar in welchem Format ich den ersten Befehl
rausschicken muss, also den Schreibbefehl den schicke ich ungefähr so
raus
ID = 0x67d data[8] = [0x23, 0x15, 0x50, 0x00, 0x00, 0x03, 0x00, 0x10],
doch danach weiß ich nicht wie ich die Daten auf den RAM schreiben kann.
meine Idee wäre:
data[8] = [0x21, 0x50, 0x1F, 0x01, data1, data2, data3, data4]
und dann in einer for Schleife
abwechselnd
data[8] = [0x00, data...]
data[8] = [0x10, data...]
und dann am Ende
data[8] = [0x11 bzw. 0x10, data...]
muss ich noch irgendetwas beachten? Denn so funktioniert es bei mir
nicht.
Danke!
Pamela
Was genau möchtest Du machen? Booten vom PC aus? Dann wird keine
Software benötigt, der LPC11C24 hat einen CAN-Bootloader im ROM.
Lediglich den PC anschliessen (z.B. PEAK PCAN-USB), in FlashMagic
LPC11C24 CAN auswählen und ISP-Go zur Startadresse (Flash oder RAM).
Oder Firmware-Upgrade vom PC aus?
http://forum.flashmagictool.com/index.php?topic=3929.0;wap2
Oder Booten von einem anderen CAN-Gerät?
Kommt drauf an, wie der Bootloader aufgerufen werden soll: ISP (mit
CANopen) oder IAP mit Reinvoke ISP. PIO0_1 und PIO_3 müssen low sein.
Siehe Kapitel 26 im UM10398. Vermutlich willst du IAP; dann aber Befehl
57 und nicht 67. War früher wohl mal anders; also aktuelles UM nehmen.
Und danach natürlich Compare usw., ob auch alles richtig geklappt hat.
Ich möchte von einem anderen CAN Gerät aus booten. Die CAN Nachricht
schicke ich von einem MCP2515 über MCP2551 zum LPC11C24 LPCXpresso
Board. Somit ist das mit dem FlashMagic leider nicht möglich, aber danke
für die Antwort.
Die Kommandos der ISP per CAN sind ja einigermaßen dokumentiert, wenn
auch nicht besonders toll. Ich habe schon einmal einen CAN-Log gemacht,
wie sich FlashMagic mit dem Controller unterhält. Ich habe die Baustelle
aus verschiedenen Gründen nicht weiterverfolgt, man kann aber anhand der
Doku recht schnell das Prinzip verstehen und dann mit einem
x-bebliebigen Contoller die Funktionalität des FlashMagic nachbilden.
Pamela schrieb:> Ich möchte mit ISP (mit CANopen) den Bootloader aufrufen.
Laut UM sollte es so laufen: Bootloader starten (wie schon geschrieben).
Der Controller hört dann auf Identifier 0x67D.
Gemäß UM (26.6.4) wird in OD 0x5015,0 die RAM-Adresse geschrieben und
dann die Daten in 0x1F50,1.
Pamela schrieb:> Denn so funktioniert es bei mir> nicht.
Wie macht sich das denn bemerkbar? Ist er überhaupt im ISP-Modus? Frag
doch einfach mal z.B. über 0x1000 den Device Type ab. Wenn das schon
nicht geht, stimmt früher was nicht.
Du willst also an Adresse 0x10000300 schreiben.
Probier mal an ID 0x67D zu senden:
0x23, 0x15, 0x50, 0x00, 0x00, 0x03, 0x00, 0x10 (hast du ja schon)
0x21, 0x50, 0x1F, 0x01, 0x00, 0x00, 0x00, 0x00
0x00 +7 Datenbytes
0x01 +7 Datenbytes
0x00 +7 Datenbytes
.
.
.
beim letzten Frame dann
0x00 oder 0x01 (je nach dem), n auch je nach dem und mit l=1 diesen als
letzten Frame kennzeichnen.
Hallo,
also es hat glaube ich daran gelegen, dass ich bei
0x21, 0x50, 0x1F, 0x01 statt 0x00 danach gleich Daten mitgeschickt habe.
Außerdem dachte ich anfangs man muss die Daten so wie bei UART in
UUencode umschreiben und bei dieser Funktion hatte ich auch noch ein
Fehler somit wurden gar keine Daten geschickt.
Hallo allerseits,
ich programmiere mit Pamela am CAN Bootloader.
Chip löschen und neuen Code hochladen funktioniert mittlerweile
wunderbar,
nur das Starten des Codes aus dem Bootloader heraus klappt noch nicht.
Ich habe alle möglichen Startaddressen für den GO-Command ausprobiert,
aber es keine will funktionieren. Das reinschreiben und ausführen des
Commands scheint aber korrekt abzulaufen, da ich vom Chip nur
SDO-Acknowledges und keine AbortCodes bekomme.
Laut UM muss die Addresse ja mindestens 0x00000200 sein. Das ist auch
der Wert auf den ersten 4bytes der BIN-Datei (Ich nehme an das ist der
Reset-Vector).
Auch 0x00000000 bringt den Code nicht zum starten.
Die Checksum der ersten 7 IVT-Einträge wird berechnet und ab Position
0x1C in den Flash geschrieben, daran sollte es also auch nicht liegen.
Nach einem Powercycle (mit abgesteckten Bootloader-Pins) startet der
Code dann auch korrekt
Was mache ich falsch? Weiß jemand die richtige Execution Address?
P.S.: Wenn der Bootloader dann irgendwann mal komplett funktioniert,
werden wir den Code natürlich auch veröffentlichen!
Konstantin schrieb:> Die Checksum der ersten 7 IVT-Einträge wird berechnet und ab Position> 0x1C in den Flash geschrieben, daran sollte es also auch nicht liegen.
Das sollte für das GO-Kommando egal sein, da es m.W. nicht (wie beim
"richtigen" Reset) beim booten nach einem gültigen Usercode sucht.
Konstantin schrieb:> Was mache ich falsch? Weiß jemand die richtige Execution Address?
??? Du legst doch fest, was an der Adresse für Befehle stehen. Oder
andersrum: Du legst die Adresse dahin, wo der von dir gewünschte Befehl
steht.
> ??? Du legst doch fest, was an der Adresse für Befehle stehen. Oder> andersrum: Du legst die Adresse dahin, wo der von dir gewünschte Befehl> steht.
Ja, ich schreibe den Code ab Flashaddresse 0 und gebe das dann auch als
Execution-Address an. Funktioniert aber nicht.
>Leg doch NVIC_SystemReset(void) ins RAM und spring dahin ...
Habe ich auch mal probiert, klappt aber auch nicht.
Wenn ich allerdings zuerst den Flash beschreibe, dann im Bootloader
bleibe, den P0_1 von GND wegnehme und dann den GO-Befehl sende oder der
SystemReset ausführe, klappt es.
Der Reset-Code ist also korrekt, wie auch die Startaddresse 0, aber der
Chip scheint trotz allem noch den Pin zu samplen. Das sollte doch
eigentlich nur beim Ausführen des BootROMs passieren, oder?
NO_ISP wäre noch eine Option, allerdings müsste man dann im Usercode die
Möglichkeit vorsehen, das wieder abzuschalten, damit man bei Bedarf
neuen Code flashen kann.
"Startaddresse 0"
Im Flash steht ab Adresse 0 erst einmal die "VectorTable",
keine echter Code, den man anspringen kann.
In der VectorTable steht an Adresse 0 der Stack Top
und an Adresse 4 der PC, wo der Code beginnen soll.
Dies ist vermutlich der Wert, an den man springen sollte.
(siehe auch Email von mir an Pamela)
Da der Cortex-Mx nur Thumb2-Code verarbeiten kann,
und Thumb-Adressen (wenn ich es richtig im Kopf habe)
ungerade sind, kann es sein, dass man auf diese
Adresse noch 1 draufzählen muss???
Vielleicht aber auch egal, weil es der ISP
sowieso ausmaskiert/selber setzt (bei 2. Argument "T").
Vielen Dank für die Mail und die Antwort hier!
Die Addresse an Position 4 hatte ich auch schon versucht. Die ist
ungerade (0x315) und bringt beim GO-Command den SDO_ADDR_ERROR
Abort-Code als Antwort. Auch mit +1 auf 0x316 meckert er rum.
Der CAN Bootloader aktzeptiert nur Addressen, die ein ganzzahliges
Vielfaches von 4 sind. Mit den nächst- und naheliegenden Addressen 0x300
(ab hier scheint Code zu stehen, vorher viel 0xFF), 0x314 und 0x318
startet er nicht (ist aber nicht mehr im Bootloader).
Noch ein anderer Punkt:
Wir möchten die Möglichkeit haben, den Chip jederzeit OHNE einen Jumper
zu setzen mit neuem Code updaten können (das Gerät wir im eingebauten
Zustand nicht mehr einfach zugänglich sein). Da nun der Bootloader aber
keinen Timeout hat, kann man ja nicht einfach immer den Bootloader
starten lassen und dann zum eigentlichen Programm starten, wenn nichts
per CAN kommt (so haben wir das bisher mit den AVRs gemacht).
Gibt es da eine tolle Lösung oder muss ich dem Chip über irgendeine
Schnittstelle sagen, das er bitte NO_ISP abschaltet und dann einen
Software Reset ausführt?
Das NO_ISP müsste dann vom Bootloader nach erfolgreichem schreiben der
neuen Firmware wieder gesetzt werden. So kann man sich natürlich
aussperren, wenn man eine Firmware flasht, die den NO_ISP Befehl nicht
unterstützt oder sonst Bugs hat.
Einen zweiten, kleinen µC, der eine Reset-Sequence ausführt und den
Bootloader-Enable Pin zunächst ein und dann wieder abschaltet, würde ich
gerne umgehen.
Konstantin schrieb:> Wir möchten die Möglichkeit haben, den Chip jederzeit OHNE einen Jumper> zu setzen mit neuem Code updaten können
Da beibt doch nur ein selbstgebauter Bootloader. Mittels der
IAP-Routinen und den Erfahrungen auf der Host-Seite sollte das kein
großes Problem mehr darstellen.
Es liegt ja sowieso in der Natur der Schnittstelle, dass das Gerät an
einem BUS hängt, an dem mehrere Geräte mit diesem Controller vorhanden
sind. In diesem Fall muss der Update-Identifier ja sowieso umdefinierbar
sein, was mit dem internen Bootloader schon nicht mehr geht.
Wenn die Startadresse 0x315 ist, dann hätte ich am ehesten
auf 0x314 getippt. 0x300 und 0x318 sind m.E. falsch,
es wird dann irgendwas ausgeführt bzw. der Controller stürzt ab.
Bzgl. IAP aus Applikation: siehe "26.7.8 Reinvoke ISP (IAP)"
im User Manual des LPC11C24.
Harald hat natürlich recht. Das hatten wir noch garnicht bedacht. Macht
den IAP Bootloader unausweichlich... Aber gut, da haben wir dann
wenigstens wieder alle Freiheiten.
FlashMagic mal genau auf die Finger zu schauen ist eine gute Idee.
Werden wir mal ausprobieren!
Vielleicht wäre es auch ein Versuch, nach dem Flashen via CAN
den Inhalt des Flashes z.B. via FlashMagic wieder auszulesen
und zu vergleichen, ob die gewünschten Daten auch an der richtigen
Stelle stehen. Wenn das Flashen vorher nicht richtig funktioniert,
kann das GO natürlich auch nicht funktionieren...
Harald schrieb:> Es liegt ja sowieso in der Natur der Schnittstelle, dass das Gerät an> einem BUS hängt, an dem mehrere Geräte mit diesem Controller vorhanden> sind. In diesem Fall muss der Update-Identifier ja sowieso umdefinierbar> sein, was mit dem internen Bootloader schon nicht mehr geht.
Warum denn das? Man darf nur die Identifier 0x67D und 0x5FD auf dem Bus
nicht anderweitig vergeben (sind ja die fixen Standardeinstellungen im
C_CAN bootloader zur Kommunikation). Welchem Node man dann mit Reinvoke
ISP (IAP) das Lauschen auf 0x67D beibringt, ist ja frei wählbar
(natürlich nur einer zur Zeit).
OT: Beim erneuten Lesen von Anfang kommt mir das schon etwas komisch,
aber egal:
- Pamela schreibt wie Konstantin => Pamela ist Konstantin bzw.
umgekehrt. Wird so mehr Unterstützung erwartet?
- Der registrierte Martin schreibt der unregistrierten Pamela eine
email, deren Empfang von Konstantin bestätigt wird. => Woher soll einer
von beiden die emailadresse des anderen kennen? Also müssen sie sich
kennen.
Aha OK, habe ich mir gerade angeschaut - wäre eine Möglichkeit, wobei
die im UM nur auf die UART eingehen und nicht auf CAN. Sollte aber
funktionieren.
Etwas unüberschaubar wird das bei einem abgebrochenen Download. Wer kann
dann den ISP re-invoken?
P.S. Das mit dem Namen ist mir auch aufgefallen, wobei Konstantin ja
nicht der Einzige wäre, der in diesem Forum mit dieser Form des Social
Engineerings arbeitet. Funktioniert hat die Nummer ja auf jeden Fall. Es
wurde sachlich und "normal" geantwortet, obwohl solche Anfragen hier
standardgemäß sofort zerfleischt werden.
Lutz schrieb:> OT: Beim erneuten Lesen von Anfang kommt mir das schon etwas komisch,> aber egal:> - Pamela schreibt wie Konstantin => Pamela ist Konstantin bzw.> umgekehrt. Wird so mehr Unterstützung erwartet?> - Der registrierte Martin schreibt der unregistrierten Pamela eine> email, deren Empfang von Konstantin bestätigt wird. => Woher soll einer> von beiden die emailadresse des anderen kennen? Also müssen sie sich> kennen.
Lieber Lutz,
natürlich kennen die beiden sich. Wenn du wirklich aufmerksam gelesen
hättest, wäre dir es auch sicher nicht entgangen.
> Autor: Konstantin (Gast)> Datum: 12.11.2012 20:21> Hallo allerseits,> ich programmiere mit Pamela am CAN Bootloader.
Daraus resultiert mal wieder:
Wer lesen kann ist klar im Vorteil :D
Jörg B. schrieb:> Lieber Lutz,> natürlich kennen die beiden sich. Wenn du wirklich aufmerksam gelesen> hättest, wäre dir es auch sicher nicht entgangen.>>>> Autor: Konstantin (Gast)>> Datum: 12.11.2012 20:21>>> Hallo allerseits,>>> ich programmiere mit Pamela am CAN Bootloader.>> Daraus resultiert mal wieder:>> Wer lesen kann ist klar im Vorteil :D
Ach lieber Jörg,
natürlich habe ich das gelesen. Hättest du deinen eigenen Rat mit dem
aufmerksamen lesen aber bei dir selber angewendet, hätte dir aufgehen
müssen, daß Pamela und Konstantin meiner Meinung nach die selbe Person
ist. Und dann ist schon klar, daß die sich kennen; unabhängig von deinem
(ansonsten korrekten) Zitat.
Ich bezog mich auf:
Lutz schrieb:> - Der registrierte Martin schreibt der unregistrierten Pamela eine> email. => Woher soll einer von beiden die emailadresse des anderen> kennen? Also müssen sie sich kennen.
wobei ich zur Verdeutlichung Konstantin diesmal im Nebensatz wegelassen
habe. Jetzt alles klar ? :-)
@Lutz:
>> - Der registrierte Martin schreibt der unregistrierten Pamela eine>> email, deren Empfang von Konstantin bestätigt wird. => Woher soll einer>> von beiden die emailadresse des anderen kennen? Also müssen sie sich>> kennen.
dieser Teil kann auch geklärt werden: Das Programm von Pamela
und Konstantin basiert scheinbar auf lpc21isp oder wurde
als Referenz benutzt. Ich bin der initiale Entwickler von lpc21isp.
Pamela hatte mich bereits parallel per Email kontaktiert.
Ich kontaktiere Dich per (Forum-)Email,
dann können wir das Problem direkt klären!
Support für LPC1114FN28 (Stand: jetzt) noch nicht vorhanden,
ich habe diverse Patches hier, aber noch keine Zeit gehabt,
diese einzumergen/hochzuladen. Sorry!
Konstantin schrieb:> P.S.: Wenn der Bootloader dann irgendwann mal komplett funktioniert,> werden wir den Code natürlich auch veröffentlichen!
Wie ist denn der Stand?
Konstantin schrieb:
> P.S.: Wenn der Bootloader dann irgendwann mal komplett funktioniert,> werden wir den Code natürlich auch veröffentlichen!
Hendrik schrieb:
> Wie ist denn der Stand?
Über 2 Jahre danach ist OpenSource da immer noch nichts zu finden. Oder?
Im EPJ #18
http://journal.embedded-projects.net/downloads/EPJ_18_web.pdf
war der Anhang mal verlinkt (PC->FTDI->mcp2515->LPC11C24, BSD 2-Clause)
sha256: 464b84859d1431d0e03f84fe2cfb182c617be26ab250a52f99cda756d9afc11b
Hat wer das Teil schon auf SocketCAN umgestrickt?
Konstantin schrieb:> Vielen Dank für die Mail und die Antwort hier!>> Die Addresse an Position 4 hatte ich auch schon versucht. Die ist> ungerade (0x315) und bringt beim GO-Command den SDO_ADDR_ERROR> Abort-Code als Antwort. Auch mit +1 auf 0x316 meckert er rum.>> Der CAN Bootloader aktzeptiert nur Addressen, die ein ganzzahliges> Vielfaches von 4 sind. Mit den nächst- und naheliegenden Addressen 0x300> (ab hier scheint Code zu stehen, vorher viel 0xFF), 0x314 und 0x318> startet er nicht (ist aber nicht mehr im Bootloader).>> Noch ein anderer Punkt:>> Wir möchten die Möglichkeit haben, den Chip jederzeit OHNE einen Jumper> zu setzen mit neuem Code updaten können (das Gerät wir im eingebauten> Zustand nicht mehr einfach zugänglich sein). Da nun der Bootloader aber> keinen Timeout hat, kann man ja nicht einfach immer den Bootloader> starten lassen und dann zum eigentlichen Programm starten, wenn nichts> per CAN kommt (so haben wir das bisher mit den AVRs gemacht).>> Gibt es da eine tolle Lösung oder muss ich dem Chip über irgendeine> Schnittstelle sagen, das er bitte NO_ISP abschaltet und dann einen> Software Reset ausführt?> Das NO_ISP müsste dann vom Bootloader nach erfolgreichem schreiben der> neuen Firmware wieder gesetzt werden. So kann man sich natürlich> aussperren, wenn man eine Firmware flasht, die den NO_ISP Befehl nicht> unterstützt oder sonst Bugs hat.>> Einen zweiten, kleinen µC, der eine Reset-Sequence ausführt und den> Bootloader-Enable Pin zunächst ein und dann wieder abschaltet, würde ich> gerne umgehen.
Ich hänge jetzt genau an diesem Punkt fest.
Die UserApp wird mit dem GO Kommando aus dem Bootloader heraus nur
gestartet, wenn ich den Bootloader-Enable Pin vorher deaktiviere. Die
Checksumme und die Filegröße (%4) habe ich geprüft. Die sind OK.
Außerdem habe ich das Problem, das Reinvoke aus meiner UserApp zum
Absturz führen. Ich habe die InvokeBootloader-Procedure von Pamela
verwendet, die Sie im Embedded Projects Journal (Listing 3) angegeben
hat.
Hat jemand einen Tip für mich?
Hallo
Gibt es den Sourcecode con dem EP_Journal noch irgendwo rumschwirren?
Der Dropbox link funktioniert leider nicht mehr...
Im Moment versuche ich mal die IAP_InvokeBootloader zu compilieren, da
bekomme ich zwei Sachen die er nicht findet :
LPC_SYSCON und IAP_CMD_REINVOKE_ISP
while(!(LPC_SYSCTL->MAINCLKUEN&0x01));// Wait until updated
19
command[0]=IAP_CMD_REINVOKE_ISP;// Reset the stack pointer to point to the top of the stack minus the 32 byte for IAP
20
// For LPC11C14 where top of RAM is 0x1000 _ 2000; MSP = (0x1000 _ 2000- 0x20) = 0x10001FE0
21
__set_MSP(0x10001FE0);
22
// The Cortex M0 needs to synchronize the CPU cache
23
__ISB();
24
iap_entry(command,result);
25
}
Damit sprint er mir korrekt in den Bootloader, und ich mit dem Programm
CANFlasherUTNL auch eine neue Firmware auf das Teil spielen ...
nur muss ich dann einen manuellen Reset ausführen
Wie schaffe ich es das nach dem Upload der UserCode automatisch startet?
ich hätte nun schon mal probiert nach dem flashen (ich bkeomme da immer
noch antworten auf die 67D Pakete)
folgendes zu senden
[0x67D] [0x23 0x70 0x50 0x01 0x00 0x00 0x00 0x00] // set execution
address
[0x67D] [0x2F 0x51 0x1F 0x01 0x01 0x00 0x00 0x00] // 'Go'
bekomme zwar jedes Paket mit einem 0x57D beantwortet aber er bleibt
trotzdem im Bootloader hängen
> Wie schaffe ich es das nach dem Upload der UserCode automatisch startet?
Aktuell fehlt der Go-Befehl im CANFlasherUTNL. Ich weiß leider nicht
mehr genau warum, aber das Kommando machte bei mir auch Probleme. Die
entsprechende Codestelle wäre:
https://github.com/EmbedME/CANFlasherUTNL/blob/master/src/LPCFlash.java#L191
Die Befehlssequenz in den Kommentaren hast du ja bereits getestet...
umgesetzt in Java-Code würde es dem hier entsprechen (falls du das
Problem findest und ins Programm integrieren möchtest):
Hallo das Problem hatte ich auch, allerdings mit einem selbst
geschriebenen Bootloader. Da Problem ist, dass er zwar wieder mit der
Go-Addresse startet, aber kein Reset gemacht wird. Ich hab mir so
geholfen:
1
intmain(void)
2
{
3
// Wenn aus dem Reinvoke ein Neustart ausgeloest wurde,
4
// ist das SYSRST-Flag nicht gesetzt. Deshalb noch einen
5
// Reset auslösen
6
if((LPC_SYSCON->SYSRSTSTAT&(1<<4))==0)
7
NVIC_SystemReset();
8
LPC_SYSCON->SYSRSTSTAT|=(1<<4);
Normalerweise ist nach einem Reset das Bit 4 (SYSRST) im SYSRSTSTAT
Register gesetzt. Wenn es gesetzt ist lösche ich es in dem eine 1 rein
geschrieben wird. Wird jetzt im Programm in den Bootloadercode
gesprungen und mit Go das Programm neu gestartet, dann ist dieses Bit
immer noch 0. In dem Zustand schiebe ich nochmal einen Reset nach, der
auch die Hardware wieder auf Resetzustand bringt.
Andi S. schrieb:> ich hätte nun schon mal probiert nach dem flashen (ich bkeomme da immer> noch antworten auf die 67D Pakete)> folgendes zu senden> [0x67D] [0x23 0x70 0x50 0x01 0x00 0x00 0x00 0x00] // set execution> address> [0x67D] [0x2F 0x51 0x1F 0x01 0x01 0x00 0x00 0x00] // 'Go'>> bekomme zwar jedes Paket mit einem 0x57D beantwortet aber er bleibt> trotzdem im Bootloader hängen
Da scheint ein Fehler drin zu sein, im Manual steht:
-----------------------
21.6.8 Go (C_CAN ISP)
Write the start address into [0x5070, 0]. Then trigger the “start
application” command by
writing the value 0x1 to [0x1F51, 1].
-----------------------
So muss die Message richtig sein:
[0x67D] [0x23 0x70 0x50 0x00 0x00 0x00 0x00 0x00]
Also auch mit dem Befehl macht er bei mir leider nichts ... er bleibt
nach wie vor immer im Bootloader drinnen (und reagiert weiterhin auf die
67d befehle)
wo ich mir nicht sicher bin :
auf das hier
67d 2f 51 1f 01 01 00 00 00
wird das geschickt
5fd 80 51 1f 01 0f 00 00 0f
könnte das der Code sein CMD_LOCKED SDOABORT_CMD_LOCKED 0x0F00 000F ??
was auch immer das heissen möge (das CRP ist es nicht das wäre ein
andere Fehlercode)
auf S. 429/430 in dem UM10398 steht eine Sequenz die per ISP Kommandos
in das RAM geschrieben und ausgeführt werden kann um einen richtigen
core-reset zu machen. Habe ich noch nicht probiert, aber das Projekt
interessiert mich auch.
Ich kenne diesen Bootloader nicht. Falls er aber wirklich genau an die
übergebene Adresse springt, muss das Bit 0 der Adresse (zusätzlich)
gesetzt sein (Thumb code adresse).
temp schrieb:> So muss die Message richtig sein:> [0x67D] [0x23 0x70 0x50 0x00 0x00 0x00 0x00 0x00]
Hab es gerade nochmal bei mir durch den Debugger laufen lassen.
[0x67D] [0x23 0x70 0x50 0x01 0x00 0x00 0x00 0x00]
scheint doch richtig zu sein! Das setzen der Start-Adresse wurde bei mir
auch mit einem Fehler quittiert. Allerdings das Go-Commando ging immer.
also das wäre mal die sequenz die ich getestet hätte :
1
t67d82315500010000000
2
3
t67d823501F0101480249
4
t67d823501F010160fee7
5
t67d823501F010ced00e0
6
t67d823501F010400fa05
7
/* Alterantiver code
8
t67d823501F01014a024b
9
t67d823501F01da60c046
10
t67d823501F010400fa05
11
t67d823501F0100ed00e0
12
*/
13
14
t67d82370500010000000
15
t67d82370500254000000
16
t67d823511f0101000000
einmal mit dme code aus der UM (sollte :
014802490160fee70ced00e00400fa05 sein)
und einmal einen anderen code was ich in nem forum gefunden habe
beide funktionierne nicht
wobei mich noch mehr wundert das er im bootloader hängen bleibt.
Müsste der nicht wenn ich mit GO auf ne falsche Adresse springe oder
dort müll steht, der bootloader dann einfach nicht mehr reagieren? )
temp schrieb:> Andi S. schrieb:>> t67d82370500254000000>> Das bringt aber den Sdo-Fehler, dass das Register RO ist (wie's auch im> Manual steht)
ja das stimmt schon, nur sollte das dann eh egal sein oder nicht?
War ja nur ein verzweifelter Versuch es irgendwie zum laufen zu bringen.
Hier noch ein anderer Hinweis (Seite 293):
Once the crystal frequency is received the part is initialized and the
ISP command handler
is invoked. For safety reasons an "Unlock" command is required before
executing the
commands resulting in flash erase/write operations and the "Go" command.
The rest of
the commands can be executed without the unlock command. The Unlock
command is
required to be executed once per ISP session. The Unlock command is
explained in
Section 20.5 “UART ISP commands” on page 299.
Sieht bei mir so aus:
WriteWord(0x5000, 0, 0x5a5a);
Oder so bei dir (ungetestet):
t67d8230050005a5a0000
sooo .... heute noch einiges getestet ... und ich glaub der interne
bootloader funktioniert einfach nicht richtig (kann ich mir nicht
vorstellen, aber es läuft einfach nicht)
Glaub die einzige möglichkeit ist einen zweiten "externen" Bootloader zu
schreiben ... den ohne Neustart bringt das ganze leider absolut nichts.
in Beitrag "Re: LPC11C24 CAN bootloader" im
Anhang ist doch auch ein Flash Tool, das hat auch ein Reset Kommando.
Hast du das auch schon probiert?
Nachtrag:
Andere Frage, wie wird der Sprung in den Bootloader ausgelöst?
Funktioniert der Reset vielleicht und du springst nach dem Reset sofort
wieder in den BL (durch irgendwelchen nicht gelöschten Speicher)?
Andi S. schrieb:> sooo .... heute noch einiges getestet ... und ich glaub der interne> bootloader funktioniert einfach nicht richtig (kann ich mir nicht> vorstellen, aber es läuft einfach nicht)>> Glaub die einzige möglichkeit ist einen zweiten "externen" Bootloader zu> schreiben ... den ohne Neustart bringt das ganze leider absolut nichts.
Ich hab an meinem Code auch nochmal gefummelt. Was nicht geht ist die
GO-Anweisung auf eine RAM-Adresse. Das sind schon andere drüber
gestolpert und bei LPC15xx ist es wohl ähnlich. Zu beachten ist auch
noch die Besonderheit, dass bei Ausführung der GO-Anweisung das
SYSCON->SYSMEMREMAP auf 0 steht, damit ist die Vektortabelle des
Bootloaders noch aktiv. Der Sprung auf eine RAM-Adresse scheint einen
Hardfault auszulösen und er hängt im Hardfaulthandler des
Bootloadercodes.
Was bei mir geht ist der Sprung zu einer ROM-Adresse. Die muss aber
>=0x200 sein, weil bis dahin ja noch der Bootloaderflash reingemappt
ist. Ich hab mir so eine Funktion gemacht:
1
__attribute__((naked))
2
__attribute__((section(".btl_reset")))
3
voidHardwareReset()
4
{
5
__asmvolatile
6
(
7
" dsb sy \n"
8
" ldr r2, =0x05FA0004 \n"
9
" ldr r3, =0xE000ED00 \n"
10
" str r2, [r3, #12] \n"
11
" dsb sy \n"
12
"ll: b ll \n"
13
);
14
}
und im Linker File:
1
....
2
*(.after_vectors*)
3
4
/* BTL_RESET fuer Bootloader reset */
5
.=0x00000200;
6
KEEP(*(.btl_reset))
7
....
Die Funktion ist das was der gcc aus NVIC_SystemReset(); macht, nur ohne
Rahmen. Was für eine Toolchain verwendest du denn?
Jedenfalls löst der Go zu 0x200 einen vernünftigen Reset aus. Ein
Breakpoint auf 0x200 geht hier auch vernünftig.
Ich arbeite zum Debuggen unter Crossworks, gebildet ist das Projekt mit
der gcc-Toolchein vom Launchpad.
Johannes S. schrieb:> Andere Frage, wie wird der Sprung in den Bootloader ausgelöst?> Funktioniert der Reset vielleicht und du springst nach dem Reset sofort> wieder in den BL (durch irgendwelchen nicht gelöschten Speicher)?
Nachtrag:
Wenn die Checksumme auf 0x1C nicht stimmt landet er nach einem Reset
auch immer sofort im Bootloader! Das hat mich vor ein paar Jahren auch
Nerven gekostet. Vor allem wenn die Toolchain das nicht berechnet und
ins bin, elf oder hex-File patcht. Beim Flashen aus einer IDE wird
häufig während des Flashens erst die CRC gebildet. So einen Code kann
man dann natürlich nicht per Bootloader übertragen.
Das war nur für den Fall, daß das nicht bekannt ist.
@temp wenn das der Fall wäre, das er nach dem flashen wieder im
bootloader landet .... würde das auch der Fall sein, wenn ich einen
händischen Reset ausführe?
Den wenn ich den Reset per Hand ausführe, dann läuft das Userprogramm
sofort los.
Im Moment versuche ich es einfach so:
P01 auf LOW -> Reset
P01 wieder raus
dann daten schicken UNLOCK und dann die Sachen mit dem GO
und da bleibt er mir ständig im Bootloader drinnen bis ich ein
händisches Reset ausführe.
ich verwende LPCXpresso ... muss mal schauen ob ich sowas auch
reinbekomme ..
Andi S. schrieb:> @temp wenn das der Fall wäre, das er nach dem flashen wieder im> bootloader landet .... würde das auch der Fall sein, wenn ich einen> händischen Reset ausführe?
Dann würde er genauso in den Bootloader springen.
Wenn du es überhaupt nicht hinkriegst, nimm den Watchdog zum Resetten!
Wie lange dein Firmewareupdate dauert kannst du einschätzen. Stell den
Watchdog auf die doppelte Zeit bevor du ins Reinvoke springst und warte
am Ende des Flashens einfach auf den Reset des Watchdogs.
Mann kann sich auch ganz am Anfang noch einen Flash-CRC-TestCode
einbauen und macht das Update über CAN erst ab 0x300 oder 0x400. Bei
Fehlern geht es dann gleich wieder in den Bootloader.
Dann ist sichergestellt, dass ein Fehlgeschlagenes Update den µC in
einen sicheren Zustand bringt und er immer wieder über CAN erreichbar
ist.
temp schrieb:> Was bei mir geht ist der Sprung zu einer ROM-Adresse. Die muss aber> >=0x200 sein, weil bis dahin ja noch der Bootloaderflash reingemappt> ist. Ich hab mir so eine Funktion gemacht:
Das ist interessant, vielen Dank für diese Info!
Ich habe das mal in den CANFlasherUTNL
(http://www.fischl.de/can/bootloader/canflasherutnl/) integriert. Die
Resetfunktion kann so automatisch an das Ende des Programmcodes angefügt
und der GO darauf ausgelöst werden (Option "Insert reset"). Bei meinem
Versuchsaufbau klappt das.
Checksumme: diese wird automatisch vom CANFlasherUTNL
berechnet/eingefügt.
Also so richtig verstehe ich das nicht, muss ich nun in mein Programm
irgendwas spezielles reinschreiben? oder kann ich nun einfach das
CANFlasherUTNL verwenden?
Thomas F. schrieb:> Resetfunktion kann so automatisch an das Ende des Programmcodes angefügt> und der GO darauf ausgelöst werden (Option "Insert reset"). Bei meinem> Versuchsaufbau klappt das.
Das ist natürlich für einen universellen Bootloader auch eine clevere
Idee.
Was da jetzt noch fehlt ist ein generalistischer Weg um einen einzelnen
Controller im Verbund über den Bus in den Bootloader zu schicken. Ich
mache das bei mir über die Seriennummer des Controllers. D.h. ich
schicke 4 SDO-Messeges an den µC und wenn die passen gehts in das
Reinvoke. Allerdings ist der Aufruf von Reinvoke etwas kritisch weil man
vorher seine gesamte Hardwarekonfiguration überprüfen muss.
Ich hab mir deshalb eine Hilfsvariable angelegt die beim Reset nicht
verändert wird.
Wenn das Userprogramm den Trigger detectiert in den Bootloader zu
springen,
belege ich die Variable mit einem magic Wert und mache einen
Systemreset.
1
// SoftwareReset auslösen
2
StartBootLoader=0x47115378;
3
NVIC_SystemReset();
Und ganz am Anfang in main:
1
intmain()
2
{
3
if(StartBootLoader==0x47115378)
4
{
5
StartBootLoader=0;
6
debug_printf("go to bootloader\n");
7
8
WDTInit(WatchDogTime);
9
ReinvokeIsp();
10
}
11
StartBootLoader=0;
12
.....
Das hat den riesen Vorteil, dass der Controller vor dem Sprung in den
Bootloader aus einem definierten Reset kam und das unterbrochene
Programm einem nicht mehr in die Quere kommt. Damit wird das
ReinvokeIsp() auch einfacher.
1
voidReinvokeIsp()
2
{
3
#define IAP_LOCATION 0x1FFF1FF1
4
staticIAPiap_entry=(IAP)IAP_LOCATION;
5
staticunsignedintcommand[5]={57,0,0,0,0};
6
staticunsignedintresult[5];
7
8
// The Cortex M0 needs to synchronize the CPU cache
9
__ISB();
10
iap_entry(command,result);
11
}
Ob mann sowas verallgemeinern kann?
Die Seriennummern könnten vom Java-Programm ermittelt werden wenn der
Controller per Hand im Bootloader ist. Entsprechende Aufrufe über CAN
dafür gibt die API ja her.
Thomas F. schrieb:>> muss ich nun in mein Programm irgendwas spezielles> reinschreiben?>> Nein, das macht der CANFlasherUTNL automatisch.
Jop macht er automatisch und funktioniert wunderbar!!!!!!!
Super Danke :D