ich habe ein kleines Arduino Projekt, dass ich mit einer laufenden HW-Nummer generieren möchte. Jeder Prozessor soll ein identisches Projekt bekommen und nur die HW-Nummer soll unterschiedlich sein.
Dazu müsste ich das Projekt jedesmal mit einer neuen Variablen HWNummer neu kompilieren, was ein wenig aufwändig ist.
Ich habe deshalb folgendes versucht:
Im Sketch deklariere ich eine Variable, z.B:
String HWNummer = "123456789";
Nach dem compilieren habe ich jetzt in der HEX-Ausgabe nach diesem String gesucht, in der Hoffnung, dass ich da einfach rüber patchen kann.
Ich finde aber im HEX-File keinen Zeichenfolge 123456789. Weiß jemand, wie man das machen könnte?
Ich fürchte, selbst wenn deine ursprüngliche Fragestellung gelöst wird, dass es nicht funktionieren wird, weil da mit Sicherheit zur Absicherung der Übertragung ein MD5 Code von der original übersetzen SW drin steckt, der dann im Ziel überprüft wird. Wenn du also in der Firmware-Datei patchst, wird das als (Übertragungs?-) Fehler erkannt werden.
/*
Blink
Turns on an LED on for one second, then off for one second, repeatedly.
This example code is in the public domain.
*/
// Pin 13 has an LED connected on most Arduino boards.
// Pin 11 has the LED on Teensy 2.0
// Pin 6 has the LED on Teensy++ 2.0
// Pin 13 has the LED on Teensy 3.0
// give it a name:
int led = 13;
const char * HWNummer = "123456789";
// the setup routine runs once when you press reset:
void setup() {
// initialize the digital pin as an output.
pinMode(led, OUTPUT);
Serial.begin(9600);
Serial.println(HWNummer);
}
// the loop routine runs over and over again forever:
void loop() {
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
Wenn der String nicht verwendet wird, wird der Compiler den String gar nicht in die Firmware eincompilieren. Außerdem werden die ASCII Werte im Code stehen. Also nicht 123456 sondern "313233343536". Du musst also nach den ASCII Werten suchen.
Was z.B. ginge wäre volatile constexpr char HWNR[] {"123456"};
Der String wird dann als "313233343536" im Hex File zu finden sein.
Edit: @agmue war etwas schneller. Was er macht funktioniert aber auch nur, weil die definierte HWNummer mit Serial.println(HWNummer); im Code verwendet wurde.
Darum habe ich in meinem Beispiel volatile davor gesetzt, damit die Definition vom Compiler nicht herausoptimiert wird, da der Wert nie verwendet wird.
Schreib dir einmal ins EEPROM von jedem Target eine ID und im Code list du die ID ein.
Alle Targets bekommen den gleichen Code, haben aber eine abweichende ID (im EEPROM).
Wenns nicht so viele verschiedene Möglichkeiten braucht dann kannst Du auch einige Eingänge mit Dip-Schalter bestücken. (Auch Stiftleisten mit Jumper oder auch Lötbrücken) um eine Zahl zu übergeben. Bei 4 Pins sind 16 verschiedene Zahlen möglich.
Brauchst Du größere Zahlen kannst Du ja 16 Zahlen in ein Array schreiben und mittels der Eingänge eines der Elemente des Arrays verwenden.
Grüße Uwe
Ja, das könnte man so machen. Aber ich wüsste nicht, wie ich eine ID in das EEPROM schreiben könnte, ohne zuvor einen Build und Download auszuführen. Und das dann für jede Nummer, oder kann ich direkt in das EEPROM schreiben, aus der IDE heraus?
Also wenn ein einfacher EEPROM put sketch auch zu viel Arbeit ist, dann würde ich im Programm eine Konfiguration vorsehen und ein Mäuseklavier oder eine Programmierung via Serieller Schnittstelle vorsehen.
Ich weiß nicht ob das wirklich klappt aber nach der Doku von avrdude kann man das Programm in einen Terminal Mode versetzen und dann Daten in das EEPROM schreiben.
Also so in der Art:
avrdude -t << END
write eeprom 0x50 0x10
quit
END
Obs wirklich so funktionier habe ich aber noch nicht ausprobiert.
Ich habe das jetzt mal ausprobiert. Ein Programm mit HWNummer "123456" und einer serialPrint Ausgabe der HWNummer.
Die Hex gepatcht (das mach ich natürlich nicht von Hand, sondern mit einem Programm) auf "363636363636" (also "666666").
Original geladen, Ausgabe ergibt "123456", passt
Patch geladen hat nicht funktioniert-> Checksum error. Ich bekomme zwar die berechnete Checksumme und die gelesene angezeigt, aber wenn ich nicht weiß, wo die steht, nützt das auch nichts...
Ach so, patchen auf "654321" kann hochgeladen werden, sind ja dieselben Zahlen..
Über die serielle Schnittstelle, über I2c, oder über einen ISP Adapter.
Im Prinzip, kann das gehen.
Leider können die meisten Arduino Bootloader das nicht, weil sie in Hauptsache klein sein sollten.
Der Mega Bootloader kann eine Ausnahme sein (ungetestet)
Natürlich!
AVRdude kann auch *.bin Dateien übertragen. Die haben keine Prüfsumme
Auch kann man die Umwandlung zu bin, die Modifikation und zurück nach hex automatisieren.
Stichwort "Builder hooks"
auf dem Wege der Hooks lassen sich auch map Dateien erzeugen, Da stehen alle Adressen drin.
Das kann ich fast nicht glauben, weil die Checksummenbildung eigentlich auch die Positionen mit einbezieht (im einfachsten Fall sowas wie fortlaufende XOR-Bildung oder so, Dann kommt bei einer verdrehten Reihenfolge auch was anderes raus. Und MD5 ist noch eine ganz andere Hausnummer.)
Aber .....
Wenn dem tatsächlich so ist, dann codier doch mit immer der identischen Anzahl Ziffern eine übergeordnete Nummer.
Beispiel:
01 = 0, 10 = 1
(Punkte zur besseren Lesbarkeit:
01.01.01.01.01.10.10.10 = 00000111 = 0x07
10.10.01.01.01.10.01.10 = 11000101 = 0xC5
usw.
Dein gespeicherter Wert hat immer die gleiche Anzahl 0 und 1.
(oder 31 und 35 oder was auch immer)
Aber die Bedeutung lässt sich dann im Programm errechnen.
Aber wie gesagt ... so recht glauben daran kann ich nicht..
Manchmal ist Wissen hilfreicher als Glauben.
Vor allen dingen in Fällen, wie diesen.
Zusätzlich liegen die Spezifikationen öffentlich aus.
Es ist also kein Problem sich die Struktur von Hex Daten anzusehen und diese Dateien zu manipulieren.
Ich kanns ja mal erzählen, was da alles drin steckt:
Zum ersten Punkt sag ich mal nichts....
Zum zweiten:
Eine Funkuhr
Ein GSMshield
Ein angesteuerter Elektromotor
Zwei Hochspannungsgeneratoren
Drei Lagemelder
Ein Infrarot-Bewegungsmelder
Drei Kontakte
Eine angesteuerte LED
Warum ist das interessant?
Kommunizieren tun die untereinander gar nicht.
Zur ID: Damit ich im Störungsfall per SMS eine Nachricht bekomme, anhand der ich identifizieren kann, welches Gerät gestört ist.
Ich habs jetzt doch lösen können. Ich erzeuge die Patch-Datei und werfe die per Batch dem AVRDude vor, dessen Ausgabe ich in eine Datei umlenke. Diese Datei werte ich aus und erhalte die Infos Position der CRC, Soll und Ist CRC.
Damit patche ich die gepatchte Datei nochmal. Und dann geht auch der upload
Das ist zwar ein wenig hinten durch die Brust, ist aber vollautomatisch möglich.