Datum:
Hallo, ich bin auf der Suche nach einem Rechenintensiven Beispielprogramm für den kleinen Atiny2313 in C oder ASM. Am liebsten wäre mir was ohne externe Hardware also keine Display Ansteuerung zum Beispiel. Probiert habe ich selber schon Fibonacci in C, bin mir aber sicher das der Kleine auch noch mehr kann. Gibt es irgendwelche Hash-Wert Implementierungen z.B.? Ich bin sehr gespannt auf eure Anregungen und was Ihr schon so schönes damit gemacht habt. Gruß eac
Datum:
Paul E. schrieb: > ich bin auf der Suche nach einem Rechenintensiven Beispielprogramm für > den kleinen Atiny2313 in C oder ASM. Pi auf 1000 Stellen. Was Sinnvolles soll es ja nicht sein. Oder willst Du nur etwas zum Abschreiben haben?
Datum:
"Ohne externe Hardware" macht m.E. wenig Sinn, dann kannst du das ja gleich am PC machen... Leider hat dein Tiny keinen ADC, sonst wär FFT oder Görtzel ein Paradebeispiel. Wenn's dir nur um's Verbraten von Rechenzeit geht: while(1) i++; Nach Beendigung der Schleife enthält i die "Antwort auf die Frage". Kann nur ein wenig dauern. Wenn's halbwegs sinnvoll sein soll: Versuch eine AES-Implementierung mit V-USB zu verheiraten, mach dir deinen eigenen "Crypto-Coprozessor" ;)
Datum:
Ich wollte eigentlich verschiedene Debugger damit testen und vergleichen und while(1) gibt mir da nicht so viel Aussage. Die Zahl Pi auf 1000 Stellen mit einem 8bit µController geht das? Gruß eac
Datum:
Paul E. schrieb: > Die Zahl Pi auf 1000 Stellen mit einem 8bit µController geht das? Klar. Das Ergebnis ist 3.0 ;)
Datum:
Also mit den Fibonaccizahlen per RS232 ausgeben kannste den kleinen wohl kaum belasten. Ich hab schon die Fibonaccizahlen auf einem Basic Stamp BS1 (in der Schule) sowie auf dem GTR (Casio CFX 9850GC+) programmiert. Selbst für die beiden war das keine große Aufgabe.
Datum:
Paul E. schrieb: > ich bin auf der Suche nach einem Rechenintensiven Beispielprogramm für > den kleinen Atiny2313 in C oder ASM.
int main() { uint64_t i, j; DDRB = 0xFF; for( j = 0; j; j++ ) for( i = 0; i; i++ ) PORTB = i; PORTB = 0xA5; } |
Das ist so rechenintensiv, daß keiner von uns das Ergebnis erleben wird. Man könnte nachrechnen, ob die Erde dann noch existiert. Peter
Datum:
Jo so ungefähr war mein Gedankengang auch. Obwohl ich eine Festkommazahl genommen hätte. Dann wären es immerhin 5 Nachkommabits ;-D Noch andere Vorschläge? Gibt es keine Verfahren mit denen man Daten für die Übertragung per Usart z.B. verschlüsselt? eac 11001000=3.125
Datum:
Paul E. schrieb: > Ich wollte eigentlich verschiedene Debugger damit testen und vergleichen > und while(1) gibt mir da nicht so viel Aussage. Klar. Dann sollest du aber den Debugger richtig fordern, reines Rechnen ist eher ein Test für den Compiler (und der funktioniert...) Also: Interrupts verwenden, Daten hin- und herverschieben, Variablen am Stack etc. Soft-PWM wär dafür z.B. ein schönes Testprogramm... Zum Spaß kannst du ja mal ein "volatile" entfernen, und schauen, ob dir dein Debugger beim Suchen hilft ;) Mein bevorzugter Debugger besteht übrigens aus ner LED und einem Widerstand. Reicht in gefühlt 99% der Fälle.
Datum:
Ich weiß schon das die Herausforderung eines Debbugers eher in der Peripherie besteht also z.B. Usart mit Stimuli. Dazu sollte aber erst mal der innere Kern zu 100% funktionieren. Man könnte sich jetzt einen Testcase aus den Fingern saugen der alle Befehle benutzt, aber ich dachte das ein kleines sinnvolles C-Programm mit irgendwelchen Berechnungen. Siehe Fibonacci. Das ist dann Realitätsnäher und sinnvoll. Gruß eac
Datum:
Timer-IRQs reichen völlig um den Debugger zu fordern, deshalb mein Soft-PWM Vorschlag. Musst ja noch nichtmal die LEDs anschliessen, das läuft auch auf dem nackten Tiny. fib hingegen kann dir höchstens zeigen, wie man mit dem Debugger einen Stack-Überlauf feststellt.
Datum:
Du könntest zum Beispiel Laufzeit-Tests aus GCCs testsuite [1] durchnudeln wie zum Beispiel [2] oder [3] falls die Programme nicht bereits zu groß für einen ATtiny2313 sind. Interrupts finden sich in der Testsuite natürlich nicht. [1] http://gcc.gnu.org/viewcvs/trunk/gcc/testsuite/gcc... [2] http://gcc.gnu.org/viewcvs/trunk/gcc/testsuite/gcc... [3] http://gcc.gnu.org/viewcvs/trunk/gcc/testsuite/gcc...
Datum:
Johann L. schrieb: > Interrupts finden sich in der Testsuite natürlich nicht. Womit diese zum Debugger-Auswählen auch nicht so wirklich taugen. Das ist als wenn man sich ein Fahrrad für eine Alpenüberquerung danach aussucht, ob man damit ohne Platten zum Aldi und zurück kommt. Fehler in den Algorithmen debuggt man am Einfachsten, indem man den Sourcecode einfach am PC übersetzt und dort ausführt. Den Debugger am µC brauchst du eigentlich nur wenn es um µC-Eigenheiten oder Hardware-Interaktion geht, Hardware will der TE möglichst nicht, also sollte er wenigstens ein paar Timer-IRQs in seinem Testprogramm haben. Schließlich will er den Debugger testen, und nicht kontrollieren, ob der GCC auch korrekten Code erzeugt.
Datum:
pFFTh schrieb: > Johann L. schrieb: >> Interrupts finden sich in der Testsuite natürlich nicht. > > Womit diese zum Debugger-Auswählen auch nicht so wirklich taugen. > > Das ist als wenn man sich ein Fahrrad für eine Alpenüberquerung danach > aussucht, ob man damit ohne Platten zum Aldi und zurück kommt. Nicht ganz. Ein Programm besteht ja nicht nur aus ISRs... Für nen Debugger ist ja auch die allgemeine Usability wichtig: • Wie werden rekursive/komplexe Strukturen und Unions dargestellt? • Wie sieht's mit rekursiven Funktionen aus? • Und Werten in drunterliegenden Call-Frames? • Wie werden geinlinte Funktionen dargestellt? • Wie werden expandierte Makros dargestellt? • Werden Funktions-Prologe richtig erkannt? • Auch mit -mcall-prologues? auch mit -maccumulate-args? • Funktioniert Step-Over auch bei geinlinten Funktionen? • Wie sieht's mit Function Clonig aus? • Werden weg-optimierte Variablen angezeigt? • Welche Debug-Formate werden unterstützt? dwarf-2? dwarf-3? dwarf-4? • Kommt der Debugger auch mit den Prologen von avr-gcc 4.7 zurecht? • Wie sieht's mit Plattformunabhängigkeit aus? • Ist der Debigger skriptbar? • Hat er einen integrierten Simulator? • Oder bietet zumindest anbindung an einen Simulator? • Kann man Programme damit nachladen? • Hat er eine Socket-Anbindung? • ... > Fehler in den Algorithmen debuggt man am Einfachsten, indem man den > Sourcecode einfach am PC übersetzt und dort ausführt. Bezüglich der GCC-Testsuite ist jetzt ein Scherz, oder? Die GCC-Testsuite gehört zur Qualitätssicherung des Compilers. Was bringt es für einen avr-gcc, den Code für einen PC zu übersetzen und dort laufen zu lassen?
Datum:
Ok ich seeh schon, Es gibt viel zu beachten. Außerdem scheint der kleine tiny nicht so geeignet zu sein mathematisch anspruchsvolle Dinge zu machen. Der beschränkte Zahlenbereich von 8 bit und der fehlende Hardware Multtplizierer erschweren die Sache ungemein. Gruß eac
Datum:
Paul E. schrieb: > Der beschränkte Zahlenbereich von 8 bit und der fehlende Hardware > Multtplizierer erschweren die Sache ungemein. Wenn du was rechenintensives suchst, kann es dir doch nur recht sein, wenn die Multiplikationen zu fuß gemacht werden mußt.
Datum:
Eben mal angetestet:
#include <math.h> int volatile A, B, C, D; float rezi (float a, float b, float c, float d) { return a/b - c*d + a > b; } int __attribute__((OS_main)) main (void) { return rezi ((long) A / B, B, C, (long) C*D); } |
Das saugt einiges an Code aus den Libs: • Vektortabelle • Startup-Code • 32-Bit integer * und / • float +, -, * und / • float Vergleich • float → int und int → float Konvertierung Das belegt ca. 1800 Bytes, und für "einfache" arithmetische Berechnungen ist man damit gut gerüstet. Die Codegröße wächst nicht mehr sooo viel wenn man das Zeug lediglich verwendet und sich keine weiteren Routinen reinzieht. Man hat also noch ≈250 Bytes für eine Berechnung von π auf 1000 Stellen. Das ist zwar sehr ambitioniert, scheint mir aber durchaus im Rahmen des möglichen; vor allem weil man keine 32-Bit Arithmetik dazu braucht.
Datum:
Johann L. schrieb: > Bezüglich der GCC-Testsuite ist jetzt ein Scherz, oder? > Die GCC-Testsuite gehört zur Qualitätssicherung des Compilers. Eben. Sag ich doch. > Was bringt es für einen avr-gcc, den Code für einen PC zu übersetzen > und dort laufen zu lassen? Für den avr-gcc? Nichts. Garnichts. Aber der TE ist keiner der Entwickler des AVR-GCC und will seinen Debugger auch sicher nicht dafür verwenden, Fehler im AVR-Backend der GCC zu finden. Wenn ich aber Fehler in meinem eigenen Quelltext suche, kann ich durchaus die Zielplattform wechseln, zumindest solang ich davon ausgehe, dass sowohl das i386-Backend als auch das avr-Backend des GCC korrekten Code generieren. Nachdem es hier um einen Debugger für einen Einsteiger/Anfänger geht, würde ich den Focus auf die häufigsten Anfängerfehler legen. Das sind hier im Forumsquerschnitt wohl IRQ-Problemchen, wenn man die ganzen Fehler aussenvorläßt, die der GCC von sich aus schon mit -Wall ankreidet.
Datum:
pFFTh schrieb: > Aber der TE ist keiner der Entwickler des AVR-GCC und will seinen > Debugger auch sicher nicht dafür verwenden, Fehler im AVR-Backend > der GCC zu finden. Oh mann ist das soooo schwer zu verstehen? 1) Der TE fragte nach "Rechenintensiven Beispielprogramm" 2) Ich habe ihm einen Link auf ein Verzeichnis gennannt, das viele ausführbare C-Programme enthält, die out-of-the-Box funktionieren. Nicht mehr und nicht weniger. Die Programme machen keine Voraussetzungen wie "dieses LCD muss hier und so angeschlossen werden" oder "das geht aber nur mit ATmega weil Assembler" oder "dafür sind's zu wenig Ports" etc. Wo die Programme stehen und zu welchem Projekt die gehören ist doch sowas von Wurscht, also überlies diese Meta-Info einfach. Daß die Programme keinen ISR-Code enthalten schrieb ich bereits. Der TO wird die Information für sich auszuwerten wissen — irgendwas von "das stört überhaupt nicht" bis hin zu "damit ist das uninteressant fü meine Zwecke".
Datum:
Johann L. schrieb: > Eben mal angetestet: > >
#include <math.h> > > int volatile A, B, C, D; > > float rezi (float a, float b, float c, float d) > { > return a/b - c*d + a > b; > } > > int __attribute__((OS_main)) > main (void) > { > return rezi ((long) A / B, B, C, (long) C*D); > } |
Nicht schlecht, danke! Mit der math.h rechnet er meine Fibonacci Folge auch gleich mal viel länger:
0000000 0000001 0000001 0000002 0000003 0000005 0000008 000000D 0000015 0000022 0000037 0000059 0000090 00000E9 0000179 0000262 00003DB 000063D 0000A18 0001055 0001A6D 0002AC2 000452F 0006FF1 000B520 0012511 001DA31 002FF42 004D973 007D8B5 00CB228 0148ADD 0213D05 035C7E2 05704E7 08CCCC9 0E3D1B0 1709E79 2547029 ... |
Hier der auch noch der Quellcode zur Vollständigkeit:
/* * AVRGCC1.c * * Created: 10.02.2012 14:10:37 * Author: Paul E. */ #include <avr/io.h> #include <math.h> int volatile long a,b,sum; int main () { DDRB=255; PORTB=a; int n; n=50; fibonacci(n); return 0; } int fibonacci(int n) { a = 0; b = 1; sum; int i; for (i=0;i<n;i++) { //PORTB=a; sum = a + b; a = b; b = sum; } return 0; } |
Datum:
ohne externe Beschaltung verhält sich jedes Programm genauso wie ein
while(1) {}
Datum:
Paul E. schrieb: > Mit der math.h rechnet er meine Fibonacci Folge auch gleich mal > viel länger Hmmm. Dein Code verwendet die math.h überhaupt nicht. Mein Schnipsel übrigens auch nicht — my bad. Ich hatte vorher was mit pow() versucht, aber das ELF wurde schon viel zu groß für einen ATtiny2313. Daher hab ich pow() wieder entfernt und das math.h aber drinne gelassen. Eine aufwändige Berechnung von Fibonacci geht über deren explizite Darstellung, die auch verwendet werden kann, um die "rekursiven" Ergebnisse zu testen:

mit dem Goldenen Schnitt

Der zweite Summand in fib(n) get rasch gegen 0 und es ergibt sich

Das führt zu folgendem kleinen C-Programm:
#include <math.h> #include <stdio.h> float phi; static unsigned long fib (int n) { return round (pow (phi, n) / sqrt (5)); } int main (void) { int i; phi = (sqrt (5) + 1) / 2; for (i = 0; i < 15; i++) { printf ("f[%d] = %lu\n", i, fib (i)); } return 0; } |
Die Wurzel-Konstanten werden übrigens bereits vom Compiler ausgewertet. Auf einem ATmega88 ausgeführt (und mit etwas Magie in anderen Modulen, um printf transparent funktionsfähig zu machen) erhält man folgende Ausgabe:
f[0] = 0 f[1] = 1 f[2] = 1 f[3] = 2 f[4] = 3 f[5] = 5 f[6] = 8 f[7] = 13 f[8] = 21 f[9] = 34 f[10] = 55 f[11] = 89 f[12] = 144 f[13] = 233 f[14] = 377 |
Wie gesagt ist pow() berweits zu groß für einen tiny2313; das obige Programm verschlingt ca 4500 Bytes. pow() brauch man hier aber nicht unbedingt, denn die Exponenten sind ganzzahlig. Man könnte das x^n also auch händlisch implementieren und braucht dann nur Multiplikation anstatt pow().