Forum: Mikrocontroller und Digitale Elektronik Werte ins Flash schreiben beim STM32F030F4


von Claus (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Leute,

mittlerweile versuche ich seit zwei Tagen Werte im Flash abzuspeichern, 
allerdings ohne Erfolg. Jedes mal, wenn ich mit einem Pointer versuche 
auf den Flash zuzugreifen, lande ich direkt im Hard Fault Handler. Hat 
einer eine Idee, woran es liegen könnte?

Was ich verwende:

- Keil µVision in der Version V5.14.00.0 (Lite-Version)
- ULINK2 Debugger

Was ich gemacht habe:

- Einstellung des letzten pages als IROM2 (siehe Bild)
- Code wie beigefügt, direkt im main.c

Code:
1
  
2
 while ((FLASH->SR & FLASH_SR_BSY) != 0){ __NOP();}                // unlock Flash
3
  
4
    if ((FLASH->CR & FLASH_CR_LOCK) != 0){
5
      FLASH->KEYR = FLASH_FKEY1;
6
      FLASH->KEYR = FLASH_FKEY2;
7
    }
8
  
9
    
10
    FLASH->CR |= FLASH_CR_PER;                                    // erase page
11
    FLASH->AR = 0x8003C00;
12
    FLASH->CR |= FLASH_CR_STRT; 
13
    
14
    while ((FLASH->SR & FLASH_SR_BSY) != 0){__NOP();} 
15
16
    if ((FLASH->SR & FLASH_SR_EOP) != 0){FLASH->SR |= FLASH_SR_EOP;}
17
    else{__NOP();}
18
    FLASH->CR &= ~FLASH_CR_PER;
19
    
20
    
21
    while ((FLASH->SR & FLASH_SR_BSY) != 0){ __NOP();}              // write to flash
22
   
23
    FLASH->CR |= FLASH_CR_PG;
24
25
    (volatile unsigned short*)(0x08003C00) = 0x1234;    // ERROR (Hard Fault Handler)
26
      
27
    while(FLASH->SR & FLASH_SR_BSY){__NOP();}
28
  
29
    if ((FLASH->SR & FLASH_SR_EOP) != 0){FLASH->SR |= FLASH_SR_EOP;}
30
    else{ __NOP();}
31
32
    FLASH->CR &= ~FLASH_CR_PG;
33
    
34
    FLASH->CR    |=  FLASH_CR_LOCK;                       // Lock Flash

von Claus (Gast)


Lesenswert?

Keiner eine Idee?

von Steffen R. (steffen_rose)


Lesenswert?

Claus schrieb:
> (volatile unsigned short*)(0x08003C00) = 0x1234;    // ERROR (Hard Fault
> Handler)

Dereferenzierung vergessen

*(volatile unsigned short*)(0x08003C00) = 0x1234;

von Chris F. (chris_de)


Lesenswert?

Mach dir doch ne section im makefile, dann ist es im Code sofort 
ersichtlich um welche Page es sich handelt :)

von Claus (Gast)


Lesenswert?

Steffen Rose schrieb:
> Dereferenzierung vergessen

Mein Fehler, habe ich korrigiert. Erzeugt leider immer noch den Hard 
Fault

Chris F. schrieb:
> Mach dir doch ne section im makefile, dann ist es im Code sofort
> ersichtlich um welche Page es sich handelt :)

Habe ich gemacht als Scatter-File (heißt so bei MDK). Wird korrekt 
ausgeführt aber es hilft leider auch nichts.

von Bernd K. (prof7bit)


Lesenswert?

Claus schrieb:
> *(volatile unsigned short*)(0x08003C00) = 0x1234;

Bist Du sichger daß man da einfach so ins Flash schreiben kann als wärs 
RAM? Ich kann das nicht recht glauben!

Ich kenns jetzt zwar nicht explizit vom STM32 sondern von nem Kinetis 
und dort ist es so daß ich in einem speziellen Peripheriegerät (dem 
Flash controller) ein paar Register setzen muss (die zu schreibende 
Adresse und das zu schreibende Wort), dann dort ein spezielles Kommando 
auslösen (es gibt da mehrere Kommandos, z.B. Sektor löschen, Sektor auf 
0xff überprüfen, ein longword schreiben, etc.), dann warten bis das 
Gerät Vollzug meldet und dann sind die 4 Bytes geschrieben.

Ich nehme an beim STM32 wirds ähnlich sein: Flash ist für den Prozessor 
read-only, löschen und neu Schreiben kann nur der Flash-Controller.

: Bearbeitet durch User
von Jim M. (turboj)


Lesenswert?

Claus schrieb:
> (volatile unsigned short*)(0x08003C00) = 0x1234;

Ein 16-Bit Transfer ins Flash? Schau mal ins Handbuch, der Flash ist oft 
nur für 32 Bit Zugriffe beim Schreiben ausgelegt.

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Jim Meba schrieb:
> Ein 16-Bit Transfer ins Flash? … Der Flash ist oft
> nur für 32 Bit Zugriffe beim Schreiben ausgelegt.

Geht beides:
1
FLASH_ProgramWord     (uint32_t Address, uint32_t Data);
2
FLASH_ProgramHalfWord (uint32_t Address, uint16_t Data);

Bernd K. schrieb:
> Ich kann das nicht recht glauben!

Ich auch nicht:
http://www.han-ese.nl/STM32/stm32f0stdlibrary/html/group___f_l_a_s_h.html

@Claus: Kommst Du damit dann allein klar?

: Bearbeitet durch User
von Claus (Gast)


Lesenswert?

Hallo!

Danke Euch für Eure hilfreichen Antworten, so langsam beginnt der 
STM32F0 das zu tun was er sollte :-)

Bernd K. schrieb:
> Bist Du sichger daß man da einfach so ins Flash schreiben kann als wärs
> RAM? Ich kann das nicht recht glauben!

Müsste laut den Beispielen von Keil und ST eigentlich genau so gehen. 
Flash unlock, page erase, check if page erased, set PG-bit, 
Schreibzugriff wie oben.

Jim Meba schrieb:
> Ein 16-Bit Transfer ins Flash?

Sollte theoretisch passen. Zumindest steht es auch so in der 
StDPeriph_Lib:

*(__IO uint16_t*)Address = (uint16_t)Data;

Interessanterweise besteht auch die Funktion FLASH_ProgramWord (uint32_t 
Address, uint32_t Data) intern aus der zweifachen Aufruf der obigen 
Zeile. Einen Beispiel für einen direkten 32-bit Zugriff auf den Flash 
habe ich nicht gefunden.

Bin noch etwas am Spielen mit dem Code, sobald es vorzeigbar ist lade 
ich es hoch!

von Steffen R. (steffen_rose)


Lesenswert?

Das prinzipielle Vorgehen ist korrekt. Man redet ja nicht direkt mit dem 
Flash, sondern mit dem Flash-Interface (controller).
1
 FLASH->CR |= FLASH_CR_PG;
2
3
    *(volatile unsigned short*)(0x08003C00) = 0x1234;    // ERROR (Hard Fault Handler)

- Write PG bit in FLASH_CR to 1
- Perform half-word write at the desired address
- loop, while BSY bit in FLASH_SR = 1

Hast Du für alle Traps einen eigenen Einsprung?
Hat die UNLOCK Prozedur geklappt? (LOCK bit in FLASH_CR = 0)

Auf den Hard Fault wird explizit hier hingewiesen:
"Any attempt to write data that are not half-word long will result in a 
bus error generating a Hard Fault interrupt."

(Reference Manual)

Aber danach sieht dein Code nicht aus. Notfalls mal beim Debuggen ins 
asm schauen. wäre aber ungewöhnlich.

Passiert dies auch, wenn du den Debugger über diese Stelle laufen läßt? 
Nicht, dass ein Debuggerzugriff auf die falsche Stelle zu diesem 
kritischen Zeitpunkt das Problem auslöst.

Einige Überlegungen beruhen darauf, dass das Erase klappt. Hast Du das 
mal genau getestet. Dazu müßtest Du vorab etwas dorthin flashen. 
Vielleicht mal die Linkereistellungen verschieben und dein Programm 
flashen. Dann alles wieder zurück und prüfen.
Dafür im Debugger aber den Cache für den Flash abschalten. Sonst siehts 
du keine Veränderungen im Flash.

von Little B. (lil-b)


Lesenswert?

Claus schrieb:
>     FLASH->CR |= FLASH_CR_PER;                                    //
> erase page
>     FLASH->AR = 0x8003C00;
>     FLASH->CR |= FLASH_CR_STRT;

du musst beim Löschen einer Page die Pagenummer angeben, nicht die 
Adresse.
Hier wäre es Page Nr. 3, die von 0x08003000 bis 0x08003FFF geht.

Es ist richtig, dass das Flash nur 16bit breit schreiben kann. Alles 
andere wird Hard Fault generieren.

Desweiteren prüft der Flash controller, ob die zu schreibende Adresse 
nicht bereits daten enthält, also noch gelöscht werden muss. Sind Daten 
auf der Adresse vorhanden, wird der Schreibvorgang abgebrochen. Wird bei 
dir wohl der Fall sein, da du nicht richtig löschst.

von Steffen R. (steffen_rose)


Lesenswert?

Little Basdart schrieb:
> Claus schrieb:
>>     FLASH->CR |= FLASH_CR_PER;                                    //
>> erase page
>>     FLASH->AR = 0x8003C00;
>>     FLASH->CR |= FLASH_CR_STRT;
>
> du musst beim Löschen einer Page die Pagenummer angeben, nicht die
> Adresse.
> Hier wäre es Page Nr. 3, die von 0x08003000 bis 0x08003FFF geht.

Hier ist die Doku etwas ungenau(?) (DM00091010.pdf)

Im Text deine Aussage:
"Program the FLASH_AR register to select a page to erase"

Im Diagramm etwas genauer:
"Write ... an address within the page to erase."

Flash address register (FLASH_AR)
"This register is updated by hardware with the currently/last used 
address. For Page Erase operations, this should be updated by software 
to indicate the chosen page."

Dann wäre noch die Pagegröße abhängig vom Derivate. Im Eingangspost 
scheint ein 16k Derivate genutzt zu sein, somit 1k Pages.

(Nicht zu verwechseln mit den Derivaten, bei denen sektorweise gelöscht 
wird.)

> Es ist richtig, dass das Flash nur 16bit breit schreiben kann. Alles
> andere wird Hard Fault generieren.
>
> Desweiteren prüft der Flash controller, ob die zu schreibende Adresse
> nicht bereits daten enthält, also noch gelöscht werden muss. Sind Daten
> auf der Adresse vorhanden, wird der Schreibvorgang abgebrochen. Wird bei
> dir wohl der Fall sein, da du nicht richtig löschst.

Diesen Fall hätte ich auch ausgeschlossen, da hier im SR PERR gesetzt 
wird. Ein Hard Fault wird hier nicht erwähnt. Hab ich aber nicht 
getetet.

von Claus (Gast)


Lesenswert?

Hallo Leute,

danke Euch für die Hilfe !!!

Habe jetzt den Fehler lokalisiert: der Code war OK, aber in der 
vorherigen Initialisierung wurde der HSI abgeschaltet und auf PLL 
umgestellt. Ohne HSI läuft jedoch nichts...

Mal eine Frage rein aus Interesse: wisst Ihr was der HSI damit zu tun 
hat? In der Doku habe ich keinen Hinweis gefunden, dass der HSI bei der 
Programmierung des Flash laufen muss.

von Claus (Gast)


Angehängte Dateien:

Lesenswert?

gefunden, siehe Bild!

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Claus schrieb:
> gefunden, siehe Bild!

Danke! :-) Darauf wäre ich wohl auch bald hereingefallen.

Ich hoffe, meine 50 Stück sind bald da:
http://www.aliexpress.com/snapshot/6690781970.html

: Bearbeitet durch User
von Claus (Gast)


Angehängte Dateien:

Lesenswert?

Torsten C. schrieb:
> Ich hoffe, meine 50 Stück sind bald da:
> http://www.aliexpress.com/snapshot/6690781970.html

Wir bestellen die bei mouser, damit geht es etwas schneller :-)

Der Chef hat mal eine kleine vierlagige Platine dafür entworfen 
(32*24mm) nur mit dem Nötigsten drauf (3V3 LDO, RST-Taster, Quarz, 
UART-Umschalter, etwas Hühnerfutter).

Programmierschnittstelle, UART, RST, BOOT0 und Versorgung sind auf ein 
Micromatch-Stecker rausgeführt und gehen dann weiter auf den Debugger 
bzw. USB <-> Seriell Wandler.

Seit wir das Ding haben, wird der überall eingesetzt. So ein Modul ist 
halt sehr praktisch für "kleinere" Aufgaben :-)

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Claus schrieb:
> So ein Modul ist halt sehr praktisch für "kleinere" Aufgaben :-)

Ja! Bis jetzt habe ich diese hier:
http://www.aliexpress.com/snapshot/6626358701.html

Eure sind bestimmt preiswerter. Und falls nicht: Kleiner!
Ich möchte auch welche (unbestückte PCBs)!
Her damit, MicroMATCH rulez! :-)

: Bearbeitet durch User
von Claus (Gast)


Lesenswert?

Hallo Torsten,

Torsten C. schrieb:
> Eure sind bestimmt preiswerter. Und falls nicht: Kleiner!

Ich weiß leider selber nicht was die Module kosten, kann aber am Montag 
gerne fragen. Habe in der Firma halt den "Luxus" dass ich einfach nur 
ins Lager gehen muss wenn ich ein paar davon brauche...

Torsten C. schrieb:
> Ich möchte auch welche (unbestückte PCBs)!
> Her damit, MicroMATCH rulez! :-)

Das muss der Chef entscheiden, sollte aber kein Problem sein.

von google (Gast)


Angehängte Dateien:

Lesenswert?

Torsten C. schrieb:
> Ich hoffe, meine 50 Stück sind bald da:
> http://www.aliexpress.com/snapshot/6690781970.html

Meine sind da ... und was soll ich sagen? Läuft bei mir. ;-)

von Steffen R. (steffen_rose)


Lesenswert?

Claus schrieb:
> Habe jetzt den Fehler lokalisiert: der Code war OK, aber in der
> vorherigen Initialisierung wurde der HSI abgeschaltet und auf PLL
> umgestellt. Ohne HSI läuft jedoch nichts...

Der wird aber auch schon für das Erase benötigt...
Da dieses vermeintlich funktioniert hat, bin ich in die Irre gelaufen.

Danke, dass du die Lösung gepostet hast.

von Claus (Gast)


Lesenswert?

Steffen Rose schrieb:
> Danke, dass du die Lösung gepostet hast.

Aber natürlich, so hilft dieser Thread ja auch Anderen. Dafür ist doch 
ein Forum da :-)

google schrieb:
> Meine sind da ... und was soll ich sagen? Läuft bei mir. ;-)

Auch eine gute Idee mit dem Adapter! Für schnell mal in Betrieb nehmen 
ideal und es kostet kaum was. Reicht die Abblockung so weit vom IC weg 
noch aus? Moderne ICs wie der STM32 stecken ja mittlerweile einiges weg.

Claus schrieb:
> Torsten C. schrieb:
>> Ich möchte auch welche (unbestückte PCBs)!
>> Her damit, MicroMATCH rulez! :-)
>
> Das muss der Chef entscheiden, sollte aber kein Problem sein.

Habe mal nachgefragt, unsere Platinen kamen von Würth, sind aber leider 
schon alle bestückt. Wir werden aber wohl in den nächsten Monaten wieder 
ein paar dutzend Nutzen bestellen, davon kannst du gerne welche haben.

Wenn Interesse besteht, so wäre es wohl auch kein Problem zu den Modulen 
ein Datenblatt zu schreiben, ein Template für Keil (gibt es mittlerweile 
kostenlos für den STM32F0 - auch für kommerziell!) zu erstellen und sie 
ins Webshop zu stellen. Ist halt eine beim örtlichen Bestücker 
gefertigte vierlagige Platine in recht überschaubaren Stückzahlen und 
daher vermutlich nicht konkurrenzlos billig (4L bei uns leider nötig 
wegen Störabstrahlungs- / Störfestigkeitsprüfung in den Endgeräten - 
aber die Module bestehen sie auch mit Bravur :-)

von Claus (Gast)


Angehängte Dateien:

Lesenswert?

Claus schrieb:
> So ein Modul ist
> halt sehr praktisch für "kleinere" Aufgaben :-)

Anbei ein Bild von einem solchen Teil.

von google (Gast)


Lesenswert?

Claus schrieb:

> google schrieb:
>> Meine sind da ... und was soll ich sagen? Läuft bei mir. ;-)
>
> Auch eine gute Idee mit dem Adapter! Für schnell mal in Betrieb nehmen
> ideal und es kostet kaum was. Reicht die Abblockung so weit vom IC weg
> noch aus? Moderne ICs wie der STM32 stecken ja mittlerweile einiges weg.

VDDA war nicht angeschlossen (streng verboten lt. abs. max. ratings, er 
hat es überlebt) und die Abblockkondensatoren haben nur 22n, trotzdem 
läuft es. Das ist sicher nicht geeignet für irgendwas anderes als einen 
schnellen Programmier- und Funktionstest mit Blinky, aber der läuft 
jetzt seit 10 Tagen an einem 0815-USB-Netzteil/ams1117 3,3 Chinateil 
durch. Hätten ja bedruckte Leergehäuse sein können und meine 
"maßgefertigte" Adapterplatine zeichne ich gerade noch, bevor sie dann 
hoffentlich drei Wochen nach Absendung bei Itead aus der Fertigung 
kommt. Hab immer nur zwei Stunden pro Woche Ruhe zum Basteln.
Eigentlich wollte ich zwischen die DIL-Pins SMD-Kondensatoren löten, 
dann war ich aber doch zu ungeduldig. Lötkolben war wieder aus, stecken 
ging schneller. Projekt habe ich noch keins, das war einfach just for 
fun

von Claus M. (claus_mueller) Benutzerseite


Lesenswert?

google schrieb:
> Projekt habe ich noch keins, das war einfach just for
> fun

:-) kommt noch, die kleinen STM32F030 sind ja wie gemacht für schnelle 
Projekte.

Claus schrieb:
> Claus schrieb:
>> So ein Modul ist
>> halt sehr praktisch für "kleinere" Aufgaben :-)
>
> Anbei ein Bild von einem solchen Teil.

Habe mal eine kleine Projektbeschreibung erstellt, vielleicht hilft es 
ja dem einen oder anderen beim Einstieg:

T on delay

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.