Derzeit habe ich eine in meiner Firmware fest codierte Seriennummer für ein Design, mit dem ich arbeite. Die Firmware kann die Seriennummer lesen und zurückmelden. Das funktioniert gut für das, was ich brauche. Das Problem ist, dass ich bei jeder neuen Seriennummer meinen Code ändern und neu kompilieren muss. Dies ist umständlich, wenn viele Einheiten gebaut werden müssen, möglicherweise Fehler auftreten und eine rundum schlechte Praxis ist. Die Seriennummern werden mir gegeben und das Hardware-Design ist in Stein gemeißelt, sodass ich keine Hardware-Funktionen zur Serialisierung der Einheiten hinzufügen kann (EEPROM / Silicon ID Chip / Pull-Ups). Ich möchte die Seriennummer an einer festen Adresse suchen, den Code einmal kompilieren und diese Adresse dann in der kompilierten HEX-Datei für jede neue Seriennummer bearbeiten. Die Nummer wird an mehreren Stellen referenziert, daher möchte ich sie im Idealfall einmal definieren und lokalisieren. Verweisen Sie dann überall in meinem Code auf diese "Variable". Weiß jemand, wie man mit dem C18-Compiler konstante Daten an einem bestimmten adressierbaren Speicherort meiner Wahl findet? Gibt es einen besseren Weg, den jemand vorschlagen kann?
quelle
Antworten:
Um die Frage der Bindung von Variablen an bestimmte Adressen im Flash-Speicher des PIC18 mit dem C18-Compiler zu lösen, lesen Sie bitte den Abschnitt "Pragmas" in der Datei hlpC18ug.chm im Verzeichnis doc, in dem der Compiler installiert ist.
Dazu müssen Sie einen neuen "Abschnitt" im Speicher definieren und ihn an eine Startadresse binden
#pragma romdata serial_no_section=0x1700
Dadurch wird ein neuer Abschnitt mit dem Namen "serial_no_section" erstellt, der an der Adresse 0x1700 im Flash-Speicher (Programmspeicher) beginnt (da wir "romdata" im #pragma definiert haben).
Definieren Sie Ihre Variablen direkt nach der Zeile #pragma wie folgt:
Jetzt haben Sie 0x12 an der Adresse 0x1700 und 0x34 an der Adresse 0x1701 im Speicher (da PIC18 das Little-Endian-Modell verwendet). Das "const rom" stellt sicher, dass der Compiler weiß, dass dies ein const-Variablentyp ist und dass die Variable im "rom" -Speicher liegt und daher über Tabellenleseanweisungen zugegriffen werden muss.
Die letzte
#pragma romdata
Anweisung stellt sicher, dass alle folgenden Variablendeklarationen mit Standardspeicherabschnitten verknüpft sind, wie der Linker dies für richtig hält, anstatt im Abschnitt "serial_no_section" weiterzumachen.Jetzt kann der gesamte Code einfach auf die Variable "mySerialNumber" verweisen, und Sie wissen genau, unter welcher Adresse sich die Seriennummer im Speicher befindet.
Das Bearbeiten des HEX-Codes kann etwas schwierig sein, da Sie die Prüfsumme für jede von Ihnen bearbeitete Zeile berechnen müssen. Ich arbeite an einer C ++ - Klasse, um Intel HEX-Dateien zu dekodieren und zu kodieren, was dies einfacher machen sollte, aber es ist noch nicht fertig. Das Dekodieren von Dateien funktioniert, das erneute Kodieren ist noch nicht implementiert. Das Projekt (wenn Sie interessiert sind) ist hier https://github.com/codinghead/Intel-HEX-Class
Hoffe das hilft
quelle
Ich habe die Seriennummer (kurz s / n) ähnlich wie Joel beschrieben. Ich habe PIC18F4620 und CCS Compiler verwendet. Die Position von s / n im Flash-Speicher wurde auf die letzten 4 Bytes erzwungen. Da ich nur 80% von Flash verwendet habe, haben mein Compiler und Linker in den letzten 4 Bytes keinen ausführbaren Code geschrieben.
Dann hatte ich zwei alternative Möglichkeiten, um S / N tatsächlich in einzelne Einheiten zu schreiben:
Antworte auf Joels Kommentar
Ich weiß nichts über C18, aber der CCS-Compiler verfügt über Bibliotheksfunktionen
write_program_eeprom(...)
undread_program_eeprom(...)
. So sehen sie in der Montage aus.quelle
write_program_eeprom(...)
undread_program_eeprom(...)
. Das EEPROM und Flash sind zwei verschiedene Dinge!Ich habe das ein paar Mal gemacht. Normalerweise definiere ich einen Firmware-Infobereich an einem festen Ort im Programmspeicher und schreibe dann ein Programm, das aus der HEX-Vorlagendatei eine serialisierte HEX-Datei erstellt. Dies sind alles einfache Dinge zu tun.
In der Produktion führen Sie das Serialisierungsprogramm einmal aus, nachdem alle Tests bestanden wurden. Es erstellt die temporäre HEX-Datei mit der eindeutigen Seriennummer, die in den PIC programmiert wird, und löscht dann die temporäre HEX-Datei.
Ich würde nicht zulassen, dass der Standort verlegt werden kann, und muss ihn dann finden. Das kann jeden Build ändern, wenn der Linker Dinge bewegt. Ich habe das für sehr kleine PICs wie die 10F-Serie gemacht, bei denen diese Konstanten Teil der MOVLW-Anweisungen sind. In diesen Fällen habe ich die MAP-Datei im laufenden Betrieb gelesen, um festzustellen, wo sich diese Speicherorte befinden. Ich habe MPLINK MAP-Datei-Parsing-Code in einer Bibliothek nur für diesen Zweck.
Um etwas an einem festen Ort zu platzieren, definieren Sie ein Segment an einer festen Adresse. Der Linker platziert zuerst solche absoluten Segmente und dann die verschiebbaren um ihn herum. Vergessen Sie nicht, CODE_PACK anstelle von CODE auf einem PIC 18 zu verwenden, da Sie sonst ganze Instruktionswörter anstelle einzelner Bytes verwenden. Zum Beispiel (nur eingegeben, nicht am Assembler vorbei):
quelle
Ich würde vorschlagen, die Seriennummer in einer festen Adresse zu speichern. Abhängig von Ihrem Compiler / Linker und dem betreffenden Teil gibt es einige Ansätze, die Sie verfolgen können:
quelle
retlw
Ansatz jedoch oft viel schneller (bei 18-Bit-PICs dauert acall
bis aretlw
insgesamt vier Zyklen; die Verwendungclrf TBLPTRU/movlw xx/movwf TBLPTRH/movlw xx/movwf TBLPTRL/tblrd *+/movf TABLAT,w
würde acht dauern).Ich würde das Gegenteil tun: Kompilieren und verknüpfen Sie den Code und finden Sie dann heraus, wo der Wert in der Linker-Datei gespeichert ist. Möglicherweise müssen Sie die Variable explizit in einem Segment suchen, das dem Flash zugeordnet ist.
Ich habe nicht danach gefragt, aber die PC-Software, die ich für meinen Wisp648-Programmierer bereitstelle, kann eine .hex-Datei lesen, einen bestimmten Speicherort ändern und die .hex-Datei zurückschreiben (in dieselbe oder eine andere Datei). Mein Programmierer muss nicht anwesend sein. Quelle ist verfügbar (in Python), Lizenz erlaubt jede Nutzung: www.voti.nl/xwisp Könnte nützlich sein, wenn Sie Ihr primäres Problem gelöst haben.
quelle