Und ich wieder mal .. Da ich bisher mehr mit C und auch unter Windows bzw. AmigaOS zu zun hatte, als mit Assembler stellt sich mir die Frage, wie ich mir Speicher bei einem AVR unter Assembler organisiere. Sicher könnte ich irgendwo im Speicher rumrühren. Und sicher wird es keine Befehle geben, die da heißen "malloc(), calloc()" usw. Aber wie kann ich mir Speicher zur Verfügung stellen und dabei auch sicher gehen, dass ich mir nicht in meine Programmdaten rumschreibe? Schliesslich liegt ja der Stack da irgendwo, genauso wie die Register, wenn ich das richtig verstanden habe.
das programm bei den avr's liegt im flash-rom... der stack im sram und für variablen benutzt man die register r0 bis r31, wenn man nun doch etwas auf den stack schieben will, dann mit push/pop... ansonsten musst du dich selber darum kümmern, das deine verschachtelungstiefe und deine per push zwischengespeicherten werte, sich nicht mit der größe deines benutzen speicherbereichs beißt. der avr fängt immer an der letzten sram stelle an, wenn man also in einer unterroutine ist und vorher noch 2 bytes gepusht hat, dann sind die letzten 4 bytes des srams belegt... dann kannst du also noch die ersten 124bytes benutzen (wenn man ein typ mit 128bytes hat)... wenn du ausversehen rücksprungadressen überschreibst, merkst du das ziemlich schnell weil der controller nicht das macht, was du dir gedacht hast :-) aber das programm kannst du nur per programmieren ändern... LameM
Ich will ja auch nichts verändern, ich will ja bloss ein paar Bytes Pufferspeicher haben. Ich habe auf meinen ATmega16 1kByte zur Verfügung. Und davon will ich halt mal 100 Bytes oder so benutzen. Aber sicher gehen, dass ich da nicht was überschreibe. Das 1 kByte steht mir völlig frei zur Verfügung. Wenn ich davon ausgehe, dass der Stack am Ende liegt und ich davon ausgehe, dass sonst alles frei ist, kann ich mir doch den Speicher selbst aufteilen. Also direkt am Anfang des SRAMs rumschreiben? Speicher geht von $0060-$045F. Also kann ich ab $0060 meine Daten ablegen. Ist das korrekt so? Bzw. wie kann man das halbwegs portabel machen, um das z.B. auch auf einen ATmega8 anzuwenden. Ich müsste entweder irgdnwie ermitteln, wie groß der RAM ist oder wo er beginnt. Das Ende habe ich ja mit RAMEND. War das jetzt alles Müll, was ich da geredet habe oder macht man das so?
es gibt keinerlei automatischen Speicherschutz, es liegt ausschliesslich in der Hand der Programmierers. Der Prozessor weiss nicht, wo und wann stack und Daten evtl. kollidieren. Daten von unten nach oben aufsteigend, stack von oben nach unten, aus. Läuft der stack aus dem Ruder, werden Daten zerstört, entweder durch direkte Programmierfehler (ungleiche Anzahl von push und pop oder aus einem Unterprogramm mit jmp statt ret zurückspringen) oder durch zu tiefe Verschachtelung, dabei worst case beachten. Ist zwar letzten Endes auch ein Programmierfehler, aber leider nicht so offensichtlich. Völlig portabel kann man es nicht machen, da man nicht automatisch weiss, wie tief der stack im jeweiligen Programm benutzt wird, können je nach Programm nur ein paar Byte oder auch 100 und mehr Bytes sein.
Danke! Also kann ich letzten Endes machen, was ich will. :) Das mit den Stack und den Daten ist sicher andersherum gemeint. Was bedeutet "worst case"?
'worst case', sozusagen der 'größte anzunehmende (Un)fall'... Aber da du schon das C-Spezifische 'malloc()' erwähnt hast, ist vielleicht noch zu sagen, dass auch solche Funktionen mit dem passenden Compiler, z.B. den WinAVR, auf einem AVR zur Verfügung stehen.
Dann müsste ich echt schauen, wieviel ich im schlimmsten Fall mit meinem Stack mache und den Rest habe ich dann frei an Speicher ... Ja WinAVR ist ja auch C und da erwartet man solche Funktionen ja. ;) Allerdings programmiere ich hier alles in Assembler, was beim Microcontroller viel Sinn macht, da man sowieso fast nur mit Port- Ein- und Ausgaben beschäftigt ist. Und man spezieller timen kann. Allerdings wäre in C alles viel einfacher denke ich. :) Gerade was das rechnen und adressieren angeht.
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.