In meiner Anwendung soll ein STM32F100R8T6B über SPI umprogrammiert werden können. Der STM ist dabei im SPI Slave mode, das neue Programm wird zur Laufzeit vom Master in SPI-Paketen übertragen. im Slave werden die Daten in einen freien Teil des int. Flash geschrieben, danach umkopiert und der STM startet sich selbst. Hierzu wurden bereits sämtliche Flash-Routinen, sowie der SPI-IRQ Handler ins RAM ausgelagert. Alle Routinen funktionieren nach ersten Tests einwandfrei, solange der Flash nicht "busy" ist. Sobald ein Flash Sektor gelöscht oder geschrieben wird, reagiert der STM temporär nicht mehr auf eingehende SPI-Pakete zur Status-Abfrage(Polling, ob das letzte Paket korrekt geschrieben wurde) Ich vermute, daß noch (irgendwo) ein CPU Stall auftritt und suche nun nach Möglichkeiten, dieses "irgendwo" zu lokalisieren. Intensives Suchen im Code sowie im List-File brachte leider keine Resultate. Ideal wäre ein Breakpoint, der aktiviert wird, sobald der STM einen Flashzugriff versucht. Mir fiel auf, daß mein STLink auf Breakpoints innerhalb Flash-basierter ISRs reagiert und diese im korrekt anzeigt. Sobald eine Routine jedoch in den RAM verschoben wird, ist der Breakpoint wirkungslos bzw. wird ignoriert. Gibt es hier eine Möglichkeit, auch diese zu aktivieren? Der Versuch per Schrittbetrieb kurz vorm Löschen das Flashes zu starten und sich dann IRQs oder Zugriffe anzuzeigen brachte keinerlei Erkenntnisse - es traten schlicht keinerlei Ereignisse auf, da ja selbst die SPI-Interrupts ignoriert wurden. (Auf Masterseite sah man, daß diese während des Schrittbetriebs erwartungsgemäß nicht abgearbeitet wurden.) Gibt es evtl jemanden, der vor ähnlichen Rätseln stand oder mir ein paar konstruktive Ratschläge geben könnte, wie man in dieser Situation weiter vorgehen könnte? Vielen Dank ein ziemlich ratloser STM32-User ps: Debugausgaben via UART sind prinzipiell zwar möglich, brachten jedoch aufgrund der hohen Übertragungsgeschwindigkeit des SPI-Busses und der kurzen Stall-Zeit bis auf einige verpaßte Daten keinen wirklichen Nutzen.
STM32-User schrieb im Beitrag #3355718: > sowie der SPI-IRQ > Handler ins RAM ausgelagert. Auch die Interrupt Vector Table (Register VTOR)? Ohne die kann er den oder die Handler nicht anspringen.
Vielen Dank für die Anregung Jim. Leider muß ich sagen - ja, sie liegt im RAM. Das Linkerskript wurde modifiziert, sodaß .isr_vector in ">RAM AT>FLASH" liegt. Da es mir nicht gelang, die Daten im RAM via Linker-Skript zu initialisieren, kopierte ich sie händisch. Dies wird gleich zu beginn in der Main erledigt: memcpy(p_ramisr, p_flashisr, isrlen); NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); p_flashisr (0x0000000) p_ramisr (0x20000000) (= NVIC_VectTab_RAM) isrlen (0x1D0) lt. List-File geht die ".data" section (_sdata) bei 0x200001D0 los - d.h. der bereich vorher wurde reserviert. Im "nicht busy" Betrieb werden die Handler korrekt angesprungen. =============================== Aber trotzdem ein sehr guter Einwand, im "Normalbetrieb" würde man nicht merken, ob er den Handler aus einer Tabelle im RAM oder Flash anspringt.
Hallo, nutzt du die Flash-Programmierroutinen aus der STlib? Dort gibt es viele Warteschleifen... Evtl. das alles zu einer Art kooperativem Multitasking umprogrammieren, d.h. man wartet nicht darauf, dass etwas fertig wird, sondern arbeitet auch die anderen Programmteile noch ab.
Hallo Marvin, genau die nutze ich, habe sie lediglich leicht modifiziert, sodaß sie im RAM liegend ihren Dienst verrichten. Die Warteschleife beim Flasch löschen stört mich an dieser Stelle nicht. Da die Applikation im Normalbetrieb (d.h. nicht während eines Updates) sehr strikte Echtzeitanforderungen hat, verzichte ich auf ein OS, nutze eine schlanke Maintask und führe das Parsen und den CRC-Check der eingehenden SPI-Pakete im Interrupt aus. (Paßt soweit zeitlich auch gut, sodaß ich im Normalbetrieb keine Daten verliere. Zu Debugzwecken schreibt der Master in sehr kurzen Zeitabständen einzelne Bytes (sequentielle Werte) via SPI, die der Slave einfach zurückgibt. im Normalmodus kommen die daten 1:1 zurück (genau 1 Byte verzögert,so wie es sein soll). Beim Flash-Löschen sieht man nun sehr schön das Löschen der einzelnen Sektoren- hier wird durch Stall die SPI routine nicht aufgerufen und der Master bekommt immer die gleichen Daten zurück. Daher habe ich auch kein Zweifel, daß es sich um einen CPU Stall handelt - das Löschen wird ja in der Main Routine angestoßen und dort auch erfolgreich abgearbeitet.. Die Frage, die sich mir stellt ist nur: wie (mit welcher Methode) kriege ich am effizientesten raus, wodurch genau der Stall verursacht wird. Nun, ich suche und probiere weiter.. (kommt mir langsam vor wie die Suche nach der Nadel im Heuhaufen :))
Korrektur: die Antwort vom Slave kommt 2 Byte danach an Ich habe soeben einen Test gefahren: direkt nach dem Starten des "Flash-Löschens" werden vom Master die Bytes 0x00 bis 0x0F periodisch geschrieben und die Antworten ausgewertet. Dies kam dabei raus: TX: [TX+ 0]: 00,01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F, [RX+ 0]: 00,00,00,00,00,00,00,00,00,00,00,02,02,02,02,02, [TX+ 16]: 00,01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F,00,01,02,03,04,05,06 [RX+ 16]: 02,02,02,02,0B,0B,0B,0B,0B,0B,0B,0B,0B,0B,0B,04,04,04,04,04,04,04,04 [TX+ 39]: 07,08,09,0A,0B,0C,0D,0E,0F,00,01,02,03,04,05,06, [RX+ 39]: 04,04,04,04,0F,0B,0B,0B,0B,0B,0B,0B,0B,0B,0B,0C, ... hier der letzte flash sektor: (versatz des "echos" ist nun wieder konstant 2) [TX+234]: 0A,0B,0C,0D,0E,0F,00,01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F [RX+234]: 06,06,06,06,06,02,02,02,02,02,02,0F,0F,05,06,07,08,09,0A,0B,0C,0D
Hallo, hm - OK, ich hatte bislang überlesen, dass die SPI-Routinen im Interrupt laufen. In PM0075 Seite 10 heißt es: "During a write operation to the Flash memory, any attempt to read the Flash memory will stall the bus. The read operation will proceed correctly once the write operation has completed. This means that code or data fetches cannot be made while a write/erase operation is ongoing." Für mich sieht das aus, als ob da doch noch Zugriffe ins Flash laufen. Wenn ich dich richtig verstehe, kopierst du den Code zu Beginn der Aktion vom Flash in den RAM. Bist du sicher, dass der Code relozierbar ist bzw. tatsächlich für den RAM compiliert wurde? Wenn da ein Unterprogrammaufruf oder eine Konstante absolut angesprochen werden, war es das. Die Aufrufe der StLib sind teilweise extrem verworren und die exzessive Nutzung von defines macht es nicht unbedingt leichter, wirklich alles zu finden. Ich würde mir die Map des compilierten Codes mal genauer anschauen und versuchen nachzuvollziehen, ob die Funktionsaufrufe auch wirklich alle ins RAM gehen. Ins Blaue geschossen tippe ich auf den Zugriff auf eine Konstante, die im Flash steht.
Hi Marvin, Danke für die Ideen - wenn alle Stricke reißen bleibt mir wirklich nur übrig, nochmal das gesamte MapFile durchzuschauen. Ich hatte bisher die (zu dem Zeitpunkt) aktiven RAM-Routinen auf branches in den Flash überprüft. Hatte ne ganze Weile gedauert, dies alles "sauberzukriegen", deine Einschätzung zur ST-Lib kann ich also 100%ig teilen. :-) Allerdings weiß ich nicht genau, wie es sich mit Flash-Konstanten verhält. Dies muß ich nochmal gründlich überprüfen. In der Lib gibts wirklich haufenweise Defines- gut möglich, daß die ein oder andere Konstante mit bei ist. Aber ich will nicht nur meckern- die ST-Lib ist ansonsten wenigstens strukturiert programmiert und man findet was man sucht (bei anderen Prozessoren sieht es da wesentlich schlimmer aus). Für Deine Mühe Danke ich Dir von ganzem Herzen - jetzt habe ich zumindest einen Ansatz, wo ich weitersuchen kann. Sollte dieser scheitern, werde ich meine "Analyse-routine" nutzen müssen,um zu detektieren, wann der kritische Zugriff vorbei ist - danach funktionieren die SPI cmds ja wieder. Glücklicherweise gibt es keine Echtzeitanforderungen während des Updates, sodaß mir dieser letzte Ausweg noch bleibt. Tausend Dank für deine Hilfe der STM32-User, der nun ein fahles Licht am Ende des Tunnels sieht ;)
Hi, habe das gleiche Probelm. Stall obwohl die Routienen zum SChreiben aus dem RAM aufgerufen werden. Hast du den Fehler inzwischen gefunden? VG
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.