Moin, kann mir vielleicht jemand sagen, ob es möglich ist die Register 0-31 des AVR in C zu beschreiben. Danke! Gruß Tom
@ Tom >kann mir vielleicht jemand sagen, ob es möglich ist die Register 0-31 >des AVR in C zu beschreiben. Danke! Steht in der Doku der libc, such nach Inline Assembler. Aber wozu brauchst du das? Sowas ist in C normalerweise nicht nötig. MFG Falk
Nein. D.h. wenn Du es versuchst, krachts gewaltig. Dazu hast Du unter C Variablen, damit Du Dich nicht mehr mit Registern abquälen mußt. Peter
Kannst aber auch eine Variable einem Register fest zuordnen, wenn dir das weiterhilft.
@Tom: Machs aber eher nicht. Dem Compiler bei der Register Belegung ins Handwerk zu pfuschen bringt normalerweise nichts ..... ausser Ärger.
Ich weiß, normalerweise setze ich die Register und Ports nach ihren Bezeichnungen aus dem Datenblatt. Doch habe ich bei einer Software das Problem, dass ich sie nach einem bestimmten aufgetretenen Ereignis wieder in den Ausgangszustand bringen muss. Dazu habe ich über den Debugger im I/O View Fenster die aktuellen Zustände angeschaut und angepasst. Die sind nun alle so wie zu Beginn. Jedoch zeigt mir das Prozessorfenster andere Werte in den Registern. Kann ich irgendwie kontrolieren, in welchem Register des Controllers zum Beispiel die UART ihren Platz hat. Oder gibt es eine Möglichkeit alle Register auf einmal zu löschen, ohne den Chip zu resetten?
@ Tom >Oder gibt es eine Möglichkeit alle Register auf einmal zu löschen, ohne >den Chip zu resetten? Tom, du verwechselst die Register der CPU (R0-R31) mit den Special Funktion Registers, mit denen die Hardware gesteuert wird. Erstere gehen dich als C Programmierer gar nichts an, letztere kannst du ganz normal lesen und schreiben wie C-Variablen, die entsprechenden Includes avr/io.h bieten alle Namen gemäss Datenblatt. MFG Falk
Mit "Register" hat natürlich jeder an Prozessorregister gedacht. Schätze du meinst I/O-Register. Da gibt's 2 Wege: Alles von Hand entsprechend Urzustand einstellen. Oder Watchdog aktivieren, kürzester Timeout, Interrupts abschalten und dann ab in die Totschleife. Gibt dann einen wunderschönen Reset und alles ist wieder initialisiert.
Tom wrote: > Doch habe ich bei einer Software das Problem, dass ich sie nach einem > bestimmten aufgetretenen Ereignis wieder in den Ausgangszustand bringen > muss. Hast du davon den Quelltext? Ich versteh noch nicht, wie da C ins Spiel kommt. Wenn du den Quelltext hast, müsste man den analysieren und schauen wie man auf C Ebene eine Rücksetzung in den Anfangszustand hinkriegt. Das heist zb. alle Initialisierungen in eine eigene Funktion packen. Diese Funktion wird dann von main() aufgerufen bzw. dann wenn dein bestimmtes Ereignis eingetreten ist. Wenn du keinen Quelltext hast, hast du sowieso ein Problem. Wie willst du es arangieren, dass dein C-Programm sich mit dem anderen Program gemeinsam im Speicher arangiert.
@ A.K.
>Mit "Register" hat natürlich jeder an Prozessorregister gedacht.
Nö, der OP schrieb schon R0-31. Meinte aber die SFRs. 8-0
MfG
Falk
>Alles von Hand entsprechend Urzustand einstellen. Hab ich versucht, haut aber nicht hin. I/O Register sehen genauso aus, wie beim Start. Jedoch funktioniert der anschließende Verbindungsaufbau nicht wie beim Start. >Wenn du den Quelltext hast, müsste man den analysieren >und schauen wie man auf C Ebene eine Rücksetzung in den >Anfangszustand hinkriegt. Das heist zb. alle Initialisierungen >in eine eigene Funktion packen. Genauso hab ich es gemacht. Zu Beginn des Verbindungsaufbaus ist nur das Baudratenregister gesetzt. Ansonsten nichts. Das krieg ich so auch auch wieder hin, nur die Verbindung klappt nicht. >Watchdog aktivieren, kürzester Timeout, Interrupts abschalten und dann >ab in die Totschleife. Gibt dann einen wunderschönen Reset und alles ist >wieder initialisiert. Das hab ich schon gemacht. Klappt super, so hätt ich das gerne ohne Reset, da ich Werte von der alten Verbindung speichern will ohne dazu das EEPROM zu verwenden.
@ Tom >Das hab ich schon gemacht. Klappt super, so hätt ich das gerne ohne >Reset, da ich Werte von der alten Verbindung speichern will ohne dazu >das EEPROM zu verwenden. Das kannst du im SRAM machen, der wird duch einen Watchdog-Reset nicht beeinflusst. Aber sinnvollerweise solltest du den Fehler in deinen Registereinstellungen suchen, das Ganze kann sicher auch ohne Watchdog-Reset gelöst werden. MFG Falk
Werte speichern geht auch ohne EEPROM. Du musst nur das obere Ende vom bekannten RAM heruntersetzen (es gibt m.W. eine Compiler/Linker-Option dafür). Die Lücke zwischen diesem Wert und dem echten Ende wird vom Watchdog-Reset nicht verändert, lässt sich also ggf. als Zwischenspeicher nutzen.
Kann ich nicht einfach ne Variable iregendwo im Flash ablegen, die nach einem Watchdog noch ihren Wert besitzt?
Hatte letztens auch mal versucht was im RAM Speicher abzulegen. Bekamm aber immer die Meldung, dass die Adresse, wo ich was ablegen wollte schon belegt ist. Ziemlicher Mist, denn es war nicht mein eigener Code. Hatte den vom Studi-Server. War für ne Kommunikation von nem WT12 und nem Mega. Funktionierte alles, nur erweitern ließ sich das Teil nicht. Ja ja, immer doof wenn man das nicht selber geschrieben hat. Aber vielleicht kann mir einer von euch sagen, ob in dieser Zeile: volatile uc_8 rf_buffer_tx[32]__attribute__((section(".buffer_tx"))); //buffer for storing the RF TX data ein Bereich im das RAM festgelegt wird? Denn der Compuiler gab mir als Fehler an, das die Adresse durch den buffer_tx bereits belegt ist. Wie kann man denn einen bestimmten Bereich im RAM festlegen/zuweisen?
Wenn man wie hier eine eigene Section verwendet, dann muss die auch vom Linker-Script erfasst werden, sonst wird das nichts. Da man aber bei AVRs Linker-Script normalerweise nie zu sehen kriegt, hatte ich die etwas einfacher handhabbare Methode mit dem oberen Speicherlimit empfohlen.
> Kann ich nicht einfach ne Variable iregendwo im Flash ablegen,...
Im Flash kann man prinzipiell nur konstante Daten ablegen. Das Flash ist
nur von der Boot-Section aus beschreibbar, und das auch meist nur
Page-weise.
Was hat das denn mit dieser Compiler/Linker-Funktion auf sich bzw. wie genau soll das funktionieren? Steht darüber was im Datenblatt?
Mit -minit-stack=N lässt sich die obere Grenze des von WinAVR verwalteten Speichers festlegen. Normalerweise ist das die obere Grenze vom RAM. Setzt man diese grenze tifern an, bleibt der Bereich dazwischen beim Reset unangetastet und kann mit struct uninitialized_vars { .... } *uninit_ptr = (struct uninitialized_vars *)0xXXXX; angesprochen werden. Man sollte dann freilich nach Reset kontrollieren, wodurch dieser ausgelöst wurde. Denn wenn es fehlende Versorgungsspannung war (Brownout-Detector nützlich), dann ist der Inhalt Schrott. Was für ein Datenblatt? Von den AVRs? Da steht Hardware drin, nicht Software.
Nochmal zurück zur Ursprungsfrage:
> ob es möglich ist die Register 0-31 des AVR in C zu beschreiben
Ja, das ist möglich mit dem inline-Assembler und wird z.B. benötigt,
wenn man von C aus eine Assembleroutine mit nicht-C-kompatibler
Parameterübergabe aufrufen will.
Generell muß man dabei folgendes beachten:
- Stackpointer, Programmzähler, Framepointer (falls vorhanden) dürfen
nicht verändert werden.
- Register, die vom Compiler für register-Variable benutzt werden,
dürfen nicht verändert werden.
- Alle anderen Prozessorregister stehen zur freien Verfügung.
- Weitere Ausnahmen sind dem jeweiligen Compiler-Manual zu entnehmen.
Stichworte: 'register allocation', 'calling conventions', ...
'Nicht verändern' bedeutet hier: Der Registerinhalt (ausgenommen PC!)
nach dem inline-Statement muß gleich dem Inhalt davor sein. Was
zwischendurch damit gemacht wird, ist dem Programmierer überlassen.
Das Verändern von nicht fest belegten Registern ist deswegen kein
Problem, weil inline-Ausdrücke Statements sind - also nicht in andere
Statements eingebaut werden können und der Zustand der nicht fest
belegten Register zwischen zwei Statements undefiniert ist.
Der Optimierer kann und wird von der Regel, daß der Registerzustand
zwischen zwei Statements undefiniert ist, abweichen.
Er ist jedoch schlau genug, inline-Statements in seine
Registerallokation mit einzubeziehen - man braucht sich darum also nicht
zu kümmmern. inline-Statements werden vom Optimierer nicht verändert.
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.