Forum: PC-Programmierung Seriell Schnittstelle Steuerleitungen


von traffic (Gast)


Lesenswert?

Hi,

ich muss die Steuerleitungen der seriellen Schnittstelle recht 
zeitkritisch abfragen. Da ich das nicht unbedingt per Polling machen 
will, die Frage: Gibt es für C unter Linux da eine Interrupt-gesteuerte 
Möglichkeit?

LG
traffic

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Die gibt's im normalen Posix-Modell nur für die DCD-Leitung: im
„normalen“ Modembetrieb bekommst du ein SIGHUP (“hangup”), wenn
DCD verschwindet.

Allerdings muss der zugrhörige Prozess zuvor der process group leader
für das entsprechende Terminal geworden sein (via setpgid() und
tcsetpgrp()).

: Bearbeitet durch Moderator
von H. K. (spearfish)


Lesenswert?

Ich gehe mal davon aus, dass du das auslesen per TTY Syscalls (ioctl) 
machst.
Da gibt es den TIOCMIWAI-Syscall.

Siehe die Doku: http://man7.org/linux/man-pages/man4/tty_ioctl.4.html
1
       TIOCMIWAIT     int arg
2
              Wait for any of the 4 modem bits (DCD, RI, DSR, CTS) to
3
              change.  The bits of interest are specified as a bit mask in
4
              arg, by ORing together any of the bit values, TIOCM_RNG,
5
              TIOCM_DSR, TIOCM_CD, and TIOCM_CTS.  The caller should use
6
              TIOCGICOUNT to see which bit has changed.

Logischerweise musst du dann diesen Syscall in einen Child-Prozess 
auslagern, wenn du nicht willst, dass dein Programm blockiert...

Siehe z.B. hier für ein Beispielprogramm: 
http://linux.mathematik.tu-darmstadt.de/pub/linux/oldstuff/people/bonnes/waitcomm/serial_test.c

: Bearbeitet durch User
von Peter II (Gast)


Lesenswert?

H. K. schrieb:
> Logischerweise musst du dann diesen Syscall in einen Child-Prozess
> auslagern, wenn du nicht willst, dass dein Programm blockiert...

Linux kann doch mittlerweile auch Threads.

von H. K. (spearfish)


Lesenswert?

Peter II schrieb:
> Linux kann doch mittlerweile auch Threads.

Stimmt. Habe ich vergessen zu erwähnen!

von Eric B. (beric)


Lesenswert?

traffic schrieb:
> ich muss die Steuerleitungen der seriellen Schnittstelle recht
> zeitkritisch abfragen.

Wie kritisch ist denn die Zeit? Linux ist, wie alle andere Desktop und 
Server OS-en, nicht gerade ausgelegt für zeitkritische (Real-time) 
Anforderungen.

von traffic (Gast)


Lesenswert?

Danke für die Antworten.

Leider bin ich irgendwie zu blöd, folgender Test-Code kommt bei mir nur 
bis zur Ausgabe "TEST":
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <termios.h>
4
#include <sys/ioctl.h>
5
#include <sys/types.h>
6
#include <sys/stat.h>
7
#include <fcntl.h>
8
#include <unistd.h>
9
#include <string.h>
10
11
int main()
12
{
13
  int fd;
14
  struct termios options;
15
  fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
16
  if(fd == 0)
17
  {
18
    printf("Fehler: Device kann nicht geöffnet werden.\n");
19
    return 1;
20
  }
21
  
22
  memset(&options,0,sizeof (struct termios));
23
  cfmakeraw(&options);
24
  cfsetispeed(&options,B9600);
25
  cfsetospeed(&options,B9600);
26
  tcsetattr(fd,TCSANOW,&options);
27
  tcflush(fd,TCIOFLUSH);
28
    
29
  int i;
30
  printf("TEST\n");
31
  i = ioctl(fd,TIOCMIWAIT,0);
32
  if( i < 0 )
33
  {
34
    printf("clear failed (%d)\n",i);
35
    return 1;
36
  }
37
  else
38
    printf("PASS\n");
39
  i = ioctl(fd, TIOCMIWAIT, TIOCM_DSR);
40
  printf("A=%d", i);
41
  
42
  close(fd);
43
  return 0;
44
}

LG
traffic

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

traffic schrieb:
> ioctl(fd,TIOCMIWAIT,0);

Nun, wenn du auf nichts wartest (0), dann ist das wohl wenig
sinnvoll.  Die Funktion kann daraus zwei Entscheidungen treffen:
sofort zurückkehren („nichts“ ist ja bereits eingetreten), oder
unendlich warten („nichts“ kann nie eintreten).  Offenbar tut sie
letzteres.

von traffic (Gast)


Lesenswert?

Naja, dem verlinkten Beispiel nach müsste es gehen:
1
/* clear the wait flags */
2
    r = ioctl(fd,TIOCMIWAIT,0);
3
    if( r < 0 )
4
    {
5
        fprintf(stderr,"clear failed (%d)\n",r);
6
        return 1;
7
    }

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?


von nicht“Gast“ (Gast)


Lesenswert?

traffic schrieb:
> zeitkritisch

traffic schrieb:
> "/dev/ttyUSB0"

Bist du dir mit den zeitkritisch sicher? So recht passt das nicht 
zusammen. Wie viel Zeit kannst du dir denn gönnen?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

nicht“Gast“ schrieb:
> So recht passt das nicht zusammen.

Die Zeiten, die für die Meldung über den USB benötigt werden, dürften
im Bereich 10 ms liegen (hängt natürlich vom konkreten Device ab, das
er uns nicht genannt hat).  So schnell muss man es erstmal auf der
Ebene des Programms schaffen in einem nicht-realtime-OS.

: Bearbeitet durch Moderator
von traffic (Gast)


Lesenswert?

Die Zeit zum Erkennen einer Pegeländerung beträgt 30-40 ms. USB ist hier 
nur zum Test drin.

von Pandur S. (jetztnicht)


Lesenswert?

Wenn eine Handshake Funktion zeitkritisch ist, sollte sie bereits im 
Treiber implementiert sein, und nicht im Benutzerprogramm. Db das Buffer 
Full, im RTS/CTS. Sonst kann man im UART Fall von einem PC wenig 
erwarten. Versuch mal eine zunehmend laengere Blochnachricht zu 
uebertragen. Die kommt dann ploetzlich in einzelne Bloecke zerhackt. Mit 
einem eigenen Timing. Ich hab die Details dazu leider vergessen. Und der 
USB treiber macht auch noch seine Spielchen.

Fazit. Man sollte von einem PC keine Echtzeitleistungen erwarten.

: Bearbeitet durch User
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.