mikrocontroller.net

Forum: PC-Programmierung UART 16550


Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend,

ich suche eine kurze Doku in deutsch, wo der UART 16550 beschrieben 
wird.
z.B. wieviel Register, Interrupt Handler usw.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da das die Standard-UART jedes PCs ist (ganz alte verwendeten noch den 
Fifo-losen Vorgänger 16450 bzw. 8250), dürfte sie in PC-Hardware-Büchern 
wie "Data Becker  - PC Intern" beschrieben sein.

Was willst Du erreichen?

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ja und zwar möchte ich das ganze Vorgehen für die ISR bzw COM 
Interrupt Handler beschreiben.
void __cdecl CommIntHandler(ETSINTREGS *pRegs);

void COM(void)
{
...
UartIntVecNum = EtsPicGetIRQIntNumber(UartIRQNum); 
// UartIntVecNum = 0x0C
SaveFlags = EtsSetInterruptFlag(ETS_DISABLEINTS);
EtsSaveInterruptHandler(UartIntVecNum, &CommDesc);
EtsSetInterruptHandler( UartIntVecNum, CommIntHandler); // set handler
...
}

//
// Saved register block passed to interrupt handlers registered
// with EtsSetInterruptHandler() and EtsSetExceptionHandler().
// These fields contain the register contents at the time of the
// interrupt.  The interrupt service routine can modify the
// values in the passed structure in order to change the user
// registers on return from the interrupt.
//
// Note:  The FS and GS registers are neither saved nor restored
// by the interrupt handler framework.  If a user interrupt handler
// wants to use either of these registers, it must preserve them itself!
//
typedef struct tagETSINTREGS
{
  DWORD   Ebp;                    // [00]
  DWORD   Eax;                    // [04]
  DWORD   Ebx;                    // [08]
  DWORD   Ecx;                    // [12]
  DWORD   Edx;                    // [16]
  DWORD   Esi;                    // [20]
  DWORD   Edi;                    // [24]
  DWORD   Gs;                     // [28]
  DWORD   Ds;                     // [32]
  DWORD   Es;                     // [36]
  DWORD   IntNum;                 // [40]
  DWORD   Ecode;                  // [44]
                           (Zero if int w/o error code)
  DWORD   Eip;                    // [48]
  DWORD   Cs;                     // [52]
  DWORD   Eflags;                 // [56]
} ETSINTREGS, *PETSINTREGS;

//---------------------------------------------------------------------- 
-------
// EtsSetInterruptHandler - Install a C function as an interrupt handler
//
//      This API installs a C function as an interrupt handler
//      for the specified interrupt.  The handler is entered as a normal
//      C function (__cdecl calling sequence) with interrupts disabled
//      and receives a pointer to the saved register set on the stack
//      as its argument.  The saved register set includes all general
//      purpose registers, DS, ES, and EFLAGS.  The FS and GS registers
//      are neither saved nor restored; if the handler alters them, it
//      must restore them itself before returning.  The handler
//      is expected to process the interrupt and may modify the
//      saved register set on the stack if wishes to
//      alter the context of the interrupted code.  When the handler 
function
//      returns, the saved registers are popped off the stack and
//      control returns to the interrupted code.
//
//      The return value from the function is TRUE if successful or 
FALSE
//      if an error occurs.
//
//---------------------------------------------------------------------- 
-------
BOOL    __cdecl EtsSetInterruptHandler(unsigned IntNumber,
               PETSINTHANDLER pHandler);

Ich verstehe da das genau Vorgehen nicht.
Was geschieht bei diesem Funktionsaufruf genau:
>>EtsSetInterruptHandler( UartIntVecNum, CommIntHandler);
Ist der CommIntHandler ein Zeiger auf einen bestimmten STACK?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Diese Definitionen und Funktionen haben nichts mit der UART zu tun, 
sondern scheinen von irgendeinem Betriebssystem zu sein - versuchst Du 
Dich da gerade mit dem Win32 DDK?

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist ein Board mit einem ELAN-SC400 Prozessor von AMD.
Ich tue mich sehr schwer mit dem Beschreiben der UART und dem COM 
Interrupt Handler.

Autor: Mark Schmitd (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab mal das ganze in ein Flussdiagramm dargestellt.
Dies ist die initialisierung des Interrupt Handlers für COM1.
Stimmt dies so?

Autor: rene (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicht ganz.
Ich hab da noch aus den DOS Zeiten.
http://www.ibrtses.com/turbopascal/stringdriver.html

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was meinst du mit "nicht ganz"?
Ich weiss nicht wie ich das ganz Beschreiben(Flussdiagramm) soll?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was auch immer das da sein soll, das hat nach wie vor nichts mit der 
UART zu tun.

Warum im Interrupthandler der Interruptcontroller befummelt wird, 
entzieht sich meinem Verständnis; die übliche Vorgehensweise in einem 
PC-Interrupthandler (unter DOS, also praktisch ohne Betriebssystem) 
sieht so aus:

[int]

Schnittstellenstatus aus UART auslesen
(Warum hat die UART den Interrupt ausgelöst?)

Je nach Schnittstellenstatus zu erledigende Dinge tun
(Zeichen abholen und speichern oder Zeichen aus Sendepuffer lesen und an 
UART übertragen oder ...)

Interruptcontroller die Beendigung der Interruptroutine mitteilen

[reti]


Es ist nicht erforderlich, in der Interruptroutine irgendwelche 
Interruptvektoren zu bestimmen, denn das geschieht schon implizit durch 
Aufruf der richtigen Interruptroutine.

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das obige Flussdiagramm soll ja nur die Installation des Interrupt 
Handler grafisch darstellen.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann darf das aber nicht mit dem Namen der Interruptroutine beschriftet 
sein.

Im übrigen wird auf PC-Hardware (unter DOS, also ohne Betriebssystem) 
ein Interrupthandler dadurch installiert, daß seine Startadresse in die 
Interrupttabelle im Arbeitsspeicher eingetragen wird. Danach muss nur 
noch dem Interruptcontroller mitgeteilt werden, daß es den 
Interrupthandler gibt (setzen/löschen des erforderlichen Bits) und 
fertig.


Hier mal etwas Pascal-Quelltext:

Interrupthandler
procedure v24_irq;
{ interruptroutine. Wird fr jedes auf 8250 ankommendes Zeichen aufgerufen }
interrupt;
  var
    zeichen : byte;
    inhalt : integer;
  begin
    inline($FA);              { Interrupts sperren }
    zeichen := port[uart];    { angekommenes Zeichen lesen }
    buffer[ein] := zeichen;   { Zeichen in FIFO eintragen }
    inc(ein);                 { Schreibzeiger erh”hen }
    inc(counter);             { Fllstand erh”hen }
    if (fifo_len - ein = 0)   { FIFO-Wraparound }
      then ein := 0;
    if (counter > fifo_len - fifo_dlost)
      then begin
        dec(counter);
        dec(ein);             { FIFO-šberlauf ! (weitere Zeichen ignorieren) }
      end;
    if (counter > fifo_len - fifo_off)
      then v24_off;           { Handshake : Schnittstelle abschalten }
    if (ein >= aus)
      then inhalt := ein - aus
      else inhalt := fifo_len - (aus - ein);
    counter := inhalt;
    inline($FB);              { Interrupts wieder zulassen }
    port[$20] := EOI;         { weitere Interrupts zulassen (8259) }
  end;

Die letzte Anweisung ist hier interessant.


Und hier wird der Interruptvektor gesetzt:
    { Interruptvektor retten & setzen }
    case com_intr[nr] of
      3 :
        begin
          setintvec(11,@v24_irq);
        end;
      4 :
        begin
          setintvec(12,@v24_irq);
        end;
      end;

Hier wird dem Interruptcontroller das Vorhandensein des Handlers 
mitgeteilt
          case com_intr[com_nr] of
            3 : port[interrupt_controller] := port_21 and $f7;
            4 : port[interrupt_controller] := port_21 and $ef;
          end;
          port[uart + 1] := 1;    { IRQ bei Datenempfang }
(sowie bei der UART der Empfangsinterrupt freigeschaltet


Die eigentliche Initialisierung der UART geschieht hier:
    { Baudratenteiler berechnen }
    baudteil := 115200 div baudrate;

    { Schnittstelle initialisieren }
    port[uart + 5] := 60;     { Line Status Register }
    port[uart + 1] := $00;    { Interrupt Enable Register }
    port[uart + 2] := $04;    { Interrupt Ident. Register }
    port[uart + 4] := $0B;    { Modem Control Register }
    port[uart + 3] := $80;    { Baudratenteiler ansprechen }
    port[uart] := lo(baudteil);
    port[uart + 1] := hi(baudteil);
    port[uart + 3] := $07;    { Line Control Register }

und ist natürlich vor dem Setzen und Initialisieren des 
Interrupthandlers durchzuführen.


Auch wenn das Turbo-Pascal-Code ist, lässt sich das recht leicht auch in 
C ausdrücken.


Was Du da gepostet hast, hat mit irgendeinem Betriebssystem oder 
irgendeiner betriebssystemartigen Umgebung zu tun.

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Hilfe!!!
Ich habe es jetzt mal so in Sätzen zusammengefasst:

Das Senden und Empfangen von der seriellen Schnittstelle funktioniert 
hier Interruptgesteuert. Dazu wurde ein Interrupt Handler eingerichtet, 
in diesem wird das Interrupt Identifikations Register ausgelesen. Über 
das Interrupt Identifikations Register, erfährt der Interrupt 
Controller, wegen welchem Ereignis der Interrupt ausgelöst wurde. Der 
Interrupt Handler wird dadurch installiert, dass seine Startadresse in 
die Interrupttabelle im Arbeitsspeicher eingetragen wird. Danach wird 
noch dem Interrupt Controller mitgeteilt, dass der Interrupt Handler 
existiert.

Sobald der UART ein Datum empfängt bzw. ein Datum an die UART übergibt, 
wird ein Interrupt ausgelöst, dieser veranlasst, dass der Interrupt 
Handler gestartet wird.

(Auf dem Board läuft ein 32Bit Echtzeitbetriebssystem, dort kann man auf 
die Win API zugreifen)

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Über das Interrupt Identifikations Register, erfährt der Interrupt
> Controller, wegen welchem Ereignis der Interrupt ausgelöst wurde.

Nein. Der Interrupt-Controller hat damit nichts zu tun, durch das 
Auslesen des IIR erfährt der Interrupt-Handler (also Deine Software), 
welches Ereignis den Interrupt ausgelöst hat.

Wann der/die UART Interrupts auslöst, wird durch die Initialisierung 
festgelegt, dort lassen sich Interrupts bei Datenempfang, leerem 
Senderegister, Änderungen der Handshakeleitungen etc. konfigurieren.

Da Du aber ein Betriebssystem verwendest, werden etliche Details anders 
gehandhabt werden; das Betriebssystem selbst verwaltet die Behandlung 
des Interruptcontrollers und auch das Einrichten eines Interrupthandlers 
durch entsprechende Funktionsaufrufe.

Daher sind die in den von mir geposteten Pascal-Sourcen getätigten Dinge 
nur mit äußerster Vorsicht zu genießen.

Ist das 32-Bit-Echtzeitsystem zufälligerweise OnTime RTOS-32?

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja ist das ist ein 32-Bit-Echtzeitsystem (OnTime RTOS-32)

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich habe es jetzt mal so in Sätzen zusammengefasst:
Schön aber was soll das?

>Das Senden und Empfangen von der seriellen Schnittstelle funktioniert
>hier Interruptgesteuert...
Brauchst du das für einen Vortrag oder willst du irgendwas 
programmieren?
Wie das mit den Interrupts funktioniert wissen zumindest die die dir 
helfen könnten. Es ist nur unklar was du eigentlich willst.

>Sobald der UART ein Datum empfängt bzw. ein Datum an die UART übergibt,
>wird ein Interrupt ausgelöst, dieser veranlasst, dass der Interrupt
>Handler gestartet wird.
nicht ganz der 16c550 kann auch erst bei einem bestimmten Füllstand 
Interrupts auslösen. Also wenn mehrere Daten vorhanden sind.

>(Auf dem Board läuft ein 32Bit Echtzeitbetriebssystem, dort kann man auf
>die Win API zugreifen)
Die erste richtige Info, wie heißt das Betriebssystem und was willst du 
eigentlich machen?

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry...

Ja das ist ein 32-Bit-Echtzeitsystem (OnTime RTOS-32).

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Als Betriebssoftware wird die ETS -  TNT Embedded ToolSuite von PharLap 
eingesetzt. Diese ist ein 32 bit Real-Time Operating System (RTOS), das 
sich durch Unterstützung eines Teils der WIN32 API leicht in Windows 
Systeme integrieren lässt.

Ich möchte eigentlich den ganzen Vorgang von der seriellen Kommunikation 
(UART) dokumentieren. Mein Programm benutzt ein Interrupt Handler für 
die serielle Schnittstelle.

1. Beschreibung UART
2. Initialiserung UART
3. Aktivierung Interrupt für COM
4. Erstellung eines Interrupt Handlers für COM
5. Funktionsweise des Interrupt Handlers

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ganze soll eigentlich relativ kurz gefasst werden.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ja das ist ein 32-Bit-Echtzeitsystem (OnTime RTOS-32).

> Als Betriebssoftware wird die ETS -  TNT Embedded ToolSuite
> von PharLap eingesetzt.

Was denn nun? Das sind zwei vollkommen unterschiedliche Paar Schuhe.

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fakt ist, das ist ein  ein 32 bit Real-Time Operating System (RTOS).
Dieses Programmiere ich mit Visual Studio 6.0 (C++).

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab nochmals meinen Text einwenig verändert:

Das Senden und Empfangen von der seriellen Schnittstelle funktioniert 
hier Interruptgesteuert. Dazu wurde ein Interrupt Handler eingerichtet, 
in diesem wird das Interrupt Identifikations Register ausgelesen. Über 
das Auslesen des Interrupt Identifikations Registers, erfährt der 
Interrupt Handler, welches Ereignis den Interrupt ausgelöst hat. Der 
Interrupt Handler wird dadurch installiert, indem seine Startadresse in 
die Interrupttabelle im Arbeitsspeicher eingetragen wird. Danach wird 
dem Interrupt Controller mitgeteilt, dass der Interrupt Handler 
existiert.

Sobald der UART ein Datum empfängt bzw. ein Datum an die UART übergibt, 
wird ein Interrupt ausgelöst, dieser veranlasst, dass der Interrupt 
Handler gestartet wird.

(Dies soll eigentlich einfach gehalten werden)

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Fakt ist, das ist ein  ein 32 bit Real-Time Operating System (RTOS).
> Dieses Programmiere ich mit Visual Studio 6.0 (C++).

Du wirst unglaubwürdig, da Du zwei unterschiedliche Produkte aufgeführt 
hast. Würdest Du tatsächlich mit einem davon arbeiten, wüsstest Du, wie 
es heißt.

Trotzreaktionen sind hier wenig hilfreich.

> > Ich programmiere unter Linux.
>
> > Ich programmiere unter Windows.
>
> Was denn nun?
>
> > Fakt ist, das ist ein 32-Bit Betriebssystem.

Erkennst Du Deine "Argumentation" wieder?

Sei's drum.


> Sobald der UART ein Datum empfängt bzw. ein Datum an die UART übergibt,

Den Sendeinterrupt (TXEMPT) solltest Du besser anders beschreiben.

Sobald der UART ein in sein Senderegister geschriebenes Zeichen (trenne 
Dich vom unglücklichen "Datum"!) versendet hat, wird der "transmit 
register empty"-Interrupt ausgelöst, um zu signalisieren, daß ein neues 
Zeichen versendet werden kann.

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum unglaubwürdig? Ich programmiere unter Windows. Linux habe ich hier 
nie verwendet. Mir geht es um das alg. Handling mit dem ganzen geraffel.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe bereits dargelegt, daß es einen ganz erheblichen Unterschied 
macht, worunter/wofür man einen Interrupthandler schreibt - es ist was 
anderes, ob man einen Interrupthandler für RTOS-32 (das ist ein Produkt! 
Keine generische Bezeichnung) oder für Pharlap TNT ETS schreibt.

Der Windows-/Linux-Vergleich ist eine Metapher für Deine Reaktion auf 
die Frage, wofür Du da was zu schreiben glaubst.

Das Handling des ganzen Geraffels ist eben unterschiedlich und 
deswegen kommt es darauf an, die Rahmenbedingungen zu kennen und auch zu 
nennen.

Dir aber scheint es wohl nur um einen Aufsatz oder dergleichen zu gehen 
...

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habs jetzt so geschrieben:

Sobald der UART ein in seinem Senderegister geschriebenes Zeichen 
versendet hat, wird „transmit holding register empty“- Interrupt 
ausgelöst, um zu signalisieren, dass ein neues Zeichen versendet werden 
kann. Im umgekehrten Fall, wenn ein Zeichen im Empfangsregister 
vorliegt, dann wird „receive data is available“- Interrupt ausgelöst, 
damit wird signalisiert dass ein neues Zeichen empfangen werden kann.

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe eher das Gefühl, du machst einen Teil einer Belegarbeit an der 
Uni,
die anderen haben es programmiert und da du Probleme dabei hattest, hast 
du dir den Dokumentationsteil rausgesucht.
Wenns wirklich so sein sollte: Schlechte Wahl, das setzt nämlich erst 
recht voraus, daß du alles verstehst.
Deine Bezeichnungen lassen erkennen, daß du in Hardwarenaher 
Programmierung nicht firm bist.

>Ich habs jetzt so geschrieben:
>...
ist etwas besser, aber deutlicher wird es mit einem Statediagram und 
Text

>dann wird „receive data is available“- Interrupt ausgelöst,
>damit wird signalisiert dass ein neues Zeichen empfangen werden kann.
das ist Müll, wenn du ein Zeichen bekommst solltest du es abholen

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hoffe das stimmt was ich hier geschrieben habe:

Das Senden und Empfangen von der seriellen Schnittstelle funktioniert 
hier Interruptgesteuert. Dazu wurde ein Interrupt Handler eingerichtet, 
in diesem wird das Interrupt Status Register ausgelesen. Über das 
Auslesen des Interrupt Status Registers, erfährt der Interrupt Handler, 
welches Ereignis den Interrupt ausgelöst hat.

Der Interrupt Handler wird dadurch installiert, indem seine Startadresse 
in die Interrupttabelle im Arbeitsspeicher eingetragen wird. Danach wird 
dem Interrupt Controller mitgeteilt, dass der Interrupt Handler 
existiert.

Sobald der UART ein in seinem Senderegister geschriebenes Zeichen 
versendet hat, wird „transmit holding register empty“- Interrupt 
ausgelöst, um zu signalisieren, dass ein neues Zeichen versendet werden 
kann. Im umgekehrten Fall, wenn ein Zeichen im Empfangsregister 
vorliegt, wird „receive data is available“- Interrupt ausgelöst, damit 
kann nun das Zeichen vom Empfangsregister abgeholt werden.

Autor: *.* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Danach wird dem Interrupt Controller mitgeteilt, dass der Interrupt
> Handler existiert.

Ich weiß ja nicht was da für ein Interruptcontroller drauf ist aber 
normalerweise wird der betreffende Interrupt nur freigeschaltet.

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist ein 8259 Controller. Der kann doch 15 Geräte verwllten oder?

void __cdecl CommIntHandler(ETSINTREGS *pRegs);

void COM(void)
{
 ...
 UartIntVecNum = EtsPicGetIRQIntNumber(UartIRQNum);
 // --> UartIntVecNum = 0x0C
 ....
 EtsSetInterruptHandler( UartIntVecNum, CommIntHandler); // set handler
 ...
}

Ich hab da noch immer Probleme damit. Ich beschreibe es mal mit meinen 
eigenen Worten.
1. UartIntVecNum = EtsPicGetIRQIntNumber(UartIRQNum);
--> Nr. von der Vectortabelle auslesen, ist hier 0x0C
  (Warum Vectortabelle?)
2.EtsSetInterruptHandler( UartIntVecNum, CommIntHandler); // set handler
--> Interrupt Handler einrichten: 0x0C und Adresse vom Interrupt Handler 
der Funktion übergeben. Dann passiert irgendwas im Stack.

Weiss nicht so ganz obn dies hier stimmt.

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich verstehe das genau Zusammenspiel UART, Interrupt Controller, 
Interrupt Handler noch nicht ganz.
Kann mir einer erklären wie es im Prinzip funktioniert?

Autor: *.* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein 8259 kann 8 Interrupts verwalten - man kann ihn aber auch 
kaskadieren und bekommt dann Weitere.

Wie ein Interrupt abläuft:

Byte wurde empfangen -> UART akiviert die IRQ-Leitung -> IRQController 
prüft, ob aktiviert -> IRQController aktiviert die INT-Leitung zum 
Prozessor -> wenn Interrupts dort freigeschaltet sind: Prozessor macht 
seinen aktuellen Befehl noch fertig, schreibt die aktuelle CS:IP Adresse 
auf den Stack und setzt die INTA-Leitung zum IRQController -> 
IRQController überträgt den Vector (Vectortabelle ist ein Array mit den 
Anfangsaddressen der Interrupthandler-Funktionen, Vector der Index eines 
Eintrages in dieser Tabelle) -> CPU springt die zum Vector passende 
Interrupthandler-Funktion an -> Interrupthandler fragt die Hardware ab 
-> UART deaktiviert seine IRQ-Leitung -> Interrupthandler macht ein IRET 
(oder wars RETI?) -> CPU macht da weiter wo sie unterbrochen wurde.

Autor: *.* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gilt für den Realmode, im PM kann das teilweise anders aussehen.

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend, ich habe doch noch Probleme mit dem Interrupt Handler.
Und zwar es wird doch zuerst die Vectornummer von der Schnittstelle COM1 
(0x3F8) ausgelesen. Dies ist hier 0x0C. Dann wirdn doch der eigentliche 
Interrupt Handler installiert bzw. eingerichtet. Die Funktion 
EtsSetInterrupt Handler erhält zwei Parameter. 1. Parameter = 
Vectornummer 0x0C, 2. Parameter  die Adresse vom Interrupt Handler. Ist 
das jetzt richtig so?
Ich möchte nur diesen Vorgang beschreiben. Mir ist nun nicht ganz klar 
ob meine Aussage so stimmt.
void __cdecl CommIntHandler(ETSINTREGS *pRegs);

void COM(void)
{
...
UartIntVecNum = EtsPicGetIRQIntNumber(UartIRQNum); 
...
EtsSetInterruptHandler( UartIntVecNum, CommIntHandler); // set handler
...
}

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das steht in der Dokumentation des von Dir nach wie vor nicht genannten 
Betriebssystems. Wir können das nicht wissen.

Autor: Zip (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
2F8 und 3F8 sind IO adressen, wo das UART montiert ist. Was soll das 
Ganze ? Weder unter Linux, noch unter Windows schreibt jemand einen 
Interrupthandler.  Dort ist die Thematik eine ganz andere. Wie 
manoevriert man in den Tiefen des verbockten Windows, ohne das alles 
abschmiert. Sogar kundige Spzialisten verbraten da schnell mal 2 Monate. 
Vergiss es.
Intel hat einen schoenen Interruptcontroller gemacht, der kann 
Prioritaeten zuweisen und rotieren. Trotzdem wollte Microsoft was 
anderes und hat oben eine Software draufgesetzt die alles vermurkst.
Als Einsteigelektuere sei das iAPX86 Manual von Intel empfohlen, Dort 
wird auch der 8259 beschrieben, und ein paar Interrupthandler sind da 
auch drin. Als naechstes waere das 386 Manual mit dem Protected mode 
empfohlen. Dort wurden die Interrupts virtualisiert und muessen durch 
trap gates. Seither hat sich interruptmaessig nicht mehr sehr viel fuer 
den Benutzer geaendert.

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist ein Webserverboard von PharLap. Es nutzt ETS ein 32 bit Echtzeit 
Betriebssystem und kann ein Teil der WIN32 API-Funktionen. Der Prozessor 
ist ein AMD-ELAN Prozessor mit 66 MHZ. Programmieren tue ich das ganze 
unter Visual Studio 6.0 mit C++.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und, hast Du mittlerweile mal in der Dokumentation nachgesehen? Die 
beschreibt, was die von Dir verwendete Funktion macht bzw. machen 
sollte.

Hättest Du Deinen Aufsatz nicht eigentlich schon längst abgeben sollen?

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ne ne das dauert noch!

Autor: Mark Schmitd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe die Beschreibungen zu dem entsprechenden Funktionen gefunden.
Ich hab da Probleme das ganze hier zu verstehen.

//
// Return the interrupt vector number which corresponds to the
// specified hardware IRQ.  Assumes PC/AT mapping of 08h for IRQs 0-7
// and 70h for IRQs 8-15.  Source is provided in 
PHAREMB/EMBCUST/PCPIC.ASM.
//
// hardwareIRQNum is the desired IRQ number
//
// Returns the interrupt vector number which corresponds to the
// specified IRQ, or -1 if the specified IRQ is out of range.
//
int     __cdecl EtsPicGetIRQIntNumber(int hardwareIRQNum);


//---------------------------------------------------------------------- 
-------
// EtsSetInterruptHandler - Install a C function as an interrupt handler
//
//      This API installs a C function as an interrupt handler
//      for the specified interrupt.  The handler is entered as a normal
//      C function (__cdecl calling sequence) with interrupts disabled
//      and receives a pointer to the saved register set on the stack
//      as its argument.  The saved register set includes all general
//      purpose registers, DS, ES, and EFLAGS.  The FS and GS registers
//      are neither saved nor restored; if the handler alters them, it
//      must restore them itself before returning.  The handler
//      is expected to process the interrupt and may modify the
//      saved register set on the stack if wishes to
//      alter the context of the interrupted code.  When the handler 
// function
//      returns, the saved registers are popped off the stack and
//      control returns to the interrupted code.
//
//      The return value from the function is TRUE if successful or 
FALSE
//      if an error occurs.
//
//---------------------------------------------------------------------- 
-------
BOOL    __cdecl EtsSetInterruptHandler(unsigned IntNumber,
               PETSINTHANDLER pHandler);

//
// Saved register block passed to interrupt handlers registered
// with EtsSetInterruptHandler() and EtsSetExceptionHandler().
// These fields contain the register contents at the time of the
// interrupt.  The interrupt service routine can modify the
// values in the passed structure in order to change the user
// registers on return from the interrupt.
//
// Note:  The FS and GS registers are neither saved nor restored
// by the interrupt handler framework.  If a user interrupt handler
// wants to use either of these registers, it must preserve them itself!
//
typedef struct tagETSINTREGS
{
  DWORD   Ebp;                    // [00]
  DWORD   Eax;                    // [04]
  DWORD   Ebx;                    // [08]
  DWORD   Ecx;                    // [12]
  DWORD   Edx;                    // [16]
  DWORD   Esi;                    // [20]
  DWORD   Edi;                    // [24]
  DWORD   Gs;                     // [28]
  DWORD   Ds;                     // [32]
  DWORD   Es;                     // [36]
  DWORD   IntNum;                 // [40]
  DWORD   Ecode;                  // [44]   (Zero if int w/o error code)
  DWORD   Eip;                    // [48]
  DWORD   Cs;                     // [52]
  DWORD   Eflags;                 // [56]
} ETSINTREGS, *PETSINTREGS;

void __cdecl CommIntHandler(ETSINTREGS *pRegs);

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und? Was erwartest Du jetzt?

Soll Dir das jemand ins Deutsche übersetzen?

Oder soll Dir jemand dabei helfen, eine Frage zu stellen?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.