Forum: Mikrocontroller und Digitale Elektronik Serielle Ports auf Karten können keine Daten einlesen (Linux)


von Rolf F. (Firma: G.) (benutzername0)


Angehängte Dateien:

Lesenswert?

Tetestet habe ich 3 serielle Sorten Ports:

* Onboard-Ports plus billigen Adapter RS-422 - RS-232 von Hexin (Ebay, 
8,11 EUR inkl. Versand aus Honkong), versorgt von den 12 V vom Netzteil:
Problemloses Senden und auch Empfangen von Daten von Maschinen wie 
Webmaschinen. Einstellungen mit setserial vorzunehmen ist nicht nötig; 
mit stty ein paar Parameter setzen reicht.

* USB-Adapter: Problemlos, nur die Ausgangspegel sind etwas schwach und 
die Daten kommen in einem Raster von ca. 10 ms, also mit erheblicher 
Latenz.
Einstellungen mit setserial vorzunehmen ist nicht nötig; mit stty ein 
paar Parameter setzen reicht.

* PCI/PCIe-Karten, konkret EX-42042, DELOCK 89320 und Longshine 
LCS-6021-485, alle auch für Linux spezifiziert:
Die Ausgaben von lcpci -v, dmesg usw. sind unverdächtig, wie bei den 
vorigen Sorten.
Aber schon das Senden funktioniert nicht richtig: Um mit 19200 Baud zu 
senden muss ich eine Baudrate von 2400 vorgeben, also nur ein Achtel der 
tatsächlichen!
Deshalb habe ich setserial einen Divisor angegeben, aber das zeigte 
keine Wirkung. Ebenso ist es mit baud_base.
Und auch mit der Konfiguration, mit der mit 19200 gesendet werden kann, 
wird nichts empfangen. Auch alle möglichen UART-Typen dem setserial 
anzugeben (nacheinander ausprobieren) änderte nichts; eingangsmäßig 
kommt nichts, es wird kein Byte empfangen.
Und beim Senden fällt auf das bei Tx- (nicht bei Tx+) kurze Pulse und 
Zwischen-Stufen im Ausgangssignal sind, siehe Bild.

Gibt es irgendeinen Trick um die seriellen PCI/PCIe-Karten unter Linux 
(Ubuntu Server 64bit) zum Laufen zu bekommen?

: Bearbeitet durch User
von Lästermaul (Gast)


Lesenswert?

Das freundlichste, was man dazu sagen kann: Bei Hardware, die von den 
Beta-Testern benutzt wird, funktioniert der Linux Entwicklungsprozess 
hervorragend.

Wahrscheinlich hat es mal funktioniert, nur beim Versuch so einen alten 
Linux-Kernel einzusetzen, stößt man auf so viele Probleme - das lohnt 
nicht.

von Rolf F. (Firma: G.) (benutzername0)


Lesenswert?

Lästermaul schrieb:
> Wahrscheinlich hat es mal funktioniert, nur beim Versuch so einen alten
> Linux-Kernel einzusetzen, stößt man auf so viele Probleme - das lohnt
> nicht.

Ich setze keinen Kernel von den Karten ein sondern umgekehrt laufen die 
unter dem aktuellen von Ubuntu, also 3.19.0-22-lowlatency #22-Ubuntu SMP 
PREEMPT Tue Jun 16 17:47:20 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux.

von Cyblord -. (cyblord)


Lesenswert?


von Lästermaul (Gast)


Lesenswert?

Habe ich mich falsch ausgedrückt...

Es dürfte wohl alte Linux-Kernel geben, unter denen der mitgelieferte 
Treiber noch funktioniert. Wenn die Karte in der Kompatibilitätsliste 
aufgeführt ist, wird es mal jemand getestet haben.

Nur wird wohl durch einen Umbau an einem anderen Modul der Treiber 
kaputt gegangen sein. Und da es kaum jemand einsetzt, kümmert sich 
niemand darum.

von Rolf F. (Firma: G.) (benutzername0)


Lesenswert?

Lästermaul schrieb:
> Habe ich mich falsch ausgedrückt...
>
> Es dürfte wohl alte Linux-Kernel geben, unter denen der mitgelieferte
> Treiber noch funktioniert. Wenn die Karte in der Kompatibilitätsliste
> aufgeführt ist, wird es mal jemand getestet haben.

Für die Karten von Longshine und Delock gibt es den gleichen kleinen 
Patch, für Kernel 2.6:
1
--- 8250.c  2011-05-10 06:16:23.000000000 +0800
2
+++ 8250_new.c  2011-12-24 20:20:22.366114976 +0800
3
@@ -862,7 +862,7 @@
4
    * claims that it's needed for 952 dual UART's (which are not
5
    * recommended for new designs).
6
    */
7
-  up->acr = 0;
8
+  up->acr = 0x18;                         // Enable 485, nDTR active high
9
   serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
10
   serial_out(up, UART_EFR, UART_EFR_ECB);
11
   serial_out(up, UART_LCR, 0x00);
12
@@ -2005,7 +2005,7 @@
13
 
14
   if (up->port.type == PORT_16C950) {
15
     /* Wake up and initialize UART */
16
-    up->acr = 0;
17
+  up->acr = 0x18;                     // Enable 485, nDTR active high
18
     serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
19
     serial_outp(up, UART_EFR, UART_EFR_ECB);
20
     serial_outp(up, UART_IER, 0);
21
@@ -2014,6 +2014,7 @@
22
     serial_outp(up, UART_LCR, 0xBF);
23
     serial_outp(up, UART_EFR, UART_EFR_ECB);
24
     serial_outp(up, UART_LCR, 0);
25
+  serial_icr_read(up, UART_ACR);      // Restore ACR after soft reset
26
   }

Aber das ist 4 Jahre alt (die betreffende Datei ist nicht mehr in den 
Kernel-Sourcen), der aktuelle Kernel erkennt ja die UARTs und die Chips 
sind Massenware von einem bekannten Hersteller (Oxford).
Deshalb sollte das ohne weitres funktionieren, auch weil die Hersteller 
nichts neuere anbieten, an Treibern für Linux.
Allerdings stellen sich die Hersteller tot, denn bevor ich hier postete 
habe ich natürlich erstmal bei den Herstellern angefragt.

Und zur EX-42042 gibt der Hersteller an das sie unter Linux läuft ohne 
das etwas dazu auf der beiligenden CD ist und ohne im Kapitel 
Installation Linux zu erwähnen; die soll also ohne Patch oder speziellen 
Treiber laufen.

von Christoph H. (Gast)


Lesenswert?

Hallo Rolf,

versuche mal vor der Benutzung ein "setserial /dev/XXXX baud_base 
921600".

Was sagen sonst lsmod und dmesg genau?
Welcher Treiber wird geladen?
Evtl. auch mal modinfo Treibername - evtl. hat der Treiber ein paar 
Parameter.

Welche Chipsätze sind auf den Karten verbaut?
OXuPCI952?


Der Patch dürfte nur den Pegel von der DTR-Leitung anders steuern, da 
darüber oft bei RS485-Karten die Umschaltung zwischen Senden und 
Empfangen statt findet.

Gruß Chris

von Erwin M. (nobodyy)


Lesenswert?

Vielleicht hilft es ja kurzzeitig mit setserial den irq auf null zu 
setzen, denn das fand ich im Skript bluetooth.sh von SuSE von 2006, 
unter /etc/pcmcia/ :

1
#!/bin/sh
2
#
3
# bluetooth
4
#
5
# PCMCIA Bluetooth device initialization
6
# Original script by Maxim Krasnyanskiy <maxk@qualcomm.com>
7
#
8
# The original script has been adapted for the use of udev and the new
9
# kernel-based PCMCIA-system.
10
#
11
12
. /etc/sysconfig/hardware/scripts/functions
13
14
is_true () 
15
{
16
  [ "$1" = "y" -o "$1" = "Y" -o "$1" = "yes" -o "$1" = "YES" ]
17
}
18
19
20
start_serial() {
21
  [ -x /etc/init.d/bluetooth ] && /etc/init.d/bluetooth start
22
23
  IRQ=`setserial $DEVNAME | sed -e 's/.*IRQ: //'`
24
  setserial $DEVNAME irq 0 ; setserial $DEVNAME irq $IRQ
25
26
  DEVICE=`echo $DEVNAME|sed -e 's_/dev/__'`
27
  MANFID=`cat /$SYSFS/$PHYSDEVPATH/manf_id`","`cat /$SYSFS/$PHYSDEVPATH/card_id`
28
  # I don't have a generic solution, sorry
29
  if [ $MANFID = "0x0160,0x0002" ]; then
30
    /usr/sbin/hciattach $DEVICE $MANFID 115200
31
  else
32
    /usr/sbin/hciattach $DEVICE $MANFID
33
  fi
34
}
35
36
stop_serial() {
37
  is_true $NO_FUSER && return 1
38
  fuser -k -HUP $DEVNAME > /dev/null
39
}
40
41
case "$ACTION" in
42
  add)
43
  start_serial
44
  ;;
45
  remove)
46
  stop_serial
47
  ;;
48
  *)
49
  logger "Unknown action received $0: $ACTION"
50
  ;;
51
esac

von Rolf F. (Firma: G.) (benutzername0)


Lesenswert?

Christoph H. schrieb:
> Was sagen sonst lsmod und dmesg genau?
> Welcher Treiber wird geladen?
> Evtl. auch mal modinfo Treibername - evtl. hat der Treiber ein paar
> Parameter.

Unterschiede, die sich nach dem Einbau der Karte zeigen:

Statt dem I/O-Bereich


  3000-3fff : PCI Bus 0000:05


ist nun vorhanden:


  3000-3fff : PCI Bus 0000:11
    3000-301f : 0000:11:05.0
    3020-303f : 0000:11:05.1
    3040-305f : 0000:11:05.1
    3060-3067 : 0000:11:05.0
    3068-306f : 0000:11:05.0
    3070-3077 : 0000:11:05.0
      3070-3077 : serial
    3078-307f : 0000:11:05.0
      3078-307f : serial
  4000-4fff : PCI Bus 0000:05


lspci zeigt ein paar verschobene Interrupts und I/O-Adressen, neben der 
Karte mit zwei Einträgen:

11:05.0 Serial controller: Oxford Semiconductor Ltd OXuPCI952 (Dual 
16C950 UART) (rev 01) (prog-if 06 [16950])
  Subsystem: Oxford Semiconductor Ltd Device 0000
  Physical Slot: 3
  Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- 
Stepping- SERR+ FastB2B- DisINTx-
  Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- 
<TAbort- <MAbort- >SERR- <PERR- INTx-
  Interrupt: pin A routed to IRQ 22
  Region 0: I/O ports at 3078 [size=8]
  Region 1: I/O ports at 3070 [size=8]
  Region 2: I/O ports at 3068 [size=8]
  Region 3: I/O ports at 3060 [size=8]
  Region 4: I/O ports at 3000 [size=32]
  Region 5: Memory at f0500000 (32-bit, non-prefetchable) [size=4K]
  Capabilities: [40] Power Management version 2
    Flags: PMEClk- DSI- D1- D2+ AuxCurrent=0mA 
PME(D0+,D1-,D2+,D3hot+,D3cold-)
    Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
  Kernel driver in use: serial

11:05.1 Bridge: Oxford Semiconductor Ltd OX16PCI954 (Quad 16950 UART) 
function 1 (8bit bus) (rev 01)
  Subsystem: Oxford Semiconductor Ltd Device 0000
  Physical Slot: 3
  Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- 
Stepping- SERR+ FastB2B- DisINTx-
  Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- 
<TAbort- <MAbort- >SERR- <PERR- INTx-
  Interrupt: pin A routed to IRQ 22
  Region 0: I/O ports at 3040 [size=32]
  Region 1: Memory at f0502000 (32-bit, non-prefetchable) [size=4K]
  Region 2: I/O ports at 3020 [size=32]
  Region 3: Memory at f0501000 (32-bit, non-prefetchable) [size=4K]
  Capabilities: [40] Power Management version 2
    Flags: PMEClk- DSI- D1- D2+ AuxCurrent=0mA 
PME(D0+,D1-,D2+,D3hot+,D3cold-)
    Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
  Kernel driver in use: serial


lsmod zeigt keine Änderung und auch die zugehörige Zeile in 
/proc/interrupts ist ungeändert:

22:          0          0   IO-APIC  22-fasteoi   ata_generic


Und dmesg meldet zwei neue serielle Schnittstellen:


[    0.629985] ttyS5: detected caps 00000700 should be 00000500
[    0.630721] 0000:11:05.0: ttyS5 at I/O 0x3078 (irq = 22, base_baud = 
921600) is a 16C950/954
[    0.632330] ttyS6: detected caps 00000700 should be 00000500
[    0.633057] 0000:11:05.0: ttyS6 at I/O 0x3070 (irq = 22, base_baud = 
921600) is a 16C950/954


setserial -a zeigt dazu:


/dev/ttyS5, Line 5, UART: 16950/954, Port: 0x3078, IRQ: 22
  Baud_base: 921600, close_delay: 50, divisor: 0
  closing_wait: 3000
  Flags: spd_normal skip_test

/dev/ttyS6, Line 6, UART: 16950/954, Port: 0x3070, IRQ: 22
  Baud_base: 921600, close_delay: 50, divisor: 0
  closing_wait: 3000
  Flags: spd_normal skip_test


> Welche Chipsätze sind auf den Karten verbaut?
> OXuPCI952?

Ja, siehe
http://www.exsys.de/index.php?page=product&info=181



> Der Patch dürfte nur den Pegel von der DTR-Leitung anders steuern, da
> darüber oft bei RS485-Karten die Umschaltung zwischen Senden und
> Empfangen statt findet.

Ja, das sollte auf meine Anwendung, RS-422 (vierdraht) keine Auswirkung 
haben.

von Rolf F. (Firma: G.) (benutzername0)


Angehängte Dateien:

Lesenswert?

Christoph H. schrieb:
> Hallo Rolf,
>
> versuche mal vor der Benutzung ein "setserial /dev/XXXX baud_base
> 921600".

Ja, ich setze


setserial /dev/ttyS5 -z uart 16950 irq 22 port 0x3078 baud_base 912600 
divisor 0 spd_normal skip_test low_latency


und die anderen Parameter exakt wie bei dem problemlosen ttyS1:


stty -F /dev/ttyS5 
2010:4:dbe:a30:3:1c:7f:15:4:0:1:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0: 
0:0:0:0:0:0:0:0


Damit funktioniert das Senden nun, mit 19200 Baud, aber einem 
merkwürdigen Peak bei Tx-, siehe Bilder (Tx+ gelb, Tx- grün).

Wieso ist da ein großer Peak mittem im Signal, nur bei der EX-42042?

Und wieso funktioniert bei der EX-42042 das Senden aber nicht das 
Empfangen, obwohl mit den gleichen Parametern über den zweiten 
Onboard-Port problemlos gelesen werden kann?

Daneben fallen auch zwei Kernel-Meldungen zu der Karte auf:

[    0.625085] ttyS5: detected caps 00000700 should be 00000500
[    0.627358] ttyS6: detected caps 00000700 should be 00000500

Was bedeutet das?

von Rolf F. (Firma: G.) (benutzername0)


Lesenswert?

Also ich habe getestet ob das, was die EX-42042 sendet, über einen 
RS422-RS232-Adapter vom zweiten Onboard-Port (mit gleicher 
stty-Konfiguration) gelesen werden kann und das funktioniert.
Aber über den zweiten Port der Karte das einlesen was der erste sendet 
funktioniert nicht; es ist eine Write-Only-Karte!

Deshalb wollte ich mal beim Chip-Hersteller anfragen, aber den gibt es 
seit 6 Jahren nicht mehr:

http://www.aufzu.de/semi/oxford.html

von Christoph H. (Gast)


Lesenswert?

Hallo Rolf,

hast Du schonmal die Karte auf RS232 gejumpert und damit getestet?
Zur Not kannst Du dafür einfach Pin 2&3 verbinden - Du solltest dann 
alle gesendeten Zeichen direkt wieder empfangen. Ggf. erfüllt der 
ECHO-Jumper den selben Zweck.
Falls das funktioniert, kannst Du die Fehlersuche auf den RS422-Teil 
beschränken. Andernfalls sind meine Möglichkeiten der Ferndiagnose 
weitgehend erschöpft.

Gruß Christoph

von Rolf F. (Firma: G.) (benutzername0)


Lesenswert?

Ich habe nachgesehen woher die caps-Meldung vom Kernel stammt:
Die caps-Meldung entsteht in 8250_core.c, im Fall out_lock und der tritt 
ein
wenn (port->type == PORT_UNKNOWN). Dies trifft ein wenn serial_in(up,
UART_IIR) >> 6 den Wert 1 ausgibt.
Angezeigt werden in diesem Fall old_capabilities und up->capabilities.
Das Problem ist offenbar das die Erkennung einen unbekannten UART-Typ
ergibt, d. h. Oxford hat irgeneinen Müll gemacht, mit dem man nur halb 
senden kann, weil auf Tx- starke Störpulse sind.

von wendelsberg (Gast)


Lesenswert?

Kann Dein Kernel mit mehr als 4 ttySx umgehen, die Standardkonfiguration 
sind nur 4?

wendelsberg

von Rolf F. (Firma: G.) (benutzername0)


Lesenswert?

wendelsberg schrieb:
> Kann Dein Kernel mit mehr als 4 ttySx umgehen, die Standardkonfiguration
> sind nur 4?
>
> wendelsberg

Ja, ansonsten könnte ich ja nicht auf ttyS5 und 6 schreiben.

Und der Kernel ist für deutlich mehr als nur vier konfiguriert:

CONFIG_SERIAL_8250_NR_UARTS=48
CONFIG_SERIAL_8250_RUNTIME_UARTS=32

: 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.