Forum: Mikrocontroller und Digitale Elektronik LPC11C24 CAN bootloader


von Pamela (Gast)


Lesenswert?

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

von Lothar (Gast)


Lesenswert?

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?

von Lutz (Gast)


Lesenswert?

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.

von Pamela (Gast)


Lesenswert?

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.

von Pamela (Gast)


Lesenswert?

Ich möchte mit ISP (mit CANopen) den Bootloader aufrufen.

von Harald (Gast)


Lesenswert?

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.

von Lutz (Gast)


Lesenswert?

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.

von Lutz (Gast)


Lesenswert?

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.

von Pamela (Gast)


Lesenswert?

Vielen Dank für die Antworten!
Inzwischen Zeit funktioniert es!

von Lutz (Gast)


Lesenswert?

Und woran hat es gelegen?

von Gero (Gast)


Lesenswert?

Hallo Pamela,

Es wäre schön, mehr zu deinem Bootloader zu erfahren. Was war der 
Fehler?
Es ist einfach unfähr uns so dumm dastehen zu lassen...

von Pamela (Gast)


Lesenswert?

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.

von Konstantin (Gast)


Lesenswert?

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!

von Lutz (Gast)


Lesenswert?

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.

von Lutz (Gast)


Lesenswert?

Wenn du einfach nur resetten willst: Leg doch NVIC_SystemReset(void) ins 
RAM und spring dahin ...

von Konstantin (Gast)


Lesenswert?

> ??? 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.

von Martin M. (capiman)


Lesenswert?

"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").

von Konstantin (Gast)


Lesenswert?

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.

von Harald (Gast)


Lesenswert?

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.

von Martin M. (capiman)


Lesenswert?

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.

von Martin M. (capiman)


Lesenswert?

Habt Ihr das GO-Kommando schon mal mit FlashMagic getract?
(vorausgesetzt FlashMagic nimmt das GO überhaupt her...)

von Konstantin (Gast)


Lesenswert?

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!

von Martin M. (capiman)


Lesenswert?

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...

von Lutz (Gast)


Lesenswert?

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.

von Harald A. (embedded)


Lesenswert?

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.

von Jörg B. (joerg-sh)


Lesenswert?

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

von Lutz (Gast)


Lesenswert?

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 ? :-)

von Martin M. (capiman)


Lesenswert?

@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.

von Roland H. (batchman)


Lesenswert?

Martin Maurer schrieb:
> Ich bin der initiale Entwickler von lpc21isp.

Oh. Dann erlaube ich mir einen kurzen off-topic Einwurf: 
Beitrag "ARM in DIP: CM0 lpc1114fn28 ist da und blinkt!" verbunden mit einem Dank für 
lpc21isp und mit der Frage, was mit dem Patch des Patches passieren 
soll.

von Martin M. (capiman)


Lesenswert?

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!

von Hendrik (Gast)


Lesenswert?

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?

von Manfred (Gast)


Lesenswert?

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?

von trashCAN (Gast)


Angehängte Dateien:

Lesenswert?

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?

von Simone (Gast)


Lesenswert?

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?

von sn00py (Gast)


Lesenswert?

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

von sn00py (Gast)


Lesenswert?

push

Also ich habe mittlerweile das ganze compilieren können
1
void IAP_InvokeBootloader(void) {
2
  static unsigned int command[5] = {57, 0, 0, 0, 0};
3
  static unsigned int result[4];
4
  __disable_irq();
5
  // Make sure 32-bit Timer 1 is turned on before calling ISP
6
  LPC_SYSCTL->SYSAHBCLKCTRL |= 0x00400;
7
  // Make sure GPIO clock is turned on before calling ISP
8
  LPC_SYSCTL->SYSAHBCLKCTRL |= 0x00040;
9
  // Make sure IO configuration clock is turned on before calling ISP
10
  LPC_SYSCTL->SYSAHBCLKCTRL |= 0x10000;
11
  LPC_SYSCTL->SYSAHBCLKDIV = 1; // AHB clock divider must 1:1
12
  // Disable the PLL
13
14
  LPC_SYSCTL->MAINCLKSEL = 0; // Enable IRC Oscillator
15
  LPC_SYSCTL->MAINCLKUEN = 0x01; // Update MCLK Clock Source
16
  LPC_SYSCTL->MAINCLKUEN = 0x00; // Toggle Update Register
17
  LPC_SYSCTL->MAINCLKUEN = 0x01;
18
  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?

von Andi S. (sn0000py)


Lesenswert?

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

von Thomas F. (_thomas_)


Lesenswert?

> 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):
1
usbtinSDO.writeExpedited(0x5070, 1, new byte[]{0x00, 0x10, 0x00, 0x00}); // write execution add 0x00001000
2
usbtinSDO.writeExpedited(0x1f51, 1, new byte[]{0x01}); // write program control 0x01
Die Dokumentation vom CAN Bootloader findet man in der NXP Doku 
"UM10398".

von temp (Gast)


Lesenswert?

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
int main (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]

von Andi S. (sn0000py)


Lesenswert?

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)

von Johannes S. (Gast)


Lesenswert?

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.

von Steffen R. (steffen_rose)


Lesenswert?

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).

von temp (Gast)


Lesenswert?

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.

von Andi S. (sn0000py)


Lesenswert?

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? )

von temp (Gast)


Lesenswert?

Andi S. schrieb:
> t67d82370500254000000

Das bringt aber den Sdo-Fehler, dass das Register RO ist (wie's auch im 
Manual steht)

von sn00py (Gast)


Lesenswert?

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.

von temp (Gast)


Lesenswert?

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

von sn00py (Gast)


Lesenswert?

den habe ich auch schon getestet gehabt zuvor ...

Läuft bei dir der Bootloader (bzw das User Programm danach?)

von Andi S. (sn0000py)


Lesenswert?

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.

von Johannes S. (Gast)


Lesenswert?

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)?

von temp (Gast)


Lesenswert?

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
void HardwareReset() 
4
{
5
   __asm volatile 
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.

von temp (Gast)


Lesenswert?

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.

von Andi S. (sn0000py)


Lesenswert?

@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 ..

von temp (Gast)


Lesenswert?

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.

von Thomas F. (_thomas_)


Lesenswert?

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.

von sn00py (Gast)


Lesenswert?

Also so richtig verstehe ich das nicht, muss ich nun in mein Programm 
irgendwas spezielles reinschreiben? oder kann ich nun einfach das 
CANFlasherUTNL verwenden?

von Thomas F. (_thomas_)


Lesenswert?

> muss ich nun in mein Programm irgendwas spezielles reinschreiben?

Nein, das macht der CANFlasherUTNL automatisch.

von temp (Gast)


Lesenswert?

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.
1
__attribute__ ((section (".non_init"))) volatile int StartBootLoader;
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
int main()
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
void ReinvokeIsp()
2
{ 
3
  #define IAP_LOCATION 0x1FFF1FF1
4
  static IAP iap_entry=(IAP)IAP_LOCATION;
5
  static unsigned int command[5] = {57, 0, 0, 0, 0}; 
6
  static unsigned int result[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.

von sn00py (Gast)


Lesenswert?

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

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.