Forum: Mikrocontroller und Digitale Elektronik PIC booten über RS485


von Bernd I. (Gast)


Lesenswert?

Hallo Leute!
Ich möchte für PIC-Programme (PIC18Fxxxx), die mit dem Compiler Proton 
von Crownhill erstellt werden, Update-Dateien für den Nutzer zur 
Verfügung stellen. Dazu habe ich am Anfang des Programms einen 
entsprechenden Bootloader geschrieben, der nichts weiter macht, als je 
64 Bytes entgegennehmen, 64 Bytes ab dem Beginn des eigentlichen 
Programms im Block löschen und die neuen 64 Bytes schreiben. Die Datei 
wird von einem eigens dafür erstellten "Updater" gesendet und alles 
kontrolliert (es kommt also nicht von einem PC). Das funktioniert soweit 
auch alles richtig! Alle Bytes, die gesendet werden, stehen anschließend 
im Programm.
ABER!!! Das Modul funktioniert hinterher nicht richtig, da in dem Update 
neue Variablen verwendet werden, die das alte Programm vorher nicht 
verwendet hat. (ich vermute, dass das daran liegt).
Flashe ich das neue Programm und boote es hinterher über besagten 
"Updater" funktioniert alles tadellos.

Wenn ich NACH dem Update (altes Programm) den Inhalt des PIC mit Hilfe 
eines Programmers mit der Original-Hex vergleiche, "spuckt" er mir ca. 
12-16 Bytes aus, die sich unterscheiden. Diese Bytes-Unterschiede liegen 
VOR dem Hauptprogramm, also dort, wo ich nichts verändere. Heißt: Dort 
am Anfang stehen jetzt andere Anweisungen, die sich logischerweise auf 
das Hauptprogramm auswirken, die beim Booten aber nicht erfasst werden.

Ich experimentiere mit diesem Problem schon Monate (immer wieder mal was 
neues ausprobieren), komme aber nicht weiter. Kann jemand helfen???
Was muss noch beachtet werden???

Bernd!

von Dieter W. (dds5)


Lesenswert?

Bernd I. schrieb:
> Diese Bytes-Unterschiede liegen
> VOR dem Hauptprogramm, also dort, wo ich nichts verändere.

Falls Du Interrupts benutzt ist das wahrscheinlich an den 
Einsprungadressen, die liegen auf 8 und 18 Hex.

Da die Startadressen der Int-Routinen bei Programmänderungen selten 
gleich bleiben, wirkt sich das natürlich auf den Code an den o.g. 
Stellen aus.

von Bernd I. (Gast)


Lesenswert?

Guten Morgen Dieter,
vielen Dank für die Antwort. In dieser (und auch anderen Anwendungen, in 
denen es nicht geht) benutze ich keine Interrupts. Ich weiss, dass auf 
Hx8 und Hx18 die Interruptadressen liegen (sollten). Das macht mich ja 
z.B. auch etwas stutzig, dass der Hex-Code sofort mit Null beginnt. 
Müßte hier (da kein Interrupt definiert) nicht erst mal Hx00 bzw. HxFF 
kommen? Aber das ist im Moment eher unwichtig. Ich MUSS dieses nervige 
Dauerproblem JETZT endlich in den Griff bekommen.
Ich probiere heute noch weitere Ideen aus und melde mich, wenn es 
Ergebnisse gibt. Hoffentlich mit einem ausführlichen Fehlerbericht für 
alle Leser, wenn es endlich klappt.

liebe Grüße von der Ostsee, Bernd

von Wolfgang R. (portside)


Lesenswert?

mal für den Linker nach Option --codeoffset suchen.
Bei MPLAB-X bei Customize.
Soll auch RESET und INTERRUPT Vector  wie auch immer umbiegen.

von Daniel V. (danvet)


Lesenswert?

Bist du sicher, dass Configuration Bits und ResetVector beim Bootloader 
und bei der FW identisch sind?

Ich habe sowas (Bootloader über UART) schon für den PIC33 gemacht.
zusätzlich: Der Bootloader muss wissen, wo die FW anfängt.
Ich habe hierzu das Linkerfile anpassen müssen, d.h. es gibt dann zwei 
verschiedene Linkerfiles (eins für den Bootloader und eins für die FW), 
allerdings ist der PIC33 auch etwas aufwändiger (viele 
Interruptvectoren) und ich habe die Interrupts in der FW verwendet.

von Daniel V. (danvet)


Lesenswert?

Bernd I. schrieb:
> Guten Morgen Dieter,
> vielen Dank für die Antwort. In dieser (und auch anderen Anwendungen, in
> denen es nicht geht) benutze ich keine Interrupts. Ich weiss, dass auf
> Hx8 und Hx18 die Interruptadressen liegen (sollten). Das macht mich ja
> z.B. auch etwas stutzig, dass der Hex-Code sofort mit Null beginnt.
> Müßte hier (da kein Interrupt definiert) nicht erst mal Hx00 bzw. HxFF
> kommen? Aber das ist im Moment eher unwichtig.

Ich denke nicht, dass das unwichtig ist. Das Speicherlayout und die 
Verwendung musst du verstehen, um den Fehler beheben zu können. Siehe 
meinen Post davor.

Gruß,
Daniel

von Bernd I. (Gast)


Lesenswert?

Sorry, Sorry ihr Lieben. Klartext: Ich kann keine PC-Software, ich kann 
nur Elektronik entwickeln und in Basic Programme für PIC's erstellen. Um 
alles andere kümmert sich der Compiler. Kenne aber natürlich den 
kompletten Aufbau der PIC's, Aufbau des Programms na usw., aber sicher 
fehlen mir hier und da noch so einige Details, die ins "Eingemachte" 
gehen. Deshalb ist meine Verfahrensweise (simpel) wie folgt:
Original-HEX des neuen Programms mit Editor öffnen. Bootloader-Bereich 
und die Config-Anweisungen am Ende löschen (die will ich ja auch nicht 
ändern).
Diese Datei schiebe ich in eine eigens dafür erstellte Hardware mit USB. 
Das Programm filtert aus diesem "Rest-Hex" nun die eigentlichen Bytes 
heraus (Anzahl Bytes am Beginn der Zeile, Zeilen-Nummer, Datentyp, CRC 
am Ende weglassen), codiert die Bytes noch (werden beim Empfang über 
UART vom Modul wieder decodiert), so dass ich also am Ende eine neue 
Datei habe, die einfach nur aus den Bytes besteht, die später genauso im 
Hauptprogramm im Flash stehen sollen. Diese fertige Bootloader-Datei 
schiebe ich wieder in den Updater.
Der Updater ruft das Modul im Hauptprogramm auf: "Nimm Update entgegen". 
Dann springt es zum Bootloader-Bereich (Beginn). Das Hauptprogramm 
beginnt natürlich klar definiert z.B. bei Hx600 (mit Org-Anweisung für 
den Compiler und PCLATH und PCL für den Counter).
Also VOR Hx600 arbeitet nun der Bootloader: Nimmt die Bytes entgegen 
(wie schon gesagt, immer 64), decodiert sie und löscht und schreibt neu 
ab Hx600 beginndend...
Bei Versuchen, den Bootloader ans Ende zu verbannen und den gesamten 
Bereich von Null beginnend neu zu schreiben, arbeitet das 
Bootloader-Programm nicht. Ich sehe hinterher, dass er 2 x 64-ziger 
Blöcke gelöscht hat, mehr macht er in diesem Fall nicht!!! ???

von Daniel V. (danvet)


Lesenswert?

Verstehe ich das jetzt richtig?
Du hast einen SourceCode, der beinhaltet den Bootloader und deine 
Anwendung.
Wenn du das komplett auf den PIC brennst, dann funktioniert dein 
Programm.
Wenn du jetzt dein Hex-File bearbeitest, dass nur noch die Anwendung 
drin ist, und das jetzt über den Bootloader drauf flashst, dann 
funktioniert dein Programm nicht mehr richtig. Das jetzt ausgelesene 
Hex-File aus dem PIC ist nicht identisch mit dem Original-File.
mögliche Ursachen:
a) du hast dein Hex-File falsch bearbeitet
b) der converter des Rest-Hex-Files ist falsch
c) dein bootloader macht nicht was er soll

Hinweis:
In der Regel verwendet man Bootlader anders:
https://www.google.de/search?q=pic18+bootloader&ie=utf-8&oe=utf-8&gws_rd=cr&ei=0ppmVsGwEYGxaZjOgvAP

: Bearbeitet durch User
von Bernd I. (Gast)


Lesenswert?

Hallo Daniel. Genau so - alles richtig verstanden !!!
Nach dem Bearbeiten/Verändern/Erweitern des Programms wird natürlich 
erst mal das Programm "normal" mit Flashen getestet. Es funktioniert!
DANN mache ich daraus auf beschriebene Weise die Update-Datei. Und mein 
Bootloader macht alles richtig! Es stehen ja am Ende alle Bytes genau so 
drin, wie sie sollen. Problem ist ja, dass sich das Programm noch bevor 
der Bootloader-Bereich beginnt (obwohl ich ihn am Beginn des Programms 
schreibe) zum neuen Programm unterscheidet. Und wenn ich das korigieren 
will (durch den Booloader), arbeitet er nicht, wie schon beschrieben 
(Löscht nur 2 Blöcke).
Wie Du schon richtig sagst: Ich muss das alles verstehen. Und das will 
ich eben. Ich schaue mir mal deinen Link an. Es ist aber nicht so, dass 
ich nicht schon viel, viel recherchiert habe. Aber alles Gefundene ist 
eins unverständlicher als das andere. Das ist alles nur abstrakt. Was da 
KONKRET (wann wird welches Byte, wo gesetzt), abläuft, kann immer keiner 
so richtig sagen. Ich denke eher in Bits und Bytes, nicht in 
"Schlagwörtern"

von Daniel V. (danvet)


Lesenswert?

Bernd I. schrieb:
> Hallo Daniel. Genau so - alles richtig verstanden !!!
> Nach dem Bearbeiten/Verändern/Erweitern des Programms wird natürlich
> erst mal das Programm "normal" mit Flashen getestet. Es funktioniert!
> DANN mache ich daraus auf beschriebene Weise die Update-Datei. Und mein
> Bootloader macht alles richtig! Es stehen ja am Ende alle Bytes genau so
> drin, wie sie sollen. Problem ist ja, dass sich das Programm noch bevor
> der Bootloader-Bereich beginnt (obwohl ich ihn am Beginn des Programms
> schreibe) zum neuen Programm unterscheidet.

Offensichtlich schreibt dein Bootloader an verbotene Adressen.
Der Bootloader darf erst ab Hx600 (in deinem Fall) schreiben, alles 
andere ist verboten.
Vielleicht solltest du diese Adressabfrage im Bootloader noch einbauen 
(evtl. auch für die Obergrenze der Adresse (Config-Bereich)? Dann 
bräuchtest du dein Hex-File auch nicht bearbeiten.

Entweder macht dein Bootloader einen Fehler oder der Converter erzeugt 
verbotene Adressen, oder deine Hex-File Bearbeitung hat einen Fehler.

Gruß,
Daniel

von boot (Gast)


Lesenswert?

Das ist alles viel zu viel Prosa.

Hast du dir mal die SPeiherbereiche aufgezeichnet eingezeichnet was wo 
liegt, was nach dem Reset ausgeführt wird, was der "Bootloader" 
überschreibt, wo er überhaupt liegt, wie das Programm gestartet wird?

Prosa in einen Roman packen.
Schaltpläne und übersichtliche Entwurfsgrundlagen hier posten.

Alles andere führt nur zu Mißverständnissen, die du vielleicht sogar 
selbst hast.

Weil wenn du es verstehen würdest, hättest du kein Problem.

von Bernd I. (Gast)


Lesenswert?

Hallo Daniel,
nein, nein, mein Bootloader macht alles richtig!
Vergiss mal für einen kleinen Augenblick das Wort "Bootloader". Noch 
bevor ich diese Wort in den Mund genommen habe, unterscheiden sich die 
beiden HEX (altes und überarbeitetes Programm) im Bereich VOR der Hx600, 
obwohl ich im Compiler nur mein Hauptprogramm bearbeitet habe. Also das 
Problem wird sicher der Compiler sein. Was macht er, wenn ich im 
Hauptprogramm neue Variablen benutze?

Vielen Dank für den Link. Das Dokument kenne ich. Und wie schon gesagt: 
Ich möchte nicht vom PC mit einer Software updaten, zumal sich meine Art 
mit dem separaten "Updater" förmlich aufdrängelt, da die Module alle am 
RS485 hängen und der Master hier nach Aufruf des Programms über 
Touch-Screen gezielt dieses oder jenes Modul updaten kann, ohne das der 
Nutzer irgentetwas an- oder abklemmen muss (lediglich die Datei, die er 
von mir per Mail bekommen hat, per USB-Kabel von seinem PC auf den 
Master mit USB-Anschluss schieben muss).

Gruß, Bernd

von Bernd I. (Gast)


Lesenswert?

Hallo lieber Gast,
genau deshalb sind wir ja hier im Forum, weil wir dieses oder jenes 
nicht sofort verstehen, weil es uns nicht schon bei der Geburt in die 
Wiege gelegt wurde.
Habe mir alles genau angesehen und weiß ja, was gemacht wird. Das ist ja 
nicht das Problem. Schaltpläne nützen hier sicher gar nichts! Ist ein 
PIC. Ich gehe mal davon aus, dass du weißt, wie man den beschaltet...

Liebe Grüße, Bernd

von Daniel V. (danvet)


Lesenswert?

Bernd I. schrieb:
> Hallo Daniel,
> nein, nein, mein Bootloader macht alles richtig!

Sagt wer?

> Vergiss mal für einen kleinen Augenblick das Wort "Bootloader". Noch
> bevor ich diese Wort in den Mund genommen habe, unterscheiden sich die
> beiden HEX (altes und überarbeitetes Programm) im Bereich VOR der Hx600,
> obwohl ich im Compiler nur mein Hauptprogramm bearbeitet habe. Also das
> Problem wird sicher der Compiler sein. Was macht er, wenn ich im
> Hauptprogramm neue Variablen benutze?

Dein Compiler macht sicherlich alles richtig.
Deine hinzugefügten Variablen ändern nicht den Flash-Inhalt.
Welche Adressen wurden verändert? Was liegt an diesen Adressen?

Vergleiche mal die MAP-Files.

>
> Vielen Dank für den Link. Das Dokument kenne ich. Und wie schon gesagt:
> Ich möchte nicht vom PC mit einer Software updaten, zumal sich meine Art
> mit dem separaten "Updater" förmlich aufdrängelt, da die Module alle am
> RS485 hängen und der Master hier nach Aufruf des Programms über
> Touch-Screen gezielt dieses oder jenes Modul updaten kann, ohne das der
> Nutzer irgentetwas an- oder abklemmen muss (lediglich die Datei, die er
> von mir per Mail bekommen hat, per USB-Kabel von seinem PC auf den
> Master mit USB-Anschluss schieben muss).

Hört sich komplex an.

Ich fürchte, wie mein Vorredner, ohne weitere Fakten (SourceCode, etc.) 
kann dir keiner weiterhelfen.

: Bearbeitet durch User
von Bernd I. (Gast)


Lesenswert?

Ohne viel Prosa:
Hatte das Problem nach vielen Experimentieren an einem anderen Projekt 
schon vor Monaten mal gelöst. Hier stand das erste mal die Forderung 
nach Update-Fähigkeit.

Habe das Problem jetzt wieder (fast) im Griff.
Ich hatte diesmal wirklich einfach nur vergessen, eine neue Variable, 
die vom Hauptprogramm beim Start aus dem EEProm ausgelesen werden muss, 
nach dem Update durch das Programm selbst in den EEProm schreiben zu 
lassen. Sorry !!
Und gepaart mit einem 2. kleinen Problem, was jetzt immer noch besteht:
Es funktioniert erst dann, wenn das Modul nach dem Update stromlos 
gemacht wird (ist Mist!). Diese Problematik kannte ich schon und habe 
deshalb nach dem Update ein Watchdog-Absturz provoziert, so dass ein 
Neustart erfolgt. Reicht aber nicht. Erst stromlos-Neustart geht!!!

FRAGE: Gibt es hier eine andere Möglichkeit per Software, die einem 
stromlos machen gleich kommt?

Vielen Dank an alle bis hier her. Gedankenaustausch hilft - denke ich - 
allen. Also, das Prinzip funktioniert!!! Ist ja eigentlich auch 
gaaaaaanz einfach. Hoffe, ich habe anderen dadurch auch Anregungen 
gegeben. Ansonsten Fragen, wenn mehr Info erwünscht.

Also: Stromlos Machen ist in diesem Fall ungünstig! Was tun?

von Eagle-User (Gast)


Lesenswert?

Springst du nachdem du das Update gemacht hast an die Hex 600 oder auf 
den Reset Vector. Falls nicht auf den Reset Vector, dann liegt da dein 
Problem.

von Bernd I. (Gast)


Lesenswert?

Goto Programm         'Bootloader beim Einschalten überspringen

Update-Programm:      'Sprung hier her nur aus Hauptprogramm nach Aufruf
xxx xxx
Update erfolgt (letztes Byte geschrieben, Quittung an Updater - Alles 
OK)
EWrite 255, [1]       'Schreibt in EEProm eine 1, Merkmal für: Update 
erfolgt

    Absturz:
    Goto Absturz      'Watchdog sorgt für Absturz (Neustart)

'XXXXXXXXXXXXX Hauptprogramm XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Programm:
PCLATH = $60
PCL = $00                   'PC auf 600 Hxladen
Org $600                    'Compiler: Hex ab Hx600 erzeugen

   i = ERead 255
   if i <> 1 then Start     'Wenn kein Update erfolgte, weiter im 
Programm

'Neue Versiosnnummer/Datum in EEProm schreiben
'Gegebenefalls neue Parameter in EEProm schreiben
     EWrite 255, [0]        'Merkmal "Update erfolgt" für nächste
                            'Einschalten wieder löschen.

Start:                      'Programm-Beginn
xxx xxx

Lt. Datenblatt (große Reset-Übersicht Blockschaltbild) führen alle 
Reset-Ereignisse (POR, BOR, WDT usw.) zu einem einzigen Ergebniss: 
Chip_Reset\
Wo springt er also hin, wenn nicht auf den Reset-Vektor?
ich versuche es aber mal direkt mit einer Reset-Instruktion!!!
Melde mich wieder...

von Bernd I. (Gast)


Lesenswert?

Auch die Anweisung "Reset" bringt nichts:

    'Fertig mit Update
    Absturz:
    Reset                      'Trotzdem stromlos machen erforderlich.

Gruß, Bernd

von Bernd I. (Gast)


Lesenswert?

Hallo Daniel, Dieter, Wolgang und Gast,
was soll ich Euch sagen: Alles PERFEKT!
Warum ich mich hier her mit der Bitte um Hilfe gewendet hatte (nach 5 
Jahren mal wieder): Ich hatte in meinem gut 10 jährigen 
"Mikroprozessor-Leben" noch nie solche massiven Probleme, wie mit dieser 
Update-Geschichte. Klar hängt man immer wieder mal Stunden, oder auch 
Tage fest, aber das hier beschäftigte mich immer wieder regelmäßig 
monatelang. Und ich dachte vor gut einem Jahr, alles gelöst zu haben. 
Jetzt traten die selben Symptome wieder auf, aber diesmal waren es alles 
nur "Patzer".
Auch der Neustart funktionert (stromlos machen nicht mehr erforderlich), 
war auch nur meine eigene Schuld.

Also Leute: So kann man ein PIC's updaten (zumindest PIC18-Familie, mit 
anderen noch nicht getestet)! Und für Anwendungen, in denen viele 
(hunderte) Module in einem Netz hängen, irgentwo unter abgehangenen 
Decken oder in UP-Dosen verbaut sind und sowieso von einem zentralen 
Steuergerät überwacht werden, da ist das eine ideale Lösung.

Noch zu beachten: Alle verwendeten Variablen im Bootloader dürfen nicht 
im Hauptprogramm verwendet werden (und umgekehrt). Sprünge aus dem einen 
zum anderen natürlich streng verboten.
Ich biete es noch einmal an: Wenn etwas gründlichere Informationen 
gewünscht sind, dann hier melden.

Frohe Weihnachten und ein erfolgreiches PIC-Jahr!
Eagle-User und PIC-Programmierer Bernd

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.