Hi, was macht eigentlich ein ARM-Prozessor, wenn er den Opcode 0xFFFFFFFF im Flash findet? Und was bei 0x00000000? Macht es einen Unterschied, ob der ARM im Thumb Modus ist oder nicht? Was sollte man sinnvollerweise ins Flash schreiben, wenn man einen (Soft-) Reset auslösen möchte, falls der Programm Counter (warum auch immer) in einen "leeren" Flash-Bereich springt?
Thumb: 0000 left shift by R0 into R0 -> NOP -> Bus-/Hardfault am FlashEnde FFFF der 2. Teil einer Befehlssequenz "Branch mit 23Bit offset" vermutlich per Hardfault beende. ARM: 00000000 illegale Bitkombination -> Hardfault FFFFFFFF SWI Never -> NOP -> Bus-/Hardfault am FlashEnde -> endet immer in einer Exception und scheint vorher höchsten Zyklen zu verbrauchen, aber nichts Böses anzustellen.
Ok, danke. Naja, das durch den Flash durch-"NOPpen" will ich genau vermeiden. Könnte ja gut sein, dass da noch Code oder Daten kommen. Damit wäre das Verhalten dann komplett undefiniert. Ich würde den Linker gerne anleiten, die leeren Flash-Bereiche mit etwas sinnvollem vollzuschreiben, das am besten direkt einen Reset auslöst oder zumindest auf Adresse 0 springt. Eine Sequenz scheidet aus, falls der Controller da mittenrein springt. Was wäre da geeignet?
Na bei Thumb einfach "leeren Flash" oder FF. Bei ARM wird das schwieriger, weil F in den obersten 4 Bit (condition code) immer "Never" bedeutet. Aber in μC-Umfeld ist ARM-Code im Flash ja eher selten.
Du gehst also davon aus, daß der an beliebige Stellen des Flashes springt, und da soll dann hinterher etwas definiertes wie z.B. ein Reset ausgeführt werden, korrekt? Ich würde sagen das ist ein Fall für einen Watchdog. Denn wenn Du schon davon ausgehst, daß der an beliebige Stellen im unbenutzten Teil des Flash springen kann, was soll ihn dann davon abhalten stattdessen an die von Deinem Code verwendeten Stelle zu springen? Ich sehe da keinen Unterschied. In Deinem normalen Code wirst Du nicht ständig Resets ausführen wollen. Nimm einen Watchdog und bau um den Rücksetzmechanismus dafür enge Plausibilitätstests ein. Wenn Du wirklich von beliebigen Sprüngen im Code ausgehst, könnte der theoretisch direkt an die Stelle mit dem Zurücksetzen des Watchdogs springen. Vermutlich könntest Du das mit der Memory Protection Unit nochmal extra sichern. Ich hab mich damit aber noch nicht im Detail beschäftigt. Evtl. hilft auch ein externer Watchdog oder 2 die sich gegenseitig überwachen.
Gerhard schrieb: > Was sollte man sinnvollerweise ins Flash schreiben, wenn man einen > (Soft-) Reset auslösen möchte, falls der Programm Counter (warum auch > immer) in einen "leeren" Flash-Bereich springt? Ich muß mich zurückhalten! Er macht nur das, was du ihm befiehlst. Also mach es.
Wenn der Programmzeiger in den luftleeren Raum springt, crasht das Programm sowieso. Es ist völlig egal was der Prozessor damit macht. Sei froh, wenn Du eine Exception bekommst, damit kannst Du immerhin einen Reset auslösen oder die gesteuerte Schaltung in einen sicheren Zustand versetzen. Unter Windoofs ist das diese berühmte allgemeine Schutzverletzung.
Gerhard schrieb: > Ich würde den Linker gerne anleiten, die leeren Flash-Bereiche mit etwas > sinnvollem vollzuschreiben, das am besten direkt einen Reset auslöst > oder zumindest auf Adresse 0 springt. > ... > Was wäre da geeignet? Warum fragst du dann, was der Prozessor bei 0xFFFFFFFF oder 0x00000000 anstellt, wenn du ganz was anderes wissen möchtest?
Gerhard schrieb: > Was sollte man sinnvollerweise ins Flash schreiben, wenn man einen > (Soft-) Reset auslösen möchte, falls der Programm Counter (warum auch > immer) in einen "leeren" Flash-Bereich springt? Nett wäre ein Breakpoint-Befehl. Normalerweise ergibt das eine Exception oder man landet im Debigger (jedenfalls beim Cortex M3). Angeblich gibt es auch offiziell undefinierte Opcodes: https://stackoverflow.com/questions/16081618/programmatically-cause-undefined-instruction-exception
Carl D. schrieb: > FFFFFFFF SWI Never -> NOP -> Bus-/Hardfault am FlashEnde In ARMv3 und ARMv4 steht cond=1111 nicht mehr für NEVER, sondern für UNPREDICTABLE. Ab ARMv5 werden damit Befehle ohne Bedingung codiert (z.B. VFP), wobei der Code 0xFFFFFFFF UNDEFINED ist.
:
Bearbeitet durch User
Eine rhetorische Frage : Wie macht man das, dass der Controller in einen unprogrammierten Bereich springt ? Weshalb sollte man/er das tun ?
Sapperlot W. schrieb: > Eine rhetorische Frage : Wie macht man das, dass der Controller in einen > unprogrammierten Bereich springt ? Man zerlegt sich die auf dem Stack gesicherte Return-Adresse durch Pufferüberlauf.
Ich würde mein Hirnschmalz lieber in ein stabiles, verlässliches Programm stecken als in die smarte Rettung aus einem schampig hingerotzten.
Markus F. schrieb: > Ich würde mein Hirnschmalz lieber in ein stabiles, verlässliches > Programm stecken als in die smarte Rettung aus einem schampig > hingerotzten. Genau, und wenn man niemals Fehler macht, braucht man auch keine zeitraubenden Tests.
Dann muesste man sich ja nur die Reboot-Zeit irgendwo hin schreiben. Unprogrammiertes Flash fuehrt eh zu einem Reboot.
Wie man das hinkriegt? push müll ret oder function crash push a push b [..] pop c pop b pop a ret Das war's dann. Oder es führt zum Festhängen des Controllers falls der Watchdog deaktiviert ist. Aber hast trotzdem Recht, insofern nichts an der Schaltung Schaden nimmt, gibts dann einen User-getriggerten Reset. Das Problem ist ja auch, daß der Controller irgendwann den Stack am Ende des RAM ausführen möchte wenn keine exception ausgelöst wird. Das führt dann wieder zu undefiniertem Verhalten. Man könnte sich behelfen, wenn man den kompletten freien Flash mit jmp reset oder jmp what_to_do_if_program_crashed oder so vollschreibt. Dann bewirkt ein Einspringen in freie Flash-Bereiche z.B. einen sofortigen Reset.
Wie wahrscheinlich ist es denn, daß die CPU bei einem Sprung an eine zufällige Adresse überhaupt im Programmflash landet? Das Flash mit seinen paar (hundert) kB ist doch verschwindend klein gegenüber dem 4GB-Adressraum.
Hm die Frage wäre ob Du dann eine Exception bekommst weil die CPU weiß, daß an dieser Stelle "nicht angeschlossen" ist... Ansonsten sind das einfach unbelegte Adressleitungen, sprich Du landest wieder irgendwo im vorhandenen Speicher, der durch die belegten Adressleitungen angesprochen wird.
Natürlich wird die Software ordentlich entwickelt und getestet. Und es gibt auch einen Watchdog. Aber es verstößt gegen die Grundregeln der Kunst, eine (fast) kostenlose Maßnahme NICHT zu treffen. Ich habe beim Reverse-Engineering auch schon 0xDEADCODE oder 0xDEADBEEF in unbenutzten Blöcken gefunden statt 0xFFFFFF. Ohne zu wissen, zu welchen Instruktionen das jetzt disassemblieren würde und ob es eine gute Wahl war. Es zeigt aber, dass jemand das Linker-File angefasst und sich Gedanken gemacht hat.
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.