Hallo zusammen ich habe seid kurzm folgendes Problem. Ich habe eine Entwicklungskit von Olimex mit einem STM32F103 Controller. Wenn ich versuche Speicher per malloc zu allozieren, dann beendet sich das Programm und gibt mir eine BusFaultException raus. Ich habe keine Ahnung, wie man dem Problem auf den Grund geht, oder wo ich den Fehler suchen soll. Vielleicht hat ja einer einen Idee.
Wo wird das denn verwaltet? Im Linkerskript wird der Stack festgelegt, aber ob und wo man den Heap verwaltet, weiß ich leider nicht. Entschuldige bitte, aber ich bin Anfänger. Vielleicht kannst du mir da auf die Sprünge helfen. Ich muss dazu sagen, dass es schon einmal funktioniert hat. Aber jetzt irgendwie nicht mehr.
Hi, arbeitest du mit den Keil Tools? Da kann man im startup-file sehr einfach den heap einstellen. Übrigends ist die Demo bis 32k frei (20k Code + 12k konstanten). Damit kann man schon mal so einiges anstellen. Auf jeden Fall erst mal etwas Heap "freigeben". VG, /r.
Hallo Ich arbeite nicht mit Keil. 32k sind mir leider zu wenig (hab jetzt schon 85k). Ich arbeite mit Eclipse, dem GCC von der sarm-toolchain von ST und OpenOCD per JTag von Olimex. Ich habe gelesen, dass man das bei Keil einstellen kann. Aber es muss doch auch so irgendwo einstellbar sein oder festgelegt werden können.
Suche dir doch irgendwo ein C++ Beispiel für den ARM-GCC, da wird auf jedenfall der Heap benötigt und reserviert.
Abgesehen davon würde ich bei uC-Anwendungen niemals mit dynamischer Speicherreservierung arbeiten.
@Bolo Arbeitest du aber schon immer, Stackbedarf ist auch dynamische Speicherreservierung, wenn man es genau betrachtet.
anbei das verwendete Linkerskript (habe es im Internet gefunden und es funktionierte). beim Testen und rumspielen habe ich jetzt festgestellt, dass das Allozieren von speicher bis zu einer bestimmten Größe möglich ist, aber darüber hinaus nicht. ich kann maximal 492 Bytes allozieren, mehr nicht. Ist echt ein komischer Wert. DANKE für eure Mithilfe
Memory-Layout lässt eine Stack-Heap-Kollision zu. Ist etwas kniffig zu debuggen. Wäre einfacher mit Stack hinter bss und Heap nach Stack, dann kann der Heap nur gegen das RAM-ende "krachen", Core-Exception dürfte aber die Gleiche sein. Wird in der Anwendung schon ordentlich RAM durch globale/statische Variablen oder zeitweise durch große/viele automatische Variablen verbraucht? Evlt. enthält "." ganz am Ende und ausserhalb der sections irgend einen unsinnigen Wert. Testweise die Zeile mit provide end ganz am Ende löschen und weiter oben hinter
1 | end = .; |
und vor } noch
1 | __end__ = . ; |
2 | _end = .; |
3 | PROVIDE (end = .); |
Vorher und nachher anhand von map- und symbol-File prüfen, ob end auf eine sinnvolle Adresse gesetzt wird (vgl. _bss_end_). Ansonsten: Minimalprojekt mit allen erforderlichen Dateien erzeugen (source, startup, linkerscript, makefile), um das Problem nachzuvollziehen und hier einstellen. Evtl. auch an Spencer Oliver senden, er düfte in Sachen STM32 und GNU-Tools einer der kompetentesten Ansprechpartner sein (e-mail Adresse an vielen Stellen in SARM Dateien)
@Martin Thomas Habe das mal ausprobiert, aber ohne Erfolg. Leider kenne ich mich mit den Linkerfiles überhaupt nicht aus. Wie kann ich denn den Stack und Heap hinter bss bringen? Entschuldige, aber ich habe wirklich keinen Plan davon. Eigentlich verwende ich nicht sehr viel an globalen Variablen, einige kleinere char-Arrays (2x90byte + ein paar kleinere)
Ich bin jetzt mal etwas tiefer eingestiegen. Es sieht so aus, als ob malloc hier nicht den richtigen Heappointer benutzt. die Funktion malloc hat eine Variable names __malloc_sbrk_base. Dies ist die Base-Adresse des Heaps. Die wird hier falsch übergeben. Die hier angezeigte Adresse liegt mitten im bss-Segment. Das ganze noch mal rein formal: Adresse end. am Ende des Linkerscripts liegt bei bspw. 0x2000091f, die in __malloc_sbrk_base angezeigte Adresse ist aber 200003f8, also mitten im bss-Segment. Dann ist klar, dass malloc schief gehen muss. Aber wo wird malloc die Adresse für __malloc_sbrk_base übergeben. habe nirgens in der Newlib eine zuweisung oder Adressierung gefunden. Mein Problem ist, dass ich einen SPI SD-Kartentreiber gefunden habe, der funktioniert. Habe ein fertiges Programm kompiliert und getestet. Wenn ich das bei mir integriere, dann bekomme ich dieses Problem. Aber der Treiber greift auf keine Malloc-funktion zu, habe ich getestet. Mit einem anderen Treiber, der aber nicht so schön, nicht vollständig und leider noch fehlerbehaftet und unkomfortabel ist, habe ich nicht das Problem nicht. Das passt der Pointer genau. Ich habe da jetzt hin und hergesucht, finde aber keine Erklärung dafür. Kann mir dazu jemande einen Tipp geben?
Das ist eines der "ARM-Probleme". Das Runtime-Startup-File und das Linkerscript müssen zusammenpassen. Jede Umgebung die ich bisher gesehen habe verwendet andere Bezeichner (z.B. für Heap-Anfang/Ende, Stack Anfang/Ende usw.) und Reihenfolgen der Speicherbereiche. Somit ist es ohne (z.T. erheblichen) Zusatzaufwand kaum möglich diese Files zwischen verschiedenen Paketen zu mischen (z.B. WinARM mit Yagarto).
Daniel Wolf wrote: > Ich bin jetzt mal etwas tiefer eingestiegen. > Es sieht so aus, als ob malloc hier nicht den richtigen Heappointer > benutzt. die Funktion malloc hat eine Variable names __malloc_sbrk_base. Hmm, woher kommt die Information? Quellcode - zumindest von sbrk? Üblicherweise (bei newlib) greift malloc auf sbrk zurück und sbrk braucht beim ersten Aufruf die Information darüber, wo es dann mit dem Heap loslegen darf. Standardbezeichnung ist end (siehe auch Standard-Linkerscripts der binutils). Kann aber gut sein, dass sbrk so implementiert wurde, dass es statt end wohl __malloc_sbrk_base erwartet. Habe auf dem Rechner grade sarm/Idealist nicht installiert, sonst kann man in den Beispielen nachschauen. Zur Not ein eigenes sbrk implementieren. Wenn richtig erinnert ist das in syscalls der newlib in sarm "weak". > Dies ist die Base-Adresse des Heaps. Die wird hier falsch übergeben. Die > hier angezeigte Adresse liegt mitten im bss-Segment. > Das ganze noch mal rein formal: > > Adresse end. am Ende des Linkerscripts liegt bei bspw. 0x2000091f, die > in __malloc_sbrk_base angezeigte Adresse ist aber 200003f8, also mitten > im bss-Segment. Dann ist klar, dass malloc schief gehen muss. Aber wo > wird malloc die Adresse für __malloc_sbrk_base übergeben. habe nirgens > in der Newlib eine zuweisung oder Adressierung gefunden. Man versuche im Linker-Script direkt hinter PROVIDE (end = .); die Zeile PROVIDE (__malloc_sbrk_base = .); und prüfe, ob dann die Zuweisung passt. > Mein Problem ist, dass ich einen SPI SD-Kartentreiber gefunden habe, der > funktioniert. Habe ein fertiges Programm kompiliert und getestet. Wenn > ich das bei mir integriere, dann bekomme ich dieses Problem. Aber der > Treiber greift auf keine Malloc-funktion zu, habe ich getestet. Mit > einem anderen Treiber, der aber nicht so schön, nicht vollständig und > leider noch fehlerbehaftet und unkomfortabel ist, habe ich nicht das > Problem nicht. Das passt der Pointer genau. Ich habe da jetzt hin und > hergesucht, finde aber keine Erklärung dafür. Kann mir dazu jemande > einen Tipp geben? Etwas zu wenig Information. Das angefrage Minimalbespiel um das Problem zu reproduzieren steht ja noch aus.
Werner B. wrote: > Das ist eines der "ARM-Probleme". Das Runtime-Startup-File und das > Linkerscript müssen zusammenpassen. Jede Umgebung die ich bisher gesehen > habe verwendet andere Bezeichner (z.B. für Heap-Anfang/Ende, Stack > Anfang/Ende usw.) und Reihenfolgen der Speicherbereiche. Soweit "kopfnick". > Somit ist es > ohne (z.T. erheblichen) Zusatzaufwand kaum möglich diese Files zwischen > verschiedenen Paketen zu mischen (z.B. WinARM mit Yagarto). Was haben Linker-Scripte und Startup-Code mit dem Packet der toolchain zu tun? Worum erheblicher Zeitaufwand? Wofür? Der einzig wirklichen Unterschied zwischen WinARM (20060606) und Yagarto(letzte ausprobierte Version, länger her) war/ist die konfiguration der newlib bezgl. syscalls. Falls man diese nicht braucht sehe ich keinen Grund für "erheblichen" Zusatzaufwand.
> Hmm, woher kommt die Information? Quellcode - zumindest von sbrk? ich stelle mal die aktuell von mir verwendeten Linkerscripte und Vector in den Anhang. diese habe ich modifiziert und angepasst so weit ich konnte. Habe sie in den Anhang gestellt. sie sind ursprünglich auf einem anderen Projekt (Donwloadlink: http://www.st.com/mcu/modules.php?mop=modload&name=Splatt_Forums&file=attachment&AtchOp=get&postid=20160&AtchName=cs-stm32-0.91.zip&AtchNum=0) Syscalls habe ich auch begefügt, diese habe ich aus einem STM32-Framework. (zu finden unter http://www.munts.com/MCU/ARM/stm32f103/) In den Syscalls wird mit end[] der Heappointer initialisiert, wenn ich mich nicht irre. Dessen Adresse kann ich nach dem Start auslesen. > Man versuche im Linker-Script direkt hinter PROVIDE (end = .); die Zeile > PROVIDE (__malloc_sbrk_base = .); und prüfe, ob dann die Zuweisung > passt. bring leider auch keinen Erfolg > Etwas zu wenig Information. Das angefrage Minimalbespiel um das Problem > zu reproduzieren steht ja noch aus. also den ersten, meiner Meinung nach nicht so guten Code für SPI -> SD/MMC ist der, den ich bei meinem Entwicklungsboard mit dabei hatte (Download: http://www.olimex.com/dev/soft/arm/STR/STM32F103-STK-TST.rar, mmc.c +.h). Der zweite, meiner Meinung nach besser ist von IAR auch in einem Demoprojekt für das Entwicklungsboard (Download: http://www.olimex.com/dev/soft/arm/ST/STM32-103STK/EW-ARM511%20STM32-103STK-.zip , zu finden im Ordner STM32-103STK-MassStorage/app die Dateien mmc.c +.h und mmc_ll_SPI2.c). Den habe ich modifiziert und erstmal alles was die DMA betrifft, entfernt. Das ist meine Grundlage, mit der ich versuche was auf die Beine zu stellen.
So, habe es jetzt endlich zum laufen bekommen. Ich habe mir den SARM Idealist heruntergeladen und mir mal die Bsp. angeschaut. Habe darauf hin dann alle notwendigen Dateien, wie Linkerscript, Vectortabelle und Startup in mein Porjekt integriert, passende Bib aus der SARM-Toolchain dazugelinkt, und siehe da, es funktioniert. Also vielen Dank, vor allem an Martin Thomas. Dank seiner Tipps habe ich es zu laufen gebracht.
@Martin Thomas Der "erhebliche Zeitaufwand" ist bei denen vorhanden die sich erst A) in die Syntax der Linkerscripte einarbeiten müssen B) rauszufinden welchen Zweck die einzelnen (jeweils anders genannten) Symbole erfüllen (sollen). Um auch zu "wissen was man tut" (-;|= Das das für dich kein Problem ist steht ausser Frage. Einer hat eben schon das spezelle Fachwissen und Fragesteller (und ich ;) idR nicht. Werner
Ich hatte nach dem "erheblichen Zeitaufwand" im Hinblick auf das "Mischen" zwischen verschiedenen Binärpacketen der GNU toolchain gefragt.
Hallo, ich verzweifele an gleichem Problem mit STM32F4... ...kannst du mir vielleicht paar tipps geben? ich verwende eclipse mit Sourcery uns GDB - Server von Atollic. gruß Denis
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.