ich habe ein Problem mit einem STM32F417, den ich per openocd über jtag ansprechen kann. derzeit ist keinerlei System vorhanden. für einen ersten test wollte ich über openocd einen GPIO-Pin programmieren. soweit ich die Dokumentation verstanden habe, finden sich die zugehörigen Register ab 0x40200000. ModeR von GPIOA wird nach einem reset mit a8000000, GPIOB mit 00000280 initialisiert, die anderen mit 0. greife ich jetzt mit mdw 0x40200000 auf GPIOA-ModeR, 0x40200400 auf GPIOB-ModeR oder 0x40200800 auf GPIOC-ModeR zu, sehe ich auch die entsprechenden Werte. versuche ich z.B. ModeR-GPIOC-14 mittels mww 0x40200800 0x10000000 als Output zu konfigurieren, nimmt das Teil das nicht an. mdw zeigt weiterhin 0 als Inhalt. merkwürdig ist, daß wenn ich mittels mdw 0x40200[04]00 0x100 den ganzen Config-Bereich von GPIO[AB] anzeige, dann scheint in allen Registern der reset-Wert zu stehen, was mir merkwürdig vorkommt. andere Zugriffe, z.B. auf das SRAM oder das Flash funktionieren hingegen einwandfrei. wenn ich auf einem STM32F4-discovery-Board ein Reset durchführe, dann funktionieren dort zum einen die Register-Modifikationen, zum anderen kann ich auch gezielt GPIOs über diese in oben beschriebener Weise setzen. ich habe mit dem Problem-Board schon alles mögliche angestellt, aber bin zu keinem Ergebnis gekommen. wo kann der Fehler liegen? Für jedwede Tips wäre ich sehr dankbar. gruß wiebittewas
ok, das Problem scheint ein generelles zu sein.
habe mal direkt code generiert, der auch erfolgreich ausgeführt werden
kann, soweit es das Füllen von Registern angeht.
offensichtlich läßt sich der gesamte Peripherie-Bereich (zumindest ab
>0x40020000 -- das 0x40200000 im Ursprungstext war falsch im Text) nicht
beschreiben.
leider habe ich noch immer keine Ahnung, warum.
Die Beispiele für STM32Fxxx, die ich hier immer mal sehe schalten immer zuerst irgendwelche Clocks ein. Schau mal ins Handbuch, welche Clocks für GPIO konfiguriert sein müssen.
naja, die clocks werden ja eigtl. erst benötigt, damit die Daten zwischen registern und den Pins zu transferieren. ich scheitere aber ja aktuell schon daran, über das ModeR-Register die Art des GPIO (In/Out/...) zu definieren (was ja vor einer Benutzung des ganzen notwendig bzw. auch sinnvoll ist), aber auch z.B. die RCC-Register zu setzen, die ja für die Clocks zuständig sind. es scheint halt so, als wäre jeglicher Schreibvorgang auf diesen Bereich unwirksam... der Test auf dem Discovery-Board hatte ja zumindest auch gezeigt, daß ich bzgl. der Vorgehensweise nicht völlig daneben liegen. momentan habe ich noch den Verdacht, daß es zumindest teilweise auch an dem einfachen FTDI-JTAG-Adapter liegen könnte (bzw. wie openocd darauf zugreift), da der funktionierende Zugriff auf das Discovery-Board ja über einen eigenen Link läuft.
jeremy b. schrieb: > naja, die clocks werden ja eigtl. erst benötigt, damit die Daten > zwischen registern und den Pins zu transferieren. Quelle? ARM scheint den Peripheriebauern keine Vorgaben zu machen, und die einzige Aussage von STM dazu scheint folgendes zu sein: ,----[ STM32F417xx Reference manual ] | After each device reset, all peripheral clocks are disabled (except for | the SRAM and Flash memory interface). Before using a peripheral you have | to enable its clock in the RCC_AHBxENR or RCC_APBxENR register. `---- > es scheint halt so, als wäre jeglicher Schreibvorgang auf diesen Bereich > unwirksam... Ein Symptom eines Registers, dem der Takt fehlt... > der Test auf dem Discovery-Board hatte ja zumindest auch gezeigt, daß > ich bzgl. der Vorgehensweise nicht völlig daneben liegen. Sicher, dass der µC wirklich jungfräulich war? Vielleicht wurde ja doch unverhofft was aus dem Flash ausgeführt, bevor der Debugger die kontrolle übernahm... Ein Blick in die peripheral clock Register sollte das bestätigen/ausschliessen können.
ansel schrieb: > jeremy b. schrieb: >> naja, die clocks werden ja eigtl. erst benötigt, damit die Daten >> zwischen registern und den Pins zu transferieren. > > Quelle? ARM scheint den Peripheriebauern keine Vorgaben zu machen, und Quelle ist einfache, elementare Logik, denn wenn ich auf die Register nicht zugreifen kann, dann kann ich auch keine Clocks konfigurieren. oder täusche ich mich da? > die einzige Aussage von STM dazu scheint folgendes zu sein: > > ,----[ STM32F417xx Reference manual ] > | After each device reset, all peripheral clocks are disabled (except for > | the SRAM and Flash memory interface). Before using a peripheral you have > | to enable its clock in the RCC_AHBxENR or RCC_APBxENR register. wofür ich aber eben auf das Register schreibend zugreifen können müßte, es aber nicht kann. laut ref-man sollte das entsprechende Register bei 0x40021030 zu finden sein, für GPIOC ist das Bit2 zuständig -- wird da unter 5.3.10 geschrieben. versuche ich darauf zu schreiben, passiert nix. >> der Test auf dem Discovery-Board hatte ja zumindest auch gezeigt, daß >> ich bzgl. der Vorgehensweise nicht völlig daneben liegen. > > Sicher, dass der µC wirklich jungfräulich war? Vielleicht wurde ja doch > unverhofft was aus dem Flash ausgeführt, bevor der Debugger die > kontrolle übernahm... Ein Blick in die peripheral clock Register sollte > das bestätigen/ausschliessen können. nein, zunächst war er vor obigen Tests nicht jungfräulich, da ich versuchte, einen Bootloader, von dem ich annahm, er würde funktionieren, ins Flash schob. Als sich dann zeigte, daß er es nicht tat, versuchte ich, mal etwas kleinschrittiger an die Sache ranzugehen, und ein flash erase zeigte offensichtlich hinreichend Wirkung. Inzwischen habe ich aber auch entsprechenden Minimal-Code wieder eingebaut, der - wenn der Debugger nicht rechtzeitig dazwischen funkt - sich selbst samt der VectorTable ins SRAM kopiert und dann endlos dreht. Ein Blick ins SRAM zeigt dann auch den Erfolg der Maßnahme, wenn der Code mal laufen gelassen wurde. interessanterweise habe ich dann gestern nach einer unendlichen Reihe von Tests und Resets das Teil in einem Zustand gehabt, das mich dann erfolgreich auch den besagten GPIO setzen ließ, nach einem poweroff war's dann aber auch schon vorbei. und nun habe ich noch mehr Fragezeichen auf der Stirn, denn sowas nicht-deterministisches könnte ich mir nur erklären, wenn es ein Zugriff nach außen wäre und es da 'ne kalte Lötstelle o.ä. gäbe, was wohl bei einem internen Register ausgeschlossen werden kann. oder wäre es denkbar, daß das Teil aufgrund äußerer Einflüsse (Löten, Überspannungen, etc.) einen derart begrenzten Defekt ausbildet?
jeremy b. schrieb: >> jeremy b. schrieb: >>> naja, die clocks werden ja eigtl. erst benötigt, damit die Daten >>> zwischen registern und den Pins zu transferieren. >> >> Quelle? ARM scheint den Peripheriebauern keine Vorgaben zu machen, und > > Quelle ist einfache, elementare Logik, denn wenn ich auf die Register > nicht zugreifen kann, dann kann ich auch keine Clocks konfigurieren. > oder täusche ich mich da? Hallo jeremy, bei den Prozessoren der Cortex-Reihe (also auch die STM32) gibt es elementare Reihenfolgen: a) Takterzeugung einstellen b) Peripherietakte einstellen ... Ohne einen Takt an den entsprechenden Peripheriebausteinen geht dort gar Nichts - zumindest nicht zuverlässig. Punkt. Keine Diskussion über könnte würde hätte. > ,----[ STM32F417xx Reference manual ] > | After each device reset, all peripheral clocks are disabled (except for > | the SRAM and Flash memory interface). Before using a peripheral you have > | to enable its clock in the RCC_AHBxENR or RCC_APBxENR register. Das ist das was ich oben gesagt habe. Bitte beachte dass auch einige der Register einen Schreibschutz haben können. Dies dient dazu dass ein Programm das sich verlaufen hat nicht einfach die Chipkonfiguration ändern kann. Ohne einen aufgehobenen Schreibschutz keine Änderung. >und nun habe ich noch mehr Fragezeichen auf der Stirn, denn sowas >nicht-deterministisches könnte ich mir nur erklären Bei Prozessoren (auch beim STM32) ist normalerweise ALLES deterministisch - auch errata :) Wenn daher etwas mal geht und mal nicht kann das an irgendwelchen fehlenden Initialisierungen liegen (Reset Values der Register???). Auch dieses Verhalten ist dann ja deterministisch - Man überlässt den Wert entschieden dem Zufall :) rgds
6A66 schrieb: >> ,----[ STM32F417xx Reference manual ] >> | After each device reset, all peripheral clocks are disabled (except for >> | the SRAM and Flash memory interface). Before using a peripheral you have >> | to enable its clock in the RCC_AHBxENR or RCC_APBxENR register. > > Das ist das was ich oben gesagt habe. nun hast Du aber leider den von mir hinzugefügten, elementaren Satz wohl überlesen: versuche ich darauf zu schreiben, passiert nix. > Bitte beachte dass auch einige der Register einen Schreibschutz haben > können. Dies dient dazu dass ein Programm das sich verlaufen hat nicht > einfach die Chipkonfiguration ändern kann. > Ohne einen aufgehobenen Schreibschutz keine Änderung. sicher, nachvollziehbar. so habe ich durchaus gesehen, daß es entsprechende Lock-Register für GPIO gibt, aber nichts dergleichen für RCC und wenn ich RCC nicht konfigurieren kann, kann ich keinen Takt einstellen. ich frage ja auch genau deswegen hier nach: was übersehe ich? > deterministisch - auch errata :) Wenn daher etwas mal geht und mal nicht > kann das an irgendwelchen fehlenden Initialisierungen liegen (Reset genau, nur habe ich jetzt schon einige Tage lang ref-man, prog-man, Beispiel-Code etc. durchforstet, bin aber parout nicht fündig geworden, was ich tun muß, um eben z.B. auf RCC schreiben zu dürfen. und genau deswegen frage ich hier nach: welche Information übersehe ich, oder was mache ich falsch? Fakt ist, die Kiste läuft nach einem Reset über den internen Takt, zieht sich den SP aus der Adresse 0 und den PC aus Adresse 4. Je nach Boot0/Boot1-Pins ist da entweder Flash, SRAM, oder System-Mem hingemapped. Wenn beide Boot auf 0 liegen ist es der FlashCode, den ich da reingebraten habe und der wohl auch ausgeführt wird, zumindest wenn ich später mit dem JTAG schaue, hat das SRAM die gewünschte Kopie des Codes und er dreht in der Endlosschleife. Testhalber habe ich in den Code auch eine Initialisierung des RCC reingebaut, die aber offensichtlich nichts bewirkt. Im Kapitel 5.3 des ref-man (RCC-Beschreibung) findet sich auch nichts darüber, daß zuvor in irgendeinem Register ein Unlock gemacht werden muß. Darum die Frage: was übersehe ich/mache ich falsch? und sorry, es hilft mir leider wenig, gesagt zu bekommen, ich soll den Takt einschalten, wenn ich doch eben genau darlege, daß mir dies nicht gelingt und ich nicht weiß, warum.... gruß
so, jetzt zeigt das Gerät tatsächlich so einigermaßen das erwartete Verhalten. das Problem war wohl, daß das define für das RCC-Register falsch war. Irgendwann da reingepackt und nicht mehr hinterfragt :( warum danach dann gar nichts mehr ging, erschließt sich mir zwar nicht endgültig, da an der Stelle eigtl. nix ist, aber wie das dann intern verarbeitet wird ist wahrscheinlich schlicht nicht definiert. falls da also nochmal jmd von Scratch vorgehen will (gilt zumindest für STM32F4xx): - Adresse 0 im Flash beinhaltet den StackPointer (sollte irgendwo oberhalb 0x20000000 zeigen) - Adresse 4 im Flash ist der ProgramCounter, da das Gerät nur Thumb-Code kann, muß da bit0 gesetzt sein - dahinter folgen die restlichen Interrupt-Vektoren - so ab 0x400 kann dann eigener Code stehen - nach 'nem PowerOn läuft das gerät mit internem Takt, aber wer sicher gehen will kann sich den Wert aus dem RCC (0x40023800) holen und bit0 setzen - dann noch das GPIO-Takt-Enable für den gewünschten Bereich setzen (findet sich in RCC_AHB1ENR (0x40023830) - danach können die mit Takt versehenen GPIOs entsprechend konfiguriert und gesetzt/gelesen werden freizuschalten ist da nix mehr sonst, höchsten die GPIO-Config bis zum nächsten Reset zu blocken, aber diese Minimallösung ist ja wohl eher was für's erste Kennenlernen des Chips tatsächlich hat/haben der/die andere(n) hier aber mit der Aussage recht, daß ein gpio-Register, dessen Takt nicht freigegeben ist, den Wert nicht verändern läßt.
> - Adresse 0 im Flash beinhaltet den StackPointer (sollte irgendwo > oberhalb 0x20000000 zeigen) Am Besten ist es natuerlich den Stackpointer gleich am Anfang auf das Ende des RAMs zu setzen, so wie es sein sollte. Das Ende errechnet sich aus dem Start (0x20000000) plus der RAM-Groesse des Controllers. Gruss
Wenn man den CCM RAM aktiviert bevor man den Stack zum ersten mal benutzt, so kann man auch diesen RAM als Stack nutzen.
Markus Müller schrieb: > Wenn man den CCM RAM aktiviert bevor man den Stack zum ersten mal > benutzt, so kann man auch diesen RAM als Stack nutzen. ich nehme an, daß es sich dabei um die zu den laut Spezifinkation vorhandenen 192kB RAM im Bereich ab 0x20000000 fehlenden 64kB handelt? leider habe ich hierzu nichts im ref-man gefunden. verrätst Du daher bitte, wie das aktiviert wird und wo es liegt?
jeremy b. schrieb: > ich nehme an, daß es sich dabei um die zu den laut Spezifinkation > vorhandenen 192kB RAM im Bereich ab 0x20000000 fehlenden 64kB handelt? Genau. > leider habe ich hierzu nichts im ref-man gefunden. > verrätst Du daher bitte, wie das aktiviert wird und wo es liegt? Hmm, scheint im Datenblatt versteckt zu sein (Anhang)... Register zum aktivieren findet man, wenn man in der Referenz nach CCM sucht. Hab' in meinen bisherigen stm32f4-Basteleien auch den Stack standardmässig ab 0x10010000. Interessant ist der Vergleich zum stm32f3 - Dort hängt das CCM am I-Bus statt am D-Bus, und taugt nicht als Stack.
>verrätst Du daher bitte, wie das aktiviert wird
Clock einschalten.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.