UART 16550: FIFOs aktiv + RLS-IRQ & RDA-IRQ

Gast #2124718
Lesenswert?
• ▲
▼
Hi,

ich beschäftige mich grad mit dem UART 16550.
http://www.national.com/ds/PC/PC16550D.pdf

Der UART unterstützt einen ReceiveLineStatus-Interrupt, der ausgelöst 
wird, wenn das auszulesende Byte im FIFO einen Fehler hat, 
beispielsweise einen Paritätsfehler. Der RLS-IRQ hat die höchste 
Priorität (wenn freigeschalten).

Der RDA-Interrupt wird ausgelöst, wenn eine einstellbare Anzahl an Bytes 
im Rx-FIFO erreicht ist. Dieser IRQ ist gedacht, um die Daten blockweise 
aus dem FIFO zu holen und sich somit byteweises Auslösen der 
Interrupt-Service-Routine zu sparen.

Ich stell mir grad die Frage ob es Sinn macht, den RLS-IRQ und RDA-IRQ 
gemeinsam zu verwenden, bzw. ob das überhaupt möglich ist. Wenn 
beispielsweise der RDA-IRQ ausgelöst wird und die Daten als Block 
abgeholt werden, also in einer Schleife innerhalb der ISR, kann der 
RLS-IRQ zwar auftreten, wird aber nicht bedient, weil ja der RDA-Teil 
der ISR abgearbeitet wird, und das fehlerhafte Byte enthalten ist.

Das heisst dann eigentlich, dass das Handling für Paritätsfehler 
etc.muss in den RDA-Teil der ISR und den RLS-IRQ kann man ignorieren. 
Der RLS-IRQ macht nur Sinn, wenn man den UART so einstellt, dass er 
bereits bei einem einzigen Byte im Rx-FIFO den RDA-IRQ auslöst. Oder 
sehe ich etwas falsch?

Ich möcht nur sicher sein, dass ich's richtig verstanden hab und somit 
die ISR klein und einfach halten kann :)

Ralf
Gast #2124720
Lesenswert?
• ▲
▼
Ralf schrieb:
> Der RLS-IRQ macht nur Sinn, wenn man den UART so einstellt, dass er
> bereits bei einem einzigen Byte im Rx-FIFO den RDA-IRQ auslöst. Oder
> sehe ich etwas falsch?

Es ist umgekehrt. Wenn nur ein Byte kommt und das einen Fehler hat, 
kommt kein FIFO Interrupt, der RLS schon.
Ich würde beide scharf schalten, und in der Service-Routine die Status 
Bits abarbeiten, bis alle erledigt sind. Was man tut, wenn z.B. ein 
Parityfehler aufgetreten ist, hängt von deiner Anwendung ab.

MfG Klaus
Gast #2124722
Lesenswert?
• ▲
▼
Hi Klaus,

> Es ist umgekehrt. Wenn nur ein Byte kommt und das einen Fehler hat,
> kommt kein FIFO Interrupt, der RLS schon.
Okay, das stimmt. Aber wenn das Byte in einem Block enthalten ist, 
bemerk ich's auch erst im RDA-Teil der ISR.

> Ich würde beide scharf schalten, und in der Service-Routine die Status
> Bits abarbeiten, bis alle erledigt sind. Was man tut, wenn z.B. ein
> Parityfehler aufgetreten ist, hängt von deiner Anwendung ab.
Mmmh, okay, ich glaub ich muss mir mal ein Flussdiagramm zeichnen und 
schauen, was rauskommt :)

Ralf
Gast #2124724
Lesenswert?
• ▲
▼
Ralf schrieb:
> Mmmh, okay, ich glaub ich muss mir mal ein Flussdiagramm zeichnen und
> schauen, was rauskommt :)

Gute Idee. Bei komplexen Bausteinen, die mehrere Interruptquellen, aber 
nur einen Vector haben, baue ich einen Loop über alle Statusbits und 
arbeite sie ab, bis alle aus sind. Wenn man das FIFO ausgelesen hat, ist 
möglicherweise schon ein neues Byte da, das kann man gleich mit 
erledigen. Bei FIFOs ein Timeout nicht vergessen, sonst bleibt 
möglicherweise etwas stecken, das erst bei der nächsten Übertragung raus 
kommt.

MfG Klaus
Gast #2124726
Lesenswert?
• ▲
▼
Klaus schrieb:
> Bei komplexen Bausteinen, die mehrere Interruptquellen, aber
> nur einen Vector haben, baue ich einen Loop über alle Statusbits und
> arbeite sie ab, bis alle aus sind.
Okay, das hätte ich eben im RDA-Teil gemacht, um die Fehler zu erkennen.

> Wenn man das FIFO ausgelesen hat, ist möglicherweise schon ein neues Byte
> da, das kann man gleich mit erledigen.
Meine Schleife liest den FIFO solange aus, wie das RDA-Flags des 
LineStatus-Registers gesetzt ist.

> Bei FIFOs ein Timeout nicht vergessen, sonst bleibt möglicherweise etwas
> stecken, das erst bei der nächsten Übertragung raus kommt.
Du meinst den CharacterTimeOut-Interrupt (CTI)?

Ralf
Gast #2124733
Lesenswert?
• ▲
▼
> Ich kenn jetzt den 16550 nicht so, aber das klingt gut.
:) Der CTI wird ausgelöst, wenn sich Daten im Rx-FIFO befinden und sich 
über eine gewisse Zeit nichts mehr im FIFO getan hat, weder auslesen 
noch empfangen.
Das soll dazu dienen, empfangene Blöcke die nicht dem eingestellten 
Trigger-Level entsprechen, also kleiner sind, auslesen zu können.

Ralf

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.