Moin Leute,
ich versuche mich gerade in Fraktale und der Darstellung auf einem
ST7735 Display.
Nachdem ich das Problem mit R-G-B und B-G-R gelöst habe steh ich nun
davor das der Compiler einfach keine Rekursion solcher Art hier mag:
1
voiddrawCircle_rec(intx,inty,floatradius){
2
drawCircle(x,y,radius,WHITE);
3
if(radius>2){
4
radius*=0.75f;
5
6
//The drawCircle() function is calling itself recursively.
7
8
drawCircle_rec(x,y,radius);
9
}
10
}
der Compiler meint dann ganz nett:
ST7735.h:1240: error: (1089) recursive function call to
"_drawCircle_rec"
Der PIC ist ein PIC18F4455 und XC8.
Nehm jede Hilfe an!
Gruß dat
Beast
BeastyK schrieb:> ST7735.h:1240: error: (1089) recursive function call to> "_drawCircle_rec"
Tja, ich kenne den Compiler nicht persönlich, aber ich würde mal sagen,
daß ihn nicht die Tatsache der Rekursion an sich stört (sowas kommt ja
schließlich dauernd vor), sondern vielmehr die Tatsache, daß du da eine
hübsche Endlos-Rekursion gebaut hast.
Und wenn das so offensichtlich ist, daß es sogar der Compiler merkt,
dann mußt du einfach mal die verschissene Logik von diesen lächerlichen
drei Zeilen Code überdenken!!!
Du willst doch nicht dümmer sein als das Programm?
c-hater schrieb:> Tja, ich kenne den Compiler nicht persönlich, aber ich würde mal sagen,> daß ihn nicht die Tatsache der Rekursion an sich stört (sowas kommt ja> schließlich dauernd vor), sondern vielmehr die Tatsache, daß du da eine> hübsche Endlos-Rekursion gebaut hast.
Wie du sehen kannst hört der rekursive Teil auf wenn der Radius < 2
wird!
c-hater schrieb:> Und wenn das so offensichtlich ist, daß es sogar der Compiler merkt,> dann mußt du einfach mal die verschissene Logik von diesen lächerlichen> drei Zeilen Code überdenken!!!
Ja, ähm, genau!
dat
Beast
BeastyK schrieb:> ST7735.h:1240: error: (1089) recursive function call to> "_drawCircle_rec">> Der PIC ist ein PIC18F4455 und XC8.
Falsche Architektur, sage ich mal.
Dieser PIC hat einen 31 Worte großen Hardware-Stack. Der liegt nicht
irgendwo im Adressraum rum, sondern ist irgendwo im Prozessorkern
verbaut. Den kannst Du weder irgendwo anders hinlegen noch vergrößern
oder verkleinern. Kleinere PICs haben sogar nur einen 3 Worte Stack.
Ich denke, dass die Compilerentwickler deswegen Rekursionen komplett
untersagen. Zumindest bei PIC16-Compilern ist das normal. Du musst das
ganze also in einen iterativen Algorithmus umschreiben.
Alternativen:
- C18 Compiler verwenden; der ist ausschließlich für PIC18F gemacht und
nicht wie der XC8 auch für PIC12/PIC16.
- einen 16- oder 32 Bit PIC verwenden. Da ist das kein Problem. Du musst
dafür nur den XC16 bzw XC32 nachinstallieren.
fchk
So, hab mal geschaut und die Compiler Option von
--stack=compiled:auto:auto:auto
Vielleicht hilft das weiter, der XC8 Compiler Guide ist ja ellenlang
...puhh
Greets
Beast
Frank K. schrieb:> - C18 Compiler verwenden; der ist ausschließlich für PIC18F gemacht und> nicht wie der XC8 auch für PIC12/PIC16
Ja, sowas in der Art hab ich bei meiner Suche auch schon gelesen, im
Microchip Forum stand dazu etwas...och menno!
Danke Frank
Wenn ich mich nicht komplett irre, dann hast du da echt eine
Endlos-Rekursion gebaut: das erste was du in deiner Funktion machst ist
die Funktion aufrufen. Zur If-Abfrage kommst du nie. In jeder
aufgerufenen Funktion wird wieder die Funktion aufgerufen. Die Abfrage
muss vor dem Rekursionsaufruf erfolgen, dann klappt das auch (wenn dann
der Stack reicht).
Nils Friess schrieb:> Wenn ich mich nicht komplett irre, dann hast du da echt eine> Endlos-Rekursion gebaut
Doch, du irrst, das eine ist drawCircle_rec und das andere nur
drawCircle!
Der neue Umgang mit dem Stack unter XC8 scheint mir die Probs zu machen,
werd wohl auf C18 umsteigen.
MfG
Beast
der nu inne Heia steigt
>//The drawCircle() function is calling itself recursively.
7
>
8
>drawCircle_rec(x,y,radius);
9
>}
10
>}
11
>
Das ist ein klassischer Fall der Endrekursion, der sich wirklich extrem
leicht in einer normalen Schleife ohne Rekursion umwandeln lässt. Wie
das geht überlasse ich dir.
BeastyK schrieb:> void drawCircle_rec(int x, int y, float radius) {> drawCircle(x, y, radius, WHITE);
Namen, die zu Großteil identisch sind, sollte man vermeiden. Wie man gut
sieht, verwirrt das schnell.
Besser wäre
1
voiddrawDisk_rec()
Um rekursive Funktionen überhaupt verwenden zu können, muß die
Architektur einen echten Stack (Push/Pop) haben und der Compiler muß das
auch unterstützen.
Und z.B. beim 8051 muß man dem Compiler extra sagen, daß eine Funktion
reentrant ist, da damit der Overhead drastisch ansteigt. Er muß dann
alle Variablen auf den Stack legen und kann kein Overlay benutzen.
Manchmal erkennt sogar der Compiler, daß eine Rekursion Unsinn ist und
optimiert selber den Code zu einer Schleife um.