Forum: Compiler & IDEs CRC8 an erzeugte Hexdatei anhängen


von Wolfgang (Gast)


Lesenswert?

Hallo,

ich suche eine Methode, eine CRC8-Checksumme über den Flashspeicher 
eines AVR-Projektes einzufügen (so wie diese Dallas 1-wire CRC). Also 
ich übersetze, nach dem Übersetzen erhalte ich eine Hexdatei. Den 
korrekten Download dieser Datei auf dem Zielsystem würde ich gerne (z.B. 
im Bootloader) überprüfen. CRC8 ist schon im Bootloader vorhanden.

srecord habe ich schon angesehen, das berechnet nur CRC16 bzw. CRC32.

Weiß da zufällig jemand ein Tool oder am besten eine Option, die man bei 
der gcc toolchain aktivieren muß?

Vielen Dank, Wolfgang

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

srecord ist Opensource, man könnte es also entsprechend modifizieren.

Aber eine 8-bit-CRC ist für solche Datenmengen keine sonderlich
glückliche Lösung, da die Wahrscheinlichkeit eines false positives
größer ist als bei einer 16-bit-CRC.  Da es für letztere bereits
vorgefertigte Implementierungen in <util/crc16.h> gibt, was spräche
dagegen, lieber den Bootloader passend „aufzubohren“?

von Jim M. (turboj)


Lesenswert?

Wolfgang schrieb:
> Den
> korrekten Download dieser Datei auf dem Zielsystem würde ich gerne (z.B.
> im Bootloader) überprüfen

Genau dafür gibt es die Checksummen am Ende jeder Zeile, und den End 
Record am Ende des Hex. Ansonsten vergleicht man besser nach dem 
Schreiben den Inhalt des Flashs mit dem Inhalt des Hex. Bei CRC8 
übersieht man Fehler mit 1/256 Wahrscheinlichkeit.

von Wolfgang K. (opendcc)


Lesenswert?

Hallo,

> Genau dafür gibt es die Checksummen am Ende jeder Zeile, und den End
> Record am Ende des Hex.

Das ist schon klar und das prüfe ich auch ab. Wenn jedoch durch 
Übertragungsfehler eine komplette Zeile fehlt, dann hilft das nicht.

Gegen CRC16 spricht schlicht Codesize. Die Flashgröße des 
Bootloaderbereiches ist nicht wirklich üppig und ich segle da ganz knapp 
am Speicherlimit entlang.

Gäbe es denn für CRC16 eine direkte Unterstützung im Linker/Locater von 
GCC?

Servus Wolfgang

von Klaus (Gast)


Lesenswert?

Wolfgang K. schrieb:
> Wenn jedoch durch
> Übertragungsfehler eine komplette Zeile fehlt, dann hilft das nicht

Wie passiert denn sowas? Schickst du für jede Zeile eine eigene 
Brieftaube?

MfG Klaus

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wolfgang K. schrieb:
> Gegen CRC16 spricht schlicht Codesize.

Hast du dir denn <util/crc16.h> mal angesehen?  Eine
CRC-16-Update-Operation ist in 15 oder so Befehlen dort codiert.

von Wolfgang K. (opendcc)


Lesenswert?

> Schickst du für jede Zeile eine eigene Brieftaube?

Nun, in etwa. Ich habe da eine Halbduplexverbindung, teils nur als 
Eindrahtinterface ausgeführt und klappere das Zeile für Zeile ins Ziel. 
Weniger eine Brieftaube, mehr ein Ackergaul.

Servus Wolfgang

von Karl H. (kbuchegg)


Lesenswert?

Wolfgang K. schrieb:
>> Schickst du für jede Zeile eine eigene Brieftaube?
>
> Nun, in etwa. Ich habe da eine Halbduplexverbindung, teils nur als
> Eindrahtinterface ausgeführt und klappere das Zeile für Zeile ins Ziel.

Hmm.
Und der Sender sendet einfach ins Nichts?

Wenn der Sender eine Zeile auf den Weg bringt und der Empfänger 
bestätigen muss, dann sollte das eigentlich ausreichend sein. Auf die 
Art kann sich der Empfänger dann auch seine 'Warte-mal' Zeit generieren, 
die er zum Beispiel benötigt um eine Page in den Flash zu brennen.

Im übrigen gehört für mich eine derartige Absicherung der Übertragung 
nicht ins Hex-File sondern in den Bootloader-Sender bzw. Empfänger. Für 
das Hex-File sollte das IMHO völlig transparent sein.

: Bearbeitet durch User
von Wolfgang (Gast)


Lesenswert?

Hallo,

nein, da habe ich schon eine Quittung, auch mit Sequenzierung. Und der 
Empfänger kann auch ein 'wart doch mal ein bischen, ich muß schreibe, 
schreibe mache' zurück geben. Eigentlich wollte ich nicht die 
Übertragung diskutieren, sondern klären, wie ich das zusätzlich 
absichern kann. Deshalb auch meine obigen Fragen:

- kann man so eine CRC (erst mal egal, welches Polynom) vom GCC erzeugen 
und einfügen lassen? Und kann ich an definierter Stelle im Flash eine 
Size-Variable ablegen (ohne dass ich das Linkerscript 
projektspezifisch ändern muß)?

- Wenn nein, gibt es Tool, dass dieses extern leistet, vorzugsweise mit 
CRC8?

von Phantomix X. (phantomix)


Lesenswert?

Hallo!


Wenn du ein Paar Tage warten kannst, werde ich sehen, dass ich die 
CRC-Berechnung in FirmwareBatchTools ( 
http://firmwarebatchtools.ugfx.org/ ) mit einbaue.
Für dein Vorhaben würde ich das Ganze dann im Kommandozeilenmodus 
empfehlen und direkt in den Buildprozess einbinden (Run after Build).
Zum Thema "Size-Variable an definierter Stelle im Flash ablegen":
Man kann in FirmwareBatchTools Variablen anlegen und an feste 
Speicheradressen schreiben. Die Größe der Firmware bestimmen ist auch 
noch todo


Größe auslesen (Innerhalb deiner Firmware):
Ich weiß jetzt nicht, ob der AVR GCC das unterstützt, beim ARM-GCC geht 
das über das Linker script/file.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wolfgang schrieb:
> - kann man so eine CRC (erst mal egal, welches Polynom) vom GCC erzeugen
> und einfügen lassen?

Nein, zumindest nicht ohne weiteres.

> - Wenn nein, gibt es Tool, dass dieses extern leistet, vorzugsweise mit
> CRC8?

Wenn's unbedingt deine heißgeliebte (und viel zu schwache) CRC-8 sein
muss, was spricht gegen meinen ersten Vorschlag, Srecord dahingehend
zu modifizieren?  Da sie ja schon andere CRCs unterstützen, sollte es
doch trivial sein, den sowieso schon als C-Code vorliegenden CRC-8
da noch zu ergänzen.

Letztlich lebt Opensource genau von sowas: jemand benötigt ein
bestimmtes Feature, und baut es sich ein.

Das wäre jetzt schon fertig, wenn du heute Mittag damit begonnen 
hättest.

von Wolfgang K. (opendcc)


Lesenswert?

Hallo Jörg,

>
> Letztlich lebt Opensource genau von sowas: jemand benötigt ein
> bestimmtes Feature, und baut es sich ein.

Das sehe ich ein bischen anders. Jemand benötigt ein Feature und er baut 
es nicht für sich, sondern für alle nutzbar und sauber ein. Inkl. 
manpage, help usw. Nur dann funktioniert das. Wenn jeder für sich macht, 
ist nichts gewonnen.

>
> Das wäre jetzt schon fertig, wenn du heute Mittag damit begonnen
> hättest.

Tut mir leid, das übersteigt meine Möglichkeiten. 'Für mich' und 
Quick&Dirty wäre vielleicht gegangen (wobei ich da Zweifel habe), aber 
ich vermute, allein bis ich Schreibrechte ins entsprechende Repository 
erlangt hätte, wäre mehr als ein halber Tag vergangen.

Servus

Wolfgang

von Markus F. (mfro)


Lesenswert?

Wolfgang K. schrieb:
> aber
> ich vermute, allein bis ich Schreibrechte ins entsprechende Repository
> erlangt hätte, wäre mehr als ein halber Tag vergangen.

So läuft das auch nicht. OpenSource-Projekte würden ganz schnell ganz 
schön schief liegen, wenn sie "jedem dahergelaufenen" Schreibrechte in 
ihr Repository geben würden. So was muß man sich verdienen.

Jedes Projekt hat einen Maintainer und meist auch eine Mailingliste.

Da schickt man einen Patch hin und wenn der gefällt und sonst auch in 
den Kram paßt, ist die Funktionalität (vielleicht) im nächsten Release 
drin oder auch nicht.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wolfgang K. schrieb:
> Jemand benötigt ein Feature und er baut es nicht für sich, sondern für
> alle nutzbar und sauber ein.

In diese Richtung wird derjenige, der es getan hat, dann vom Maintainer
des Projekts schon noch ein wenig getreten, keine Sorge. :-)  Ich bin
seit mehr als 20 Jahren in der Opensource-Szene aktiv, und viele Jahre
davon auch als eine Art Projektleiter.

Worauf du jedenfalls nicht zu warten brauchst ist, dass irgendjemand
anders anfangen würde, da eine CRC-8 mit reinzubauen.  Du brauchst
sie, jetzt und ganz konkret, nicht irgendjemand.  Damit ist der
Leidensdruck bei dir am höchsten, das auch zu tun.

> Tut mir leid, das übersteigt meine Möglichkeiten.

Selbstüberschätzung ist gewiss nicht gut, aber Selbstunterschätzung
ist es auch nicht.  Guck doch einfach erstmal rein, wie Srecord so
strukturiert ist.  Da sie ja laut deiner Aussage schon mehr als eine
Möglichkeit der CRC-Bildung haben, wird es hoffentlich nur darauf
hinauslaufen, noch eine dritte hinzuzufügen.  Wenn sie das bei den
schon vorhandenen Optionen einigermaßen sinnvoll gestrickt haben, dann
sind das ein oder zwei Bildschirmseiten an Code, den du ergänzen
müsstest (wobei es die Vorlage für CRC-8 ja schon gibt, die musst du
nichtmal neu erfinden), plus ein paar Zeilen in der Doku.  Danach die
Projektseite gesucht, gucken ob sie Patch- oder Bugtracker dort haben,
und einen aufmachen, Patch anhängen.

von Wolfgang K. (opendcc)


Lesenswert?

Hallo Jörg,

ich habe da mal reingesehen. Ganz so leicht ist es nicht.

Also bin ich mal Deinen Vorschlag gefolgt und habe CRC16 implementiert. 
Es geht, ich kann srecord davon überzeugen, mir das zu erzeugen und ich 
kann es innerhalb des AVR auch auf CRC=good abpruefen. Es ist gemütlich, 
braucht etwa 400ms auf einem 16MHz für 128k. Für Power-Up zu lange. Und 
die zitierten 15 Byte Codespace kann ich auch nicht so ganz 
nachvollziehen. CRC8 hätte ich eben als Tabelle im Bootloader vorliegen, 
das hätte schon Vorteile in runtime und zusätzlichen Platzbedarf.

Was mich auch stört, sind die vielen Handeingriffe:

1. Länge dem Bootloader bekannt machen: dazu brauche ich eine fest 
verankerte Konstante im App-Flash. Entweder irgendwo ans Ende (da habe 
ich jeweils eine prozessorindividuelles Linkanweisung, außerdem liegt da 
schon was) oder einem Vorschlag auf AVR-Freaks folgend zwischen .vectors 
und dem Rest von .text. Aber auch das ist ösig: zum Prozessor das 
passende linkerscript suchen (avrmega?.x), dort rumpatchen und als 
lokales Linkerscript ablegen.

2. srecord jeweils diese Adressen bekannt geben: auch wieder recht 
zielabhängig und auch nicht 'single source'.

Vielleicht habe ich da noch nicht alles gut gebaut, das eine oder andere 
kann man ev. mit gawk noch irgendwie automatisch rausfischen. Aber all 
das macht diese Lösung nicht wirklich leicht auf andere Projekte 
portierbar. Ich würde es ja auch als howto publizieren, aber so kann man 
das eigentlich niemand zumuten. Wünschen wurde ich mir da eine 
vordefinierte Section z.B. '.user_const', die gcc definiert nach 
.vectors hinpackt. Und eine Variable, die beim Linken automatisch mit 
der erzeugten Länge des Targets befüllt wird. Und als Zuckerl obendrauf 
noch eine Option -add-obj-crc??. Die Antwort, wie das geht, kenne ich ja 
schon ...

Viele Grüße

Wolfgang

: Bearbeitet durch User
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.