Hallo zusammen,
ich arbeite an einer Leiterplatte mit einem Mikrocontroller (STM32H743)
bei dem es voraussichtlich im Laufe der Zeit ein paar Hardwareänderungen
geben wird. Ich würde jetzt gerne eine Hardwareversionsnummer im
Mikrocontroller speichern, so dass bei Firmware-Updates die Firmware
weiß was an welchen Pins hängt etc. Problem ist bei meinem
Mikrocontroller, dass es anscheinend außer dem Flash keine Möglichkeit
gibt etwas dauerhaft zu speichern (auch wenn es laut einigen Dokumenten
2kbyte user option bytes geben sollte). Ich habe über folgende
Möglichkeiten nachgedacht:
1) Eine Seite des Flashs für die Versionsnummer zu reservieren. Problem
ist, dass das 128k wertvoller Speicher sind, und ich eventuell sehr bald
Daten auf einen externen Flash auslagern muss.
2) Momentan ist ein FRAM angeschlossen, auf dem ich die Versionsnummer
speichern könnte. Das bedeutet dann allerdings, dass dieser immer an den
jetzigen Pins hängen muss.
3) Kodierung der Versionsnummer durch einen hardware-seitig festen Pegel
an verschiedenen Pins. Problem ist auch hier, dass das immer die
gleichen Pins sein müssen. Ich kann momentan schlecht abschätzen wie
viele Revisionen es eigentlich geben wird.
Ich tendiere ein wenig zur Option 2. Habt ihr da eine starke Präferenz
bei euren eigenen Projekten? Ich bin leider relativ neu in dem Bereich
und wäre sehr über ein paar eurer Kommentare dankbar.
> 3) Kodierung der Versionsnummer durch einen hardware-seitig festen Pegel> an verschiedenen Pins.
Das ist das, was meist gemacht wird. Teilweise über Pull-Ups/Downs an
Pins, die im Normalbetrieb auf Output stehen (wird dann im Reset
eingelesen). Ggf kanns du auch Widerstandswerte per ADC einlesen
(braucht weniger Pins). Gerne werden auch Bestückungsvarianten kodiert.
Im µC selbst ist mMn quatsch - dann muss der ja erstmal für die Platine,
auf der er eingesetzt wird, geflasht werden und das ist ja genau das,
was du vermeiden willst.
Externer nicht-flüchtiger Speicher ist ähnlich blöd - erfordert einen
zusätzlichen Programmierschritt nach der Bestückung, der µC kann den ja
nicht selbst initialisieren.
Wie wäre es mit einem build switch in der Firmware. Für die
entsprechende Hardwarerevision ein spezifisches Binary zu kompilieren
sollte ja kein Problem sein. Außerdem spart man so unnötigen Code der
das Handling zur Laufzeit macht, dass kostet nur unnötig Ressourcen.
Ein 1-wire EEprom dafür vorsehen.
Wenn es klein sein soll: DS2431 in 6pin BGA.
foobar schrieb:> Externer nicht-flüchtiger Speicher ist ähnlich blöd - erfordert einen> zusätzlichen Programmierschritt nach der Bestückung, der µC kann den ja> nicht selbst initialisieren.
Den kann man ja auch vor der Bestückung programmieren.
Irgendwelche Pins für die Kodierung zu reservieren, finde ich recht
suboptimal im Verhältnis von Pinverbrauch zur Informationsdichte.
Eine Kröte wird der TO wohl schlucken müssen.
Kevin M. schrieb:> Wie wäre es mit einem build switch in der Firmware. Für die> entsprechende Hardwarerevision ein spezifisches Binary zu kompilieren> sollte ja kein Problem sein. Außerdem spart man so unnötigen Code der> das Handling zur Laufzeit macht, dass kostet nur unnötig Ressourcen.
Das seh ich auch so. Sofern es kein Problem ist größere Container-Files
für Updates zu nutzen kann man problemlos verschiedene Binaries
nebeneinander speicher und das richtige anhand einer ID einspielen.
Nachteil ist halt größere Komplexität bei Produktion/Update.
Vincent H. schrieb:> und das richtige anhand einer ID einspielen.
Und die Frage geht darum wie und wo man diese ID speichert.
Dass man X unterschiedliche Firmwareversionen in ein "Containerfile"
(angeberische Bezeichnung für eine popelige ZIP-Datei) packen kann ist
nun wirklich nicht das Problem.
Wer es hochtrabend haben will, das Ganze ist ein Problem aus dem
Identitätsmanagement. Wie versehe ich einer Entität mit welchen
Attributen um ihr für die gewünschte Anwendung eine Identität zu geben.
Wer es praktisch haben will, irgend einen Tod muss man sterben. Seien es
reservierte Pins, Speicheradressen, Unterprogramm-Adresse etc. Sei es
eine Datenbank die eine vorhanden ID (STM32 Hardware ID, MAC Adresse,
etc.) auf die Firmware-Version abbildet. Sei es ein Aufdruck, Aufkleber,
Markierung, Barcode etc. die ein menschlicher Bediener
(semi-automatisch) ablesen muss. Sei es ein mechanischer Unterschied
(z.B. Position, Art des Programmiersteckers). Sei es spezieller
Speicher, ein zusätzlicher "Management"-Mikrocontroller, ID-Chip, ...
Die ideale, immer passende Lösung gibt es nicht. Eine gute Lösung ist
eine, die im Gesamtsystem, für die meisten Standardfälle, zu
vernünftigen Kosten funktioniert.
Dafür muss man das eigene Gesamtsystem verstehen und die eigenen
Standardfälle kennen. Zum Beispiel auch die vorhandene
Wartungsorganisation. Wie einfach es ist an das Gerät ranzukommen? Soll
aus aus der Ferne oder vor Ort neue Firmware eingespielt werden? Wird
überhaupt neue Firmware im Feld eingespielt? Modul- oder Boardtausch im
Feld ist eine beliebte Alternative, weil der gemeine IT-Hausmeister für
Firmwareupdates zu blöd ist). Welchen Grad der Automatisierung muss man
haben? Folgekosten wenn es schief geht? Usw. usw.
Hannes J. schrieb:> Vincent H. schrieb:>> und das richtige anhand einer ID einspielen.>> Und die Frage geht darum wie und wo man diese ID speichert.
Wie wärs mit dem Prozessorflash...?
Ich verwende immer ein I2C Eeprom. Den I2C Bus brauche ich eh noch für
andere Sensoren. Da wird dann einfach ein 1Kbit Eeprom für Version und
Setup aufgespielt.
Das mit dem Flash habe ich mal versucht, aber nach dem Ändern war immer
ein Hardreset nötig. Ausserdem ist bei dem Prozessor eine Page immer
gleich 128 Kbytes groß.
Max schrieb:> 3) Kodierung der Versionsnummer durch einen hardware-seitig festen Pegel> an verschiedenen Pins. Problem ist auch hier, dass das immer die> gleichen Pins sein müssen. Ich kann momentan schlecht abschätzen wie> viele Revisionen es eigentlich geben wird.
Das ist die einzige Option von deiner Auswahl die das Problem wirklich
einigermaßen sicher löst.
Du könntest auch deine Supply mit einem Teiler abgreifen und mit Adc
einlesen, und den Widerstand je nach Hardwareversion ändern.
Max schrieb:> Ich kann momentan schlecht abschätzen wie> viele Revisionen es eigentlich geben wird.
Muß du auch nicht, das legt das Projectmanagment fest, wann welche neue
(nicht abwärtskompatible) Hardware-version während der
Produktlebensdauer releast wird.
4 bits (15 Versionen) reichen völlig, weil so eine Hardwareveränderung
macht man nicht mehrmals am Tag. In der Regel bündelt man ohnehin mehere
Änderungen zu einerm 'Musterstand' der dann offiziel übers
Änderungswesen releast. Und ohne unnötigen Mehraufwand ist nur eine
geringe Anzahl von Musterständen (auch Modellpflege, oder
Produktionskostenoptimierte Variante), realisierbar, bspw. einmal im
Jahr. Selbst bei einem Millionenseller wie den Commodore Amiga500
damals, genügte eine einstellige Anzahl von Revisionen:
https://www.amigawiki.org/doku.php?id=de:models:a500
> 4 bits (15 Versionen) reichen völlig...
Dem stimme ich zu, das reicht für >=85% der Anwendungen. Und wenn nicht,
dann investierst du ein bisschen zusätzliches Hühnerfutter (Widerstände)
und liest trinär ein, damit hast du 81 Versionen auf den vier
Portpins...
Grüße
>(auch wenn es laut einigen Dokumenten>2kbyte user option bytes geben sollte)
was spricht denn gegen den?
Da könnte es sogar HAL-Funktionen dafür geben.
Bei einigen Geräten habe ich im Programmcode eine Konfigurationsdatei
hinterlegt, die anhand der "Unique device ID" die entsprechende
Konfiguration zuordnen kann. Beim Programmstart wird einfach die ID vom
STM32 ausgelesen und alles eingestellt. Bei der ersten Inbetriebnahme
muss man halt die ID auslesen und alles in der Konfig richtig zuordnen.
Wenn man Geräte beim Kunden hat, kann er einfach über einen Bootloader
Firmwareupdates machen und es wird immer die richtige Einstellung
geladen.
> Bei einigen Geräten habe ich im Programmcode eine Konfigurationsdatei> hinterlegt, die anhand der "Unique device ID" die entsprechende> Konfiguration zuordnen kann.
Das bedingt aber doch, dass du im Voraus alle infrage kommenden UIDs
kennst, oder? Für ne Handvoll Geräte kann ich mir das vorstellen, aber
wie löst du das ab 1k aufwärts?
Grüße
dummschwaetzer schrieb:>>(auch wenn es laut einigen Dokumenten>>2kbyte user option bytes geben sollte)> was spricht denn gegen den?
das sind alles Einstellungen wie Schreibschutz, ob der Watchdog sofort
startet, ab welcher Adresse der Coprozessor bootet usw. und schon sind
2K voll. Man könnte höchstens tricksen, z.B. auf den Schreibschutz
verzichten und das dann freie Byte benutzen.
Aber was spricht gegen den Spannungsteiler an einem ADC-Eingang? Das
braucht nur einen Pin für mehr als 15 Versionen (wie viele würdet ihr
wagen?). Solange man mit sowieso nötigen Widerstandswerten auskommt,
kostet das praktisch nichts. Solange die Platine richtig bestückt ist,
passt es ganz von alleine, ohne manuelle Zuordnung und Eingabe.
Ja, der eine Pin muss für alle Zeiten festgelegt sein, man sucht sich
natürlich einen, auf dem sonst nicht viel drauf ist. Und ja, der
kleinste H7 hat nur 8 ADC-Eingänge wenn man HS-USB braucht. Opfer müssen
gebracht werden ;)
Wenn zufällig ein I2C-LED-Treiber auf der Platine ist, kann mit dessen
/Adress/-Pins fast 100 Versionen unterscheiden.
Wir haben angefangen RFID-Chips mit I2C Schnittstelle mit auf die
Platine zu packen. Der Bestücker programmiert Datum und Hardwarerevision
beim Bestücken mit rein. Über die I2c Schnittstelle kann ich die Version
abfragen und auf Kompatibilität prüfen.
Ich hab dafür 8 Portpins mit 0-Ohm Widerständen vorgesehen, die MCs
haben ja heutzutage massig IO-Pins.
Der Vorteil ist, man kann bequem verschiedene Bestückungsvarianten
pflegen und die Firmware erkennt automatisch, welche Variante die
Platine hat.
In der Regel hat man auch massig Flash, so daß man alle Varianten in
einer Firmware pflegen kann.
Die Unterscheidung nur mit einem Speicher hat den Nachteil, daß man von
außen nicht erkennen kann, welche Variante das ist. Und in der Fertigung
ist ein zusätzlicher Schritt nötig, diesen Speicher mit der richtigen
Signatur zu programmieren und es darf dabei kein Fehler passieren.
Schnell ist mal das falsche Hexfile angeklickt oder die falsche Platine
aus der Schütte gegriffen.
Ohne die Hardwareerkennung gab es bei der Variantenpflege ständig Ärger.
Gerald M. schrieb:> Wir haben angefangen RFID-Chips mit I2C Schnittstelle mit auf die> Platine zu packen. Der Bestücker programmiert Datum und Hardwarerevision> beim Bestücken mit rein. Über die I2c Schnittstelle kann ich die Version> abfragen und auf Kompatibilität prüfen.
Das klingt jedoch nicht nach Massenproduktion und nicht jedermann seine
Loesung, doch finde ich sie cool, besonders wenn man das mit einem MES
verbindet -> optische Lesegeraete entfallen.
> Der Bestücker programmiert Datum und Hardwarerevision> beim Bestücken mit rein.
War ist das fuer ein Bestuecker, kommen die RFID´s nicht von einem
Feeder?
Klingt interessant!
Birke E. schrieb:> Das klingt jedoch nicht nach Massenproduktion und nicht jedermann seine> Loesung
Das ist tatsächlich genau die Lösung für die Produkte die hunderte bis
tausende Male im Jahr produziert werden. Für viele ist das nicht
Massenproduktion, für uns ist das das obere Ende des Verarbeitbaren.
Birke E. schrieb:> War ist das fuer ein Bestuecker, kommen die RFID´s nicht von einem> Feeder?
Doch, aber auf dem Band nach dem Löten zum Abkühlen ist ein Schreibgerät
angebracht. Das ist alles Vollautomatisch.
Gerald M. schrieb:> Über die I2c Schnittstelle kann ich die Version> abfragen und auf Kompatibilität prüfen.
Eine Nummer einfacher als RFID wäre auch ein I2C-Port Expander mit
unterschiedlich beschalteten Pull-Ups/Downs. Je nach Anzahl der zu
erwarteten Revisionen sind problemlos 16 oder 256 Revisionen
realisierbar mit wenig PCB-Fläche. Auslesen in der Software wäre immer
gleich.