Forum: Mikrocontroller und Digitale Elektronik STM32 gpio-moder zeigt merkwürdiges Verhalten


von jeremy b. (wiebittewas)


Lesenswert?

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

von jeremy b. (wiebittewas)


Lesenswert?

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.

von Jim M. (turboj)


Lesenswert?

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.

von jeremy b. (wiebittewas)


Lesenswert?

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.

von ansel (Gast)


Lesenswert?

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.

von jeremy b. (wiebittewas)


Lesenswert?

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?

von 6A66 (Gast)


Lesenswert?

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

von jeremy b. (wiebittewas)


Lesenswert?

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ß

von jeremy b. (wiebittewas)


Lesenswert?

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.

von Christoph S. (mixer) Benutzerseite


Lesenswert?

> - 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

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Wenn man den CCM RAM aktiviert bevor man den Stack zum ersten mal 
benutzt, so kann man auch diesen RAM als Stack nutzen.

von jeremy b. (wiebittewas)


Lesenswert?

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?

von ansel (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

>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
Noch kein Account? Hier anmelden.