Forum: Mikrocontroller und Digitale Elektronik Fill-Direktive für AVR Assembler?


von Tobias A. (tadolph)


Lesenswert?

Hallo zusammen,

ich möchte den Programmspeicher über einen bestimmten Bereich mit einem 
Befehl füllen. Also z.B. 100 mal "rjmp PC".

Ich weiß, dass es bei Microchips MPASM für genau diesen Fall eine 
Fill-Direktive gibt:

fill <expr>, <count>
also z.B. fill (goto $), 100

Ich habe die Hilfe für den AVR Assembler durchsucht, aber nichts 
vergleichbares gefunden.

Hat jemand eine Idee, wie man dieses Problem mit dem AVR Assembler lösen 
kann?

Viele Grüße
Tobias

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

mit .DD kann man immerhin 4 Byte auf einmal füllen, so habe ich 
unbenutzte Pointer der Interrupt-Tabelle im Mega644 mit "rti nop" 
gefüllt

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Wozu genau soll das denn gut sein? Es gibt die Copy@Paste Funktion, 
einfach oft genug ausführen...

von Severino R. (severino)


Lesenswert?

Travel Rec. wrote:
> Wozu genau soll das denn gut sein? Es gibt die Copy@Paste Funktion,
> einfach oft genug ausführen...

Gewisse Hersteller empfehlen, ungenutzten Programmspeicher mit GOTO $, 
also einem Sprung auf "sich selber" zu füllen. Wenn das Programm 
aufgrund einer Störung in einen unbenutzten Bereich springt, bleibt es 
wenigstens hängen und macht dann nicht irgend einen Mist. Wenn dann auch 
noch der Watchdog eingeschaltet ist, gibt es wenigstens einen sauberen 
Reset.

Das mit Copy & Paste (& = and, und nicht @ = at) klappt nicht, da man 
sonst genau abzählen müsste, wieviele Zeilen einzufügen wären, und 
sobald das Programm eine Instruktion länger wird, müsste man am Schluss 
einen GOTO $ manuell entfernen.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

>Gewisse Hersteller empfehlen, ungenutzten Programmspeicher mit GOTO $,
>also einem Sprung auf "sich selber" zu füllen. Wenn das Programm
>aufgrund einer Störung in einen unbenutzten Bereich springt, bleibt es
>wenigstens hängen und macht dann nicht irgend einen Mist.

AVRs benötigen diesen "Trick" nicht, da wenn sie auf ungenutzten 
Programmspeicher springen, sie hier $FF vorfinden und weiterlaufen 
(PC+1), bis sie wieder auf programmierten Code treffen. Dies kann im 
Extremfall ein kompletter Durchlauf durch das gesamte Flash sein, 
woraufhin der AVR wieder bei Vektor $0000 ankommt, was einem RESET 
entspricht.

von Severino R. (severino)


Lesenswert?

Travel Rec. wrote:
> woraufhin der AVR wieder bei Vektor $0000 ankommt, was einem RESET
> entspricht.

Bist Du sicher, dass ein GOTO $0000 dasselbe wie ein Watchdog-Reset ist?

von Sebastian (Gast)


Lesenswert?

Es ist zumindest ein Reset, der den Controller über die Initialisierung 
in einen definierten Zustand versetzen sollte.

Wird eigentlich bei jedem Programmieren der ganze Flash geschrieben, 
oder bleiben Programmreste im Flash, wenn das Programm von einer Version 
zur nächsten kleiner geworden ist?

Aufpassen, wenn Daten im Controller liegen. Die würden dann ja auch als 
Code interpretiert und sonstwas verursachen. Aber vor einem Datenblock 
könnte mann ja zumbeispiel auf $0000 springen lassen.

Oder man programmiert einfach sauber ;-)

Sebastian

von Tobias A. (tadolph)


Lesenswert?

Hallo und erstmal danke für die schnellen Antworten.

Ich möchte damit alle nichtbenutzten Programmspeicherteile mit einem 
rjmp PC belegen.

Das Problem ist, wenn man einen Stuck-At Fehler im Programmcounter 
annimmt.

Wenn man zur nächsten Stelle (PC+1) springt, ist damit ja nicht 
unbedingt sichergestellt, dass man überhaupt wieder bei org'0000' 
ankommt, oder? Dafür müßte ja nur ein einziges Bit fest auf eins sein.

Bei einem "rjmp PC" würde man halt an der aktuellen Stelle bleiben. Ein 
"definierter Neustart" würde nichts bringen, weil man nicht mehr 
sicherstellen kann, welche Programmteile überhaupt noch ausgeführt 
werden, oder ob diese überhaupt noch sinnvollen Code ergeben. Bei einen 
Stuck-At im LSB fürde nur noch jeder zweite Befehl ausgeführt, dafür 
aber gleich zweimal hintereinander...  Oder liege ich dabei falsch?

Copy&Paste ginge natürlich, ist aber doch sehr umständlich damit den 
gesamten Speicher zu füllen. Übersichtlich ist das dann auch nicht mehr.

Viele Grüße
Tobias

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Es macht keinen Sinn den Speicher zu befüllen. Nach dem löschen ist der 
Speicher 0xFF (nix mit einem Bit gesezt oder so) wenn der AVR darauf 
trifft führt dies zu einem Reset. Auch wenn das gewisse hersteller 
empfehlen, ATMEL tut es meines Wissens nicht...

Und der Reset IST ein definierter Neustart, weil dort der Prozessor auch 
anfängt wenn du das Program das erste mal startest.

Du kannst dir natürlich ein Skript schreiben, welches die HEX Datei bis 
zur Größe des AVRs mit sowas vollschreibt...

von Benedikt K. (benedikt)


Lesenswert?

Läubi Mail@laeubi.de wrote:
> Nach dem löschen ist der
> Speicher 0xFF (nix mit einem Bit gesezt oder so) wenn der AVR darauf
> trifft führt dies zu einem Reset.

Nein, wie oben schon geschrieben, ist 0xFF ein gültiger Befehl (ich 
glaube and r7 oder sowas), der auch ausgeführt wird. Falls aber bis ganz 
nach oben nix anderes mehr im Speicher steht, dann kommt der PC 
irgendwann auf Adresse 0, da er überläuft.

> Und der Reset IST ein definierter Neustart, weil dort der Prozessor auch
> anfängt wenn du das Program das erste mal startest.

Der Reset ja, aber ein Sprung auf Adresse 0 ist kein Reset !

von Michael U. (amiga)


Lesenswert?

Hallo,

ein rjmp 0x0000 ist kein Reset und damit durchaus nicht unbedingt 
definiert.

Nur wenn wirklich alle Register im Programm auf definierte Werte gesetzt 
werden und man sich nirgens auf die Reset-Werte verläßt (IO sind 0x00 
usw.) kommt es einen Neustart nahe.
Spätestens wenn ein IRQ in den Kram reinschlägt (der ist ja weiter aktiv 
im Gegensatz zum Reset) wird es zufällig.

Gruß aus Berlin
Michael

von Sebastian (Gast)


Lesenswert?

Wie wärs ans Ende des Programms (per Assambler-direktive festlegen) eine 
Endlosschleife zu setzen? Der Watchdog holt ihn dann raus und macht 
einen Reset. Der Watchdog-Reset ist doch ein echter, oder? Bis zu dieser 
Endlosschleife wird nur 0xFF ausgeführt, was meines Wissens nach nop 
entspricht.

Kann bitte noch jemand was zu meinem Einwurf von vorhin sagen: Wird der 
Flash überhaupt wieder 0xFF geschrieben, wenn sich das Programm 
verkleinert, oder bleiben dann überreste der alten Programmversion als 
Leiche im Flash? Dann funktioniert oben gesagtes jedenfalls nicht so 
einfach.

Allerdings gehen wir hier immer von einem Softwarefehler aus, der dafür 
sorgt, dass der µC Code ausführt, wo eigentlich kein Code steht. Tobias 
geht aber von einem Hardwarefehler aus (z.B. Stuck-at im PC). Gegen 
soetwas hilft ja denk ich auch kein Reset (vielleicht Spannungs-aus?), 
weshalb er den Controller zum nichtstun zwingen will, wenn er irgendwie 
zufällig mal in den freien Flash-bereich gesprungen ist. Quasi zur 
Schadensbegrenzung.
Oder hab ich das jetzt falsch verstanden?

Gruß,
Sebastian

von Tobias A. (tadolph)


Lesenswert?

Hallo Sebastian,

> Kann bitte noch jemand was zu meinem Einwurf von vorhin sagen: Wird der
> Flash überhaupt wieder 0xFF geschrieben, wenn sich das Programm
> verkleinert, oder bleiben dann überreste der alten Programmversion als
> Leiche im Flash? Dann funktioniert oben gesagtes jedenfalls nicht so
> einfach.

Also ich weiß es nicht mit Sicherheit. Ich programmiere aber auch immer 
über die Auto-Funktion, da kann man den Chip ja vorher immer löschen 
lassen, dann stehen da auf jeden Fall FF's.

> Allerdings gehen wir hier immer von einem Softwarefehler aus, der dafür
> sorgt, dass der µC Code ausführt, wo eigentlich kein Code steht. Tobias
> geht aber von einem Hardwarefehler aus (z.B. Stuck-at im PC). Gegen
> soetwas hilft ja denk ich auch kein Reset (vielleicht Spannungs-aus?),
> weshalb er den Controller zum nichtstun zwingen will, wenn er irgendwie
> zufällig mal in den freien Flash-bereich gesprungen ist. Quasi zur
> Schadensbegrenzung.
> Oder hab ich das jetzt falsch verstanden?

Nein, das hast du absolut richtig verstanden. Wenn der Controller einmal 
einen nicht dafür vorgesehenen Programmteil erreicht hat, soll er stehen 
bleiben. Eben weil er diesen Bereich laut Software nie erreichen sollte. 
Also muß ein Problem mit der Hardware vorliegen. Dann versuche ich den 
Schaden zu begrenzen, damit der Controller nicht noch irgendwelchen 
Quatsch macht.

Ein Reset hilft mir bei einem Hardwarefehler leider nicht weiter.

Viele Grüße
Tobias

von Tobias A. (tadolph)


Lesenswert?

Läubi Mail@laeubi.de wrote:
> Du kannst dir natürlich ein Skript schreiben, welches die HEX Datei bis
> zur Größe des AVRs mit sowas vollschreibt...

Hmja, da hatte ich auch schon drüber nachgedacht. Das würde natürlich 
gehen. Ich lasse allerdings auch einen CRC über den gesamten FLASH 
laufen. Nachdem ich etwas verändert habe, lass ich einmal den Simulator 
laufen. Der CRC stellt fest, dass ein flascher CRC Wert rauskommt. Den 
schau ich nach, und hinterlege dann entsprechend den neuen CRC Wert. 
Dann lass ich nochmal neu assemblieren und dann läuft das ganze.

Wenn ich dann nochmal mit einem Skript drübergehe stimmt der CRC nicht 
mehr. Hmm, aber ich könnte ja mit dem Skript auch noch direkt den CRC 
neu bestimmen.

Ja das wäre schon eine Lösung. Jedoch eine sehr umständliche und 
vielleicht auch wieder fehleranfällige Methode.

Ich hatte gehofft, dass es da eine einfachere Lösung gibt.

Viele Grüße
Tobias

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
Noch kein Account? Hier anmelden.