Hallo,
ich scheitere an einem eigenartigem Problem beim Versuch den QUISCI -
Algorithmus auf einem ATtiny zu implementieren. Folgender Codeausschnitt
funktioniert, wenn er mit Visual Studio übersetzt wird einwandfrei,
liefert jedoch falsche Ergebnisse, wenn er auf dem ATtiny ausgeführt
wird.
Das komische daran ist, dass der erste Schleifendurchlauf durchaus das
richtige Ergebniss liefert. Dieses wird dann beim 2. Durchlauf jedoch
wieder überschrieben, obwohl pdata weitergezählt wird?!
Hoffe mir kann jemand helfen.
Ralf
> Folgender Codeausschnitt funktioniert, wenn er mit> Visual Studio übersetzt wird einwandfrei, ...> noch 2 kleine fehler im code: _SN muss SN werden ...
Daraus schließe ich, dass du nicht den Originalcode gepostet hast,
sondern möglicherweise irgend etwas Eingetipptes. Das ist keine gute
Idee, denn nicht selten basieren die Probleme auf kleinen Tippfehlern,
die bei dieser Art der Reproduktion schnell mal verloren gehen.
Bitte poste nochmal genau den Code, der nicht funktioniert, also am
besten per Cut&Paste hier einfügen.
Hallo stefan... das ist der originalcode (fast)
ich habe nur ein wenig rumprobiert und allem eine eigene variable
zugewiesen (also nicht das übergebene SN genommen sondern nocheinmal ein
unsigned char _SN = SN dazugenommen -> hat leider nix gebracht, also
habe ich es wieder entfernt, damit alle die das lesen nicht unnötigen
käse konsumieren müssen.
wenns dich berhigt hier nochmal der originalcode:
Ich kann beim besten Willen diesen Sourcecode nicht mit deiner
Fehlerbeschreibung in Einklang bringen. Denn egal ob der Algorithmus im
allgemeinen richtig implementiert ist, beschreibt er doch auf jeden Fall
pdata[0] bis pdata[3], und nicht pdata[0] zweimal hintereinander.
Als Beispiel mal zwei mögliche Tippfehler, die zu deiner
Fehlerbeschreibung passen würden:
1) Bei den }-Klammern vertippt, so dass das "pdata++;" in den else-Zweig
oder hinter die for-Schleife gerutscht ist.
2) Bei "pdata++;" beim Namen vertippt, so dass versehentlich eine
globale Variable (data?) weitergezählt wird, und nicht pdata.
Das beruhigt mich irgendwie, auch wenn es mir nicht wirklich weiter
hilft.
Habe gestern schon den halben Tag nach dem Fehler gesucht und nix
gefunden...
Der Algorithmus beschreibt ja auch data[0] bis data[3], er ändert jedoch
in jeder schleife die vorher schon geschriebenen werte (so scheint mir
zumindest). Also im 1. Durchlauf wird data[0] geändert, im 2. data[1]
und data[0] usw. :-(
Ich kann leider auch nicht wirklich debuggen - habe keinen JTAGICE mkII
:-(. Werde mir jetzt mal ein Software UART dran bauen und mit in jedem
Durchlauf alle Werte ausgeben lassen. Vielleicht hilfts ja.
Dank dir trotzdem für deine Mühe..
ist denn SHN immer in {0...8} ? Das seh ich net, und dann greifst Du
über SK[] hinweg.
Ausserdem hat SK[] 9 Elemente und irgendwie willst Du mod 8 rechnen
#grübel#
@ oliver: werd ich mal versuchen...
@ georg: SHN ist immer in 0..8, da SHN = SN und SN = irgenwas % 8
das SK 9 elemente hat ist mir noch garni aufgefallen ;-) sollte doch
aber eigentlich nix an der funktionalität ändern, da sowieso immer nur
die ersten 8 verwendet werden.
@stefan: nein ... - werde den google dazu mal befragen ... hab nämlich
keine ahnung wie das geht :-)
Der Missbrauch eines Parameters als lokale Variable mutet schon
etwas seltsam an. Warum dies? Das dürfte selbst in C++ so nicht
legal sein, es sei denn, dein Prototyp initialisiert C mit einem
Default-Wert.
Wie wird eigentlich sichergestellt, dass das übergebene SN nie
größer als 7 bzw. 8 ist? Es dient ja als initialer Index in die
Tabelle.
Einen wirklichen Zusammenhang zum originalen Quisci-Algorithmus
kann ich in deinen Ausführungen nicht finden.
Du weißt, dass es zumindest eine Behauptung in einem Newsartikel
gibt, dass der Algorithmus kryptographisch eher schwach und leicht
kompromittierbar ist?
Hallo Jörg,
ich wollte hier nicht über die sicherheit / unsicherheit des
Algorithmusses spekulieren. Ich habe auch den originalen Algorithmus
seit gestern immer weiter 'zurückgebaut' um dem Fehler näher zu
kommen....
Der Missbrauch des Parameters als lokale Variable funktioniert übrigends
wirklich. Man muss sich nur im klaren darüber sein, dass dieser nach dem
Funktionsaufruf in einer anderen Funktion nicht mehr dem Wert vor dem
Aufruf entspricht.
----
habe die lösunge gerade gefunden, auch wenn ichs nicht verstehe warum es
jetzt geht??!!
aus
gemacht. Und jetzt läufts?! Darauf gekommen bin ich weil mir der AVR
Simulator angezeigt hat das SK[] nur Nullen enthält?! Kann mir das
vielleicht noch jemand erklären?!
Jörg Wunsch wrote:
> Der Missbrauch eines Parameters als lokale Variable mutet schon> etwas seltsam an. Warum dies? Das dürfte selbst in C++ so nicht> legal sein, es sei denn, dein Prototyp initialisiert C mit einem> Default-Wert.
???
Dass Parameter in der Funktion verändert werden, ist doch gang und gäbe
in C.
EDIT:
Und auch in C++ dürfte das uneingeschränkt erlaubt sein.
Ralf wrote:
> Der Missbrauch des Parameters als lokale Variable funktioniert übrigends> wirklich. Man muss sich nur im klaren darüber sein, dass dieser nach dem> Funktionsaufruf in einer anderen Funktion nicht mehr dem Wert vor dem> Aufruf entspricht.
Die Parameter werden als Kopie übergeben, der Originalwert bleibt
unverändert.
> Die Parameter werden als Kopie übergeben, der Originalwert bleibt> unverändert.
gut zu wissen... hätte ich jetzt anders angenommen :-) jaja so ist das
mit dem gefühlten wissen :-)
Ralf wrote:
> ich wollte hier nicht über die sicherheit / unsicherheit des> Algorithmusses spekulieren.
Ich habe mir angesichts dessen nur die Frage gestellt, wofür das
Ganze gut ist.
> habe die lösunge gerade gefunden, auch wenn ichs nicht verstehe warum es> jetzt geht??!!
Ich auch nicht. Der generierte Code sollte in beiden Fällen gleich
sein. Hast du dir den denn mal angeguckt?
Stefan Ernst wrote:
>> Der Missbrauch eines Parameters als lokale Variable mutet schon>> etwas seltsam an.> ???> Dass Parameter in der Funktion verändert werden, ist doch gang und gäbe> in C.
Der Code ist arg verwurschtelt, ich hatte ursprünglich angenommen, der
Parameter würde nur dafür überhaupt benutzt, in der Funktion eine
lokale Variable zu besitzen. Aber er wird ja in der Tat u. U. auch
als Parameter benutzt, das sehe ich jetzt erst so recht.
>Mach mal aus -Os -O2. -Os ist nicht gerade zuverlässig, vor nicht langer>Zeit ließ sich damit nichtmal der Linux Kernel compilieren.
Na ja, der Linux-Kernel lässt sich für einen attiny2313 unter avr-gcc
auch mit -O2 nicht kompilieren:-)
Am -Os liegt es bestimmt nicht.
Oliver
Vor kurzem hatte hier einer auch das Problem, dass -Os falschen Code
produzierte. Schließ es lieber aus, bevor du stundenlang suchst und nix
findest, weil du den Fehler von vornherein ausgeschlossen hast. Ist doch
schnell gemacht.
> meine compileroptionen:>> -Wall -gdwarf-2 -std=gnu99 -mint8 -DF_CPU=16000000UL -Os> -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums> -mtiny-stack
Zumindest beim zweiten Brocken Assemblercode in deinem Beitrag vom
20.05.2008 um 12:25 war -Os nicht angegeben. Was dort gezeigt wird,
ist völlig unoptimiert, aber deswegen nicht unbedingt falsch.
Der Unterschied zwischen beiden Varianten besteht darin, dass für
werden die Daten in die data-Section gepackt und beim Funktionsaufruf
per Schleife in das Array kopiert.
Deswegen sehen beide Varianten unterschiedlich aus, was aber kein
Fehler sein muss.
Ich würde spaßeshalber auch mal die nicht ganz ungefährlichen Optionen
-mint8 und -mtiny-stack weglassen.
avr-gcc.exe -mmcu=attiny85 -Wall -gdwarf-2 -std=gnu99 -mint8
-mtiny-stack -DF_CPU=16000000UL -Os -funsigned-char
-funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT
mmcu fehlte nicht wirklich... steht beim avr studio nur woanders und
deswegen hab ichs vorhin vergessen mit rauszuschreiben ... :-)
-O2 hilft leider nicht
>Vor kurzem hatte hier einer auch das Problem, dass -Os falschen Code>produzierte.
Bei einer vor-2008-avr-gcc-Version? Da hast du doch sicher einen link,
oder?
Bei 2008er gabs mehrere Probleme, aber um den geht es hier ja nicht.
Oliver
Ralf wrote:
>> Zumindest beim zweiten Brocken Assemblercode in deinem Beitrag vom>> 20.05.2008 um 12:25 war -Os nicht>> das stimmt (auch wenn mir rätselhaft ist wie man soetwas an diesem code> erkennen kann) ... hatte für die datei ein -O0 angegeben um> auszuschließen das irgendetwas wegoptimiert wird.
...und hattest die Funktion auf ein Stück Code eingegrenzt, das
außer der Initialisierung des Arrays gar nichts gemacht hat. Die
ganze Funktion wäre vom Optimizer durch einen einfachen RET ersetzt
worden, wenn du die Optimierung aktiviert gehabt hättest. ;-)
Da kein Schwein hier dein Problem nachvollziehen kann, bliebe es
höchstens, dass du das ganze Projekt mitsamt Makefile mal 1:1
zusammenwickelst und uns gibst.
nö bin ich nicht :-) aber bisher reichts ja... und es ändert sich an
meinem problem nix, wenn ich die option weglasse...
kann man hier eigentlich irgendwie die themenüberschrift ändern?!
>kann man hier eigentlich irgendwie die themenüberschrift ändern?!
Das löst dein Problem auch nicht :-)
Wie Jörg schon sagte, zip mal alle Dateien des Projektes zusammen, und
stell die hier rein. Sonst wird das nichts.
Oliver
.init0 ist keine sinnvolle section, in die man seine eigenen
Initialisierungsroutinen schreiben kann. Erstens sind alle
geradzahligen für das System reserviert. Zweitens wird in .init2
erst das _zero_reg_ initialisiert, und aller compiler-generierter
Code geht davon aus, dass dieses Register 0 ist. Damit sollte man
mit eigenen Init-Routinen in der Regel bis .init3 warten.
Schließlich und endlich: .initN-Funktionen müssen immer auch `naked'
sein. Die sollen nämlich nirgendwo hin "return"en. Die Sprache C
benötigt allerdings syntaktisch eine Funktion als kleinste Einheit,
die ausführbaren Code generieren kann, insofern muss man diese
init-Codeschnipsel rein der Syntax wegen in eine Funktion verpacken.
Jörg, vielen dank für diese erklärung... alles was ich bisher dazu
gelesen hatte war
http://www.roboternetz.de/wissen/index.php/Avr-gcc/Interna , wo steht
> .initn Flash Code wird vor main ausgeführt, n = 0...9
also hatte ich einfach mal die 0 genommen....
habe dies jetzt geändert (die init0 funktion rausgenommen) und siehe da,
alles funktioniert fast wie gewünscht - die ausführungszeit der funktion
verlangsamt sich jedoch um etwa 4 µsekunden... ;-)
> Vielleich hilft es, alles zu lesen, etwa den Abschnitt " Frühe> Codeausführung vor main()" darin...
hätte sicherlich geholfen... aber ich hatte an der stelle weiter oben
die benötigte Information (wie ich was vor der main ausführen kann)
gefunden... :-)
@oliver: da wird über den speicherinhalt eine prüfsumme gebildet was
sicherstellen soll, dass die anwendung nur bei korrektem flash
ausgeführt wird. hab das jetzt an den anfang der main verschoben - geht
genauso.