Wann wird eine Variable zurueckgeschrieben / volatile

Persönliche Seite #4293712
Lesenswert?

Hallo alle zusammen,

ich habe da mal eine, hoffentlich interessante, Frage.

Nehmen wir an, ich habe zwei Interrupts mit unterschiedlichen 
Prioritaeten.
ISR_A hat eine hoehere Prioritaet als ISR_B. ISR_A kann ISR_B 
unterbrechen.

ISR_A greift schreibend auf eine globale Variable eines anderen Moduls 
zu (Ueber die Systemarchitektur bitte ich hinwegzusehen, darum geht es 
nicht).

ISR_B greift nur lesend auf diese Variable zu.

Es ist nicht schlimm, wenn ISR_B einen veralteten Wert der Variable 
bekommt. Sollte es aber irgendwann mal mitbekommen das ISR_A den Wert 
geaendert hat.

Muss die Variable volatil sein?

Die Variable ist eine Struktur, kann also wahrscheinlich nicht in den 
Registern behalten werden. Wohl aber eines ihrer Member.

Wie macht der gcc das? ISR wird aufgerufen, variable wird in Register 
geholt, geschrieben, gelsen, was weiss ich und bevor die ISR verlassen 
wird wird dann zurueck in den Speicher geschrieben?!

Ich vermute es kommt auf den Einzelfall an und im Zweifel wird ein Blick 
ins Assembler Listing noetig sein, oder pauschal als volatil 
deklarieren.

Beste Gruesse
Christopher
Gast #4293718
Lesenswert?

beim beenden wird sie auf jeden Fall zurückgeschrieben.

Wenn wirklich nur 2 ISR beteiligt sind, braucht man kein Volatile. Aber 
das die 2. ISR sinnvolle Daten bekommt ist nur bei 8bit variablen 
sichergestellt. Bei größeren musst du davon ausgehen, das Operationen 
nicht Atomar sind.
Persönliche Seite #4293735
Lesenswert?

Peter II schrieb:
> beim beenden wird sie auf jeden Fall zurückgeschrieben.
Danke dafuer schonmal, das war auch meine Vermutung.

> Wenn wirklich nur 2 ISR beteiligt sind, braucht man kein Volatile.
es sind noch ein Paar mehr, aber die interessieren sich nicht fuer die 
Variable

> Aber
> das die 2. ISR sinnvolle Daten bekommt ist nur bei 8bit variablen
> sichergestellt.
Vorausgesetzt man ist auf einer 8bit Maschine unterwegs, oder? Das 
bringt mich zu einer neuen Frage. Wenn man eine Maschine mit 32bit 
Datenbus hat und eine Variable auf 32bit aligned ist, dann ist der 
Zugriff darauf auch atomar, oder?

> Bei größeren musst du davon ausgehen, das Operationen
> nicht Atomar sind.
Die Lesezugriffe aus ISR_B sind atomar gehalten. Aber danke fuer den 
hinweis. ISR_A hat keine Interruptsperre, da diese nicht von ISR_B 
unterbrochen werden kann.

LG
Christopher
Gast #4293737
Lesenswert?

Peter II schrieb:
> Wenn wirklich nur 2 ISR beteiligt sind, braucht man kein Volatile.

Volatile hat doch aber auch den Zweck, dass der Compiler nicht meint 
Code optimieren zu können weil sich der Inhalt der Variable nicht 
geändert haben kann.
Insofern braucht man IMMER volatile wenn mindestens eine ISR im Spiel 
ist, hier vor allem weil der höher priorisierte Interrupt den 
niedrigeren unterbrechen und die Variable ändern kann.

Korrigiert mich falls ich falsch liege.


Creepy wird es wenn es multicore Rechner sind, die pro core einen 
eigenen Cache haben.
Da muss sogar in Hochsprachen wie Java volatile benutzt werden, wenn die 
Variable in mehreren Threads geändert werden kann. Ansonsten kann es 
vorkommen, dass Thread 2 einen veralteten Wert der Variable in seinem 
Cache liegen hat und benutzt, den Thread x schon geändert hatte.
Gast #4293748
Lesenswert?

Christopher B. schrieb:
>> Aber
>> das die 2. ISR sinnvolle Daten bekommt ist nur bei 8bit variablen
>> sichergestellt.
> Vorausgesetzt man ist auf einer 8bit Maschine unterwegs, oder? Das
> bringt mich zu einer neuen Frage. Wenn man eine Maschine mit 32bit
> Datenbus hat und eine Variable auf 32bit aligned ist, dann ist der
> Zugriff darauf auch atomar, oder?

würde ich pauschal nicht sagen. Das ist dann wirklich abhängig von der 
Hardware.

> Volatile hat doch aber auch den Zweck, dass der Compiler nicht meint
> Code optimieren zu können weil sich der Inhalt der Variable nicht
> geändert haben kann.
> Insofern braucht man IMMER volatile wenn mindestens eine ISR im Spiel
> ist, hier vor allem weil der höher priorisierte Interrupt den
> niedrigeren unterbrechen und die Variable ändern kann.
ihm ist aber egal, ob er den alten stand noch liest. Und nach dem eine 
ISR neu aufgerufen wird muss sie eh aus dem Speicher gelesen werden.

Volatile würde also nur bewirken, das sich innerhalb der Ausführung der 
ISR die Variabel soft ändern kann - das braucht er aber nicht.
Gast #4293752
Lesenswert?

Peter II schrieb:
> ihm ist aber egal, ob er den alten stand noch liest. Und nach dem eine
> ISR neu aufgerufen wird muss sie eh aus dem Speicher gelesen werden

Richtig, wobei das eine sehr zweifelhaftes Design ist nur um sich ein 
Volatile (und den geringen Overhead, der daraus resultiert) zu sparen.

Das weiss 3 Monate nach dem Schreiben des Codes nicht mal der TO mehr.
Sowas ergibt dann unwartbarer Code.
Gast #4293762
Lesenswert?

Der Andere schrieb:
> Richtig, wobei das eine sehr zweifelhaftes Design ist nur um sich ein
> Volatile (und den geringen Overhead, der daraus resultiert) zu sparen.

sehe ich nicht so. Eine ISR sollte so schnell wie möglich sein, da kann 
ein volatile schon zu viel sein.

Und das verhalten ist ja definiert, damit kann man sich auch darauf 
verlassen.
Moderator Persönliche Seite #4293799
Lesenswert?

Peter II schrieb:
> Volatile würde also nur bewirken, das sich innerhalb der Ausführung der
> ISR die Variabel soft ändern kann - das braucht er aber nicht.

Ich würde:

1. die Variable volatile machen
2. In der ISR die volatile Variable in eine lokale Variable kopieren
3. Mit der lokalen Variablen weiterarbeiten

Dann sollte eine Änderung während der ISR durch eine zweite ISR egal 
sein.
#4293800
Lesenswert?

Christopher B. schrieb:

> Es ist nicht schlimm, wenn ISR_B einen veralteten Wert der Variable
> bekommt. Sollte es aber irgendwann mal mitbekommen das ISR_A den Wert
> geaendert hat.

Was genau ist darunter zu verstehen?
Insbesondere der Teil 'sollte es aber irgendwann mitbekommen' ist 
interessant. Was verstehst du darunter?
Wartet die ISR B darauf, dass die ISR A den Wert ändert?

> Muss die Variable volatil sein?

Im Zweifelsfall: ja
Denn dann laufen die Dinge genau so, wie du sie hingeschrieben hat und 
keine Optimierung kann dir da reinpfurzen.
#4293808
Lesenswert?

@Christopher B. (chrimbo)

>ISR_A hat eine hoehere Prioritaet als ISR_B. ISR_A kann ISR_B
>unterbrechen.

>ISR_A greift schreibend auf eine globale Variable eines anderen Moduls
>zu (Ueber die Systemarchitektur bitte ich hinwegzusehen, darum geht es
>nicht).

>ISR_B greift nur lesend auf diese Variable zu.

Ob nur lesen/schreiben ist egal, man brauch IMMER volatile und IMMER 
einen ATOMAREN Zugriff, hier auch in ISR_B. In ISR_A muss er nicht 
atomar sein bzw. er ist es automatisch, da ISR_A durch nichts anderes 
unterbraochen werden kann. Siehe Interrupt.

>geholt, geschrieben, gelsen, was weiss ich und bevor die ISR verlassen
>wird wird dann zurueck in den Speicher geschrieben?!

Sicher, weil es praktisch keinen Sinn macht, Teile einer Struktur lokal 
zu speichern. Absolut sicher ist es nur mit volatile. Der Zugriff 
erfolgt exakt dort, wo er im Programm steht, nicht erst am Ende der ISR.

>Ich vermute es kommt auf den Einzelfall an und im Zweifel wird ein Blick
>ins Assembler Listing noetig sein,

Nein.

>oder pauschal als volatil
>deklarieren.

Ja.
Gast #4293816
Lesenswert?

Falk B. schrieb:
> Ob nur lesen/schreiben ist egal, man brauch IMMER volatile und IMMER
> einen ATOMAREN Zugriff, hier auch in ISR_B. In ISR_A muss er nicht
> atomar sein bzw. er ist es automatisch, da ISR_A durch nichts anderes
> unterbraochen werden kann. Siehe Interrupt.

warum volatile? E
s gibt keinen Grund dafür wenn sie die Variabel innerhalb von einem ISR 
Aufruf nicht ändern muss!

Bei Eintritt werden immer alle Variablen aus dem Ram geladen und beim 
Verlassen wieder zurückgeschrieben auch ohne Volatile.
Moderator Persönliche Seite #4293850
Lesenswert?

Peter II schrieb:
> Bei Eintritt werden immer alle Variablen aus dem Ram geladen und beim
> Verlassen wieder zurückgeschrieben auch ohne Volatile.

Ja, das schon. Aber wo ist garantiert, dass der in main() zugewiesene 
Wert tatsächlich schon in der globalen Variablen gespeichert ist? 
Grundsätzlich kann der Compiler die Variable unendlich lang in einem 
Register halten. Den Einsprung in die ISR() sieht er ja nicht.
#4293855
Lesenswert?

@ Peter II (Gast)

>warum volatile?

Schrieb ich das nicht bereits?

> E
>s gibt keinen Grund dafür wenn sie die Variabel innerhalb von einem ISR
>Aufruf nicht ändern muss!

Wir reden von einer UNTERBRECHENBAREN ISR. Ausserdem geht es bei 
volatile darum, dass ABSOLUT sichergestellt ist, dass KEINERLEI 
Optimierung mit lokalen Speicherbereichen vorgenommen wird. Das kann 
aber passieren, wenn die ISRs in verschiedenen .c Dateien liegen, welche 
getrennt übersetzt werden.

>Bei Eintritt werden immer alle Variablen aus dem Ram geladen und beim
>Verlassen wieder zurückgeschrieben auch ohne Volatile.

Nicht zwingend, auch wenn es zu 99,9% so ist! Ein agressiver Optimierer 
kann da Variablen lokal halten.
Gast #4293859
Lesenswert?

Frank M. schrieb:
> Ja, das schon. Aber wo ist garantiert, dass der in main() zugewiesene
> Wert tatsächlich schon in der globalen Variablen gespeichert ist?

es gibt keinen zugriff in der main!

> >Bei Eintritt werden immer alle Variablen aus dem Ram geladen und beim
> >Verlassen wieder zurückgeschrieben auch ohne Volatile.
> Nicht zwingend, auch wenn es zu 99,9% so ist! Ein agressiver Optimierer
> kann da Variablen lokal halten.

wo soll das lokal sein? Es gibt kein "Außerhalb" einer ISR.
Gast #4293861
Lesenswert?

Falk B. schrieb:
> Wir reden von einer UNTERBRECHENBAREN ISR. Ausserdem geht es bei
> volatile darum, dass ABSOLUT sichergestellt ist, dass KEINERLEI
> Optimierung mit lokalen Speicherbereichen vorgenommen wird. Das kann
> aber passieren, wenn die ISRs in verschiedenen .c Dateien liegen, welche
> getrennt übersetzt werden.

genau das ist auch gut so. Warum sollte man diese Optimierung auch mit 
volatile verhindern?

Sie kann doch während der ISR im Register gehalten werden.
#4293892
Lesenswert?

"ISR_A greift schreibend auf eine globale Variable eines anderen Moduls
zu"

Damit das bei getrennt compilierten ISRs SICHER funktioniert, braucht 
man volatile. Und explizit atomaren Zugiff in der niederpriorisierten 
ISR. Diese ist hier genauso zu betrachten wie ein Zugiff aus dem 
Nicht-ISR Programm in main().
Gast #4293897
Lesenswert?

Falk B. schrieb:
> "ISR_A greift schreibend auf eine globale Variable eines anderen Moduls
> zu"
>
> Damit das bei getrennt compilierten ISRs SICHER funktioniert, braucht
> man volatile. Und explizit atomaren Zugiff in der niederpriorisierten
> ISR. Diese ist hier genauso zu betrachten wie ein Zugiff aus dem
> Nicht-ISR Programm in main().

nein, braucht man nicht.

Es spielt keine rolle, ob die ISR sich verschachtelt aufrufen. Wie schon 
geschrieben:

>Bei Eintritt werden immer alle Variablen aus dem Ram geladen und beim
>Verlassen wieder zurückgeschrieben auch ohne Volatile.

nur das ist wichtig. Oder wenn die Änderung der Variable sofort in der 
anderen ISR ankommen soll, was hier aber nicht gefordert ist!

Das Atomar Problem ist davon getrennt.
Moderator Persönliche Seite #4293909
Lesenswert?

Peter II schrieb:
>>Bei Eintritt werden immer alle Variablen aus dem Ram geladen und beim
>>Verlassen wieder zurückgeschrieben auch ohne Volatile.
>
> nur das ist wichtig. Oder wenn die Änderung der Variable sofort in der
> anderen ISR ankommen soll, was hier aber nicht gefordert ist!

Nein, das ist Sch....lecht.

Nach Deiner Logik misslingt das:

Nennen wir die globale Variable foo. ISR_B liest nur die Variable, ISR_A 
beschreibt sie.

  1) ISR_B wird aufgerufen und benutzt foo mit dem Wert 42.
  2) ISR_A unterbricht ISR_B und schreibt in foo den Wert 22.
  3) ISR_A beendet sich, die 22 wird im RAM gespeichert
  4) ISR_B beendet sich, die noch-42 wird im RAM gespeichert.

Folge: im RAM steht wieder der alte Wert 42 statt der neue Wert 22.

Jedenfalls nach Deiner Logik. Nach meiner Logik findet 
glücklicherweise Schritt 4 in der Realität gar nicht statt. Aber nur, 
weil ISR_B die Variable nicht verändert. Glück gehabt!

Ich halte Deinen Vorschlag trotzdem für unsauber, ich würde volatile 
nehmen. Da weiß ich wenigstens, was passiert.
Persönliche Seite #4293931
Lesenswert?

Erstmal danke für die Antworten und ich erkenne an der Diskussion, dass 
es wohl wirklich nicht so klar ist und freue mich darueber zum Denken 
angeregt zu haben.

Karl H. schrieb:
> Was genau ist darunter zu verstehen?
> Insbesondere der Teil 'sollte es aber irgendwann mitbekommen' ist
> interessant. Was verstehst du darunter?
> Wartet die ISR B darauf, dass die ISR A den Wert ändert?
Nein, B wartet nicht auf A. Irgendwann ist natuerlich schwammig 
formuliert. Sagen wir im naechsten Aufruf von B.

VG
Christopher
#4293999
Lesenswert?

@ Frank M. (ukw) Benutzerseite

>Ich halte Deinen Vorschlag trotzdem für unsauber, ich würde volatile
>nehmen. Da weiß ich wenigstens, was passiert.

Eben. Wo liegt das Problem? Die volatile-Variable wird sicher nicht die 
Performance des Controllers in die Knie zwingen.
Gast #4294004
Lesenswert?

Frank M. schrieb:
> 1) ISR_B wird aufgerufen und benutzt foo mit dem Wert 42.
>   2) ISR_A unterbricht ISR_B und schreibt in foo den Wert 22.
>   3) ISR_A beendet sich, die 22 wird im RAM gespeichert
>   4) ISR_B beendet sich, die noch-42 wird im RAM gespeichert.
>
> Folge: im RAM steht wieder der alte Wert 42 statt der neue Wert 22.

Aufgabe Lesen!!!!

er schriebt nur ein einer ISR und in der anderen liest er.

Übrigens, lößt Volatile das Problem nicht. Denn es gibt auch hier das 
loch, das die Variabel kurz im Register ist.
Moderator Persönliche Seite #4294008
Lesenswert?

Frank M. schrieb:
> Nennen wir die globale Variable foo. ISR_B liest nur die Variable, ISR_A
> beschreibt sie.

Peter II schrieb:
> Aufgabe Lesen!!!!

Siehe oben, das steht sogar in meiner Annahme: "ISR_B liest nur die 
Variable". Wer kann da nicht lesen?

> er schriebt nur ein einer ISR und in der anderen liest er.

Jepp, und genau deshalb hast Du Glück, dass es so funktioniert. 
Deshalb wird Schritt 4 nicht ausgeführt!

Deine pauschale Aussage:

  "Bei Eintritt werden immer alle Variablen aus dem Ram geladen und
   beim Verlassen wieder zurückgeschrieben auch ohne Volatile."

stimmt nämlich nicht für ISR_B. Da wird nämlich nix zurückgeschrieben.
Moderator Persönliche Seite #4294040
Lesenswert?

Peter II schrieb:
> was hat das mit Glück zu tun, [...]

Du hast deshalb Glück, weil der avr-gcc so klug ist, unveränderte 
Variablen am Ende der ISR nicht wieder zurückzuschreiben. Es kann 
natürlich sein, dass man auf der Welt keinen so dummen C-Compiler 
findet, der das tatsächlich täte. Falsch wäre es aber nicht. Und deshalb 
nutzt Du hier eine Vermutung zum Verhalten des C-Compilers aus.

Deshalb: volatile und gut ist.

Innerhalb der ISR (auch ISR_B wegen Unveränderbarkeit) kann man ja den 
Wert der volatile-Variablen in eine lokale Variable kopieren und am Ende 
wieder zurück (was man in ISR_B natürlich tunlichst unterlässt). Damit 
macht man das dann selber und weiß dann auch, was da passiert.
#4294069
Lesenswert?

Peter II schrieb:
> Falk B. schrieb:
>> "ISR_A greift schreibend auf eine globale Variable eines anderen Moduls
>> zu"
>>
>> Damit das bei getrennt compilierten ISRs SICHER funktioniert, braucht
>> man volatile. Und explizit atomaren Zugiff in der niederpriorisierten
>> ISR. Diese ist hier genauso zu betrachten wie ein Zugiff aus dem
>> Nicht-ISR Programm in main().
>
> nein, braucht man nicht.

So, so.
Du bist also in der Lage dem Compiler vorschreiben zu können, welche 
Register er wie verwenden wird?

Dir ist schon bewusst, dass ein Compiler einen Schreibzugriff auf eine 
Variable auch komplett unter den Tisch fallen lassen kann, wenn er 
keinen Sinn darin sieht?

Ohne volatile ist noch nicht einmal garantiert, dass die ISR_A überhaupt 
die Variable beschreibt! Compiler sind ziemlich gut darin, Code der (aus 
seiner Sicht) keinen Effekt hat zu identifizeren und hinauszuwerfen.
Gast #4294074
Lesenswert?

Karl H. schrieb:
> So, so.
> Du bist also in der Lage dem Compiler vorschreiben zu können, welche
> Register er wie verwenden wird?
ja, denn am ende der ISR muss er sie in dem Ram schreiben ob er will 
oder nicht.


> Dir ist schon bewusst, dass ein Compiler einen Schreibzugriff auf eine
> Variable auch komplett unter den Tisch fallen lassen kann, wenn er
> keinen Sinn darin sieht?
kann er in diesem fall nicht. Sobald sie an einer anderen stelle im 
Quellcode verwendet wird.
#4294085
Lesenswert?

@ Peter II (Gast)

>> So, so.
>> Du bist also in der Lage dem Compiler vorschreiben zu können, welche
>> Register er wie verwenden wird?

>ja, denn am ende der ISR muss er sie in dem Ram schreiben ob er will
>oder nicht.

Soso, du kennst also gute, optimierende Compiler in und auswendig? Und 
die können auf keinen Fall Variablen in ISRs dauerhaft in Registern 
halten? Zumal reine Schreibzugriffe ohne Lesezugriff in der gleichen ISR 
bzw. gleiche Datei (= Übersetzungseinheit) einem WOM gleichkommen und 
ganz fix rausfliegen!

int a;

main()
{

a=1;

}

Ja das mal durch deinen Compiler mit aktiver Optimierung und staune ;-)
Gast #4294091
Lesenswert?

Falk B. schrieb:
> Soso, du kennst also gute, optimierende Compiler in und auswendig? Und
> die können auf keinen Fall Variablen in ISRs dauerhaft in Registern
> halten?

können sie nicht, wenn sie woanders verwendet werden. Dann die ISR wird 
beendet und es gibt keine "außerhalb" Kontext.

du scheinst es mit Threads zu verwechseln, die einen eigenen 
Threadkontext haben.



> Wenn sie nicht geändert wurde, dann muss er sie nicht ins RAM
> schreiben. Und genau das rettet Dir den Arsch.

nur löst volatile diesem Problem überhaupt nicht. Dafür muss man mit 
locks arbeiten.

selbst mit volatile geht

variabel+++

in 2 ISR schief.
Persönliche Seite #4294093
Lesenswert?

Frank M. schrieb:
> unveränderte
> Variablen am Ende der ISR nicht wieder zurückzuschreiben. Es kann
> natürlich sein, dass man auf der Welt keinen so dummen C-Compiler
> findet, der das tatsächlich täte. Falsch wäre es aber nicht.

nun ja, wenn er einen Schreibzugriff macht obwohl die Variable nur 
gelesen wird, dann waere das wohl falsch.

Wie dem auch sei. Danke an alle. Es wird jetzt als volatile deklariert 
um ganz sicher zu gehen ;-)

LG
Christopher
Moderator Persönliche Seite #4294095
Lesenswert?

Falk B. schrieb:
> int a;
>
> main()
> {
>
> a=1;
>
> }
>
> Ja das mal durch deinen Compiler mit aktiver Optimierung und staune ;-)

Sorry, Falk, auch wenn es Dir (und mir) nicht gefällt:
1
00000090 <main>:
2
  90:  81 e0         ldi  r24, 0x01  ; 1
3
  92:  90 e0         ldi  r25, 0x00  ; 0
4
  94:  90 93 01 01   sts  0x0101, r25
5
  98:  80 93 00 01   sts  0x0100, r24
6
  9c:  80 e0         ldi  r24, 0x00  ; 0
7
  9e:  90 e0         ldi  r25, 0x00  ; 0
8
  a0:  08 95         ret
Die 1 wird tatsächlich im RAM abgelegt, auch wenn sie weiterhin nicht 
genutzt wird. Da reicht es aus, dass sie global ist.

avr-gcc 4.7.2 getestet mit -Os und -O2. Bei -O2 steht sogar noch mehr 
Code drin.
#4294185
Lesenswert?

Hier mal ein Test, auch wenn er gegen mich ausgeht ;-)

Frage: Kann es sein, dass Compiler bzw. der avr gcc bei ISRs Ausnahmen 
bezüglich des Variablenzugriffs machen? Sprich, dass globale Variablen 
NIE lokal optimiert bzw. zwischengespeichert werden können?
Angehängte Dateien:
Gast #4294189
Lesenswert?

Falk B. schrieb:
> Frage: Kann es sein, dass Compiler bzw. der avr gcc bei ISRs Ausnahmen
> bezüglich des Variablenzugriffs machen? Sprich, dass globale Variablen
> NIE lokal optimiert bzw. zwischengespeichert werden können?

wo soll er sie den zwischenspeichern?

Meines wissen sind alle ISR aufrufe in einer

_MemoryBarrier

definiert. Vor und nach der ISR muss alles im Ram landen.
#4294205
Lesenswert?

@ Peter II (Gast)

>wo soll er sie den zwischenspeichern?

Keine Ahnung.

>Meines wissen sind alle ISR aufrufe in einer

>_MemoryBarrier

>definiert. Vor und nach der ISR muss alles im Ram landen.

Na zumindest nach der ISR. Vorher kann man ja nicht beeinflußen, dort 
läuft das Hauptprogramm an einer beliebigen Stelle ;-)

Einigen wir uns so.

Wenn NUR ISRs im Spiel sind kann man auf volatile Definition von 
globalen Variablen verzichten. Bei unterbrechenbaren (priorisierten) 
ISRs muss dennoch für atomaren Zugriff gesorgt werden.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren