Guten Tag,
Betreff sagt eigentlich schon fast alles.
Alles funtkioniert super, nur wenn ich in der main code einfüge hinter
das printf, dann wird mir die SPeicherposition 0x100000f8
kaputgeschrieben.
Dabei spielt es keine rolle welcher Wert dort steht.
Aufmerksam auf den Kern des Problems wurde ich erst als mir auffiel,
dass die private member variable des Nunchuk nur einmal auf den I2C
zugreifen kann bevor ihre Address Daten zerstört werde. Bzw, ist nicht
ganz richtig. sie konnte nur einmal lesend zugreifen.
während System::init wird ein anderer I2C Sensor am selben Port mit der
gleichen I2C klasse ausgelesen, alles funktioniert.
Bin das ganze jetzt schon zig mal durchgegangen, im Endeffekt kommt der
Fehlzugriff während dem Intterrupt ansprung, also nicht davor oder
danach, sondern während und auch nur wenn meine main "zu lang" ist.
ziemlich weit unten sieht man wie der IRQ verschatelt ist.
Ich weiss nicht mehr was ich machen soll ~_+ Hilfe
Ich vermute der Hund liegt irgendwo im stack vergraben, und das die
Registersicherung nicht ganz einheitlich abläuft. Aber wieso das Problem
erst bei längerer main auftritt, da bin ich einfach überfragt.
ich habe mal mit __attribute__((interrupt)) vor der C++ routine
probiert, aber da ging dann gar nichts mehr.
Bin für jeden Tip dankbar, wenn mehr code gebraucht wird oder ich
irgendwas ausprobieren soll, nur zu.
MfG
Johannes
Johannes V. schrieb:> nur wenn meine main "zu lang" ist.
Das ist bestimmt nicht die Ursache, die liegt woanders.
_attribute_ ((interrupt)) gehört ggfs. an die Funktion
I2C1_IRQHandler, aber auch da bin ich beim Cortex-M3 nicht ganz sicher.
Was anderes: Es kann sein, dass du für printf("%f") eine erweiterte
Runtime-Lib dazulinken musst, hast du das gemacht? Ansonsten ersetz mal
float acc[3] durch int acc[3] und printf("%f") durch printf("%d").
willibald schrieb:> _attribute_ ((interrupt)) gehört ggfs. an die Funktion> I2C1_IRQHandler, aber auch da bin ich beim Cortex-M3 nicht ganz sicher.
CM3 Interrupt Handler benötigen keinen speziellen Stackframe, sondern
werden wie normale C Funktionen aufgerufen. Irgendwelche Attribute sind
also nicht erforderlich.
Hallo,
ich habe zwischenzeitlich den Interrupt jetzt einfach mit in die send()
eingebaut, da sie vorher ja auch nicht verlassen wurde während den
wartezeiten.
Aber das ist ansich ja auf Dauer auch keine Lösung. Zum einen weil dann
andere Intterrupts unter umständen meine SCL zu weit strecken (bleibt
low sobald I2C irq flag steht) und zum anderen weil ich mir sicher bin,
dass ich Interrupts noch brauchen werde sobald ich die RF12Bs zum laufen
kriege.
_attribute_((irq)) habe ich auch probiert, aber das hat dann auch den
aufruf komplett zu nichte gemacht und der controller geht in eine
dauerschleife.
Also nochmal kurz und knapp, der Fehler kommt Zustande während dem
Übergang vom C IRQ Handler der nichts anderes macht als den C++ IRQ
Handler zu callen.
Dabei können auch andere I2C transfers vorher stattfinden ohne das der
Speicher, oder zumindes was ich davon sehe, überrschrieben wird.
Zu Printf: in der tat muss man floatingpoint erst freischalten. habe ich
auch gemacht und mittlerweile gibt er mir die messwerte auch
entsprechend aus.
Das es nicht an einer zu großem main liegt ist mir auch klar, nur im
ersten Atemzug ist das der zu beobachtende grund. Es muss irgendwas mit
dem Übergang zwischen C und C++ zu tun haben. Ich gehe mittlerweile
davon aus das ein weiterer Interrupt den ich in ähnlichem still betreibe
auch irgendwo den Speicher überrschreibt, nur merkt man es nicht.
Wäre es denkbar die C++ IRQ Handler direkt in die Vectortabelle zu
schreiben wenn innerhalb eh nur mit statischen variablen gearbeitet wird
oder fehlt mir dann der this pointer?
Tut mir leid wenn das jetzt teilweise dumme fragen sind, aber ich habe
auch erst vor 3 monaten angefangen mich intensiv mit programmieren zu
beschäftigen.
Johannes V. schrieb:> Aufmerksam auf den Kern des Problems wurde ich erst als mir auffiel,> dass die private member variable des Nunchuk nur einmal auf den I2C> zugreifen kann bevor ihre Address Daten zerstört werde.
Ich kenne mich mit C++ nicht aus, aber unter C ist das klassisch ein
Pointer, der in den Wald zeigt oder ein zu großes Displacement auf den
Pointer.
So bequem Pointer auch sind, manchmal sollte man lieber einen Index
nehmen. Ein Index läßt sich nämlich immer auf Gültigkeit prüfen, ein
Pointer aber nicht.
Innerhalb einer Funktion kann man den Pointer überblicken. Aber
funktionsübergreifend nehme ich lieber einen Index und jede Funktion
prüft ihn bei Übergabe auf Gültigkeit.
Auch würde ich nicht gleich alle 3 I2C-Ports zusammen mengen, sondern
erstmal nur ein I2C zum Laufen bringen.
Danach sollte man das doch einfach mit Vererbung auf 3 erweitern können.
Ständige Auswahlentscheidungen mit switch/case sind dann unnötig.
Johannes V. schrieb:> Tut mir leid wenn das jetzt teilweise dumme fragen sind, aber ich habe> auch erst vor 3 monaten angefangen mich intensiv mit programmieren zu> beschäftigen.
Und dann gleich mit so einem Boliden anfangen, Hut ab.
Ich würde mir das nicht zutrauen.
Peter
Dürfte eigentlich nicht das Problem sein, 16kb hat er, und laut Rowleys
verbrauche ich ca 500 byte.
Es läuft ja auch noch kein richtiges Programm, bin noch mit Treiber
Entwicklung beschäftigt.
Einen exessiven Aufruf der mir den stack während der Laufzeit abschmatzt
schließe ich auch aus, habe bis jetzt nicht einen rekursiven Aufruf und
die tiefste Ebene müsste bei 3 liegen.
Guten Tag,
das Problem saß natürlich vor dem Bildschirm.
Rowleys Crossworks bieted eine Schöne Ansicht des verwendeten Speichers
mit farbigen Balken. Ich dachte es wäre eine Art "Real-Time" Anzeige.
Aber weit gefehlt, es zeigt nur an wie viel Stack und Heap der Linker
zuteilt.
Und da waren dann wohl 128 byte doch zu knapp ~_^
Ich habe es noch nicht getested, nur gerade erfahren wie man das
einstellen kann das er mehr Speicher reserviert.
Aber dazu eine andere Frage. Ich würde gerne eine ISR im Ram ablegen.
Dazu eine neue Sektion im Linker eintragen und mit
__attribute__((section"whatever")) die Funktion bereitstellen. Wird nach
POR der code automatisch in den RAM copiert? Oder muss ich dann noch das
startupscript manipulieren? Gibt es schon eine section die ich einfach
mit nutzen könnte (fast_run z.b.)
MfG
Johannes