Как найти ком порт в linux

What is the proper way to get a list of all available serial ports/devices on a Linux system?

In other words, when I iterate over all devices in /dev/, how do I tell which ones are serial ports in the classic way, that is, those usually supporting baud rates and RTS/CTS flow control?

The solution would be coded in C.

I ask because I am using a third-party library that does this clearly wrong: It appears to only iterate over /dev/ttyS*. The problem is that there are, for instance, serial ports over USB (provided by USB-RS232 adapters), and those are listed under /dev/ttyUSB*. And reading the Serial-HOWTO at Linux.org, I get the idea that there’ll be other name spaces as well, as time comes.

So I need to find the official way to detect serial devices. The problem is that none appears to be documented, or I can’t find it.

I imagine one way would be to open all files from /dev/tty* and call a specific ioctl() on them that is only available on serial devices. Would that be a good solution, though?

Update

hrickards suggested to look at the source for “setserial”.
Its code does exactly what I had in mind:

First, it opens a device with:

fd = open (path, O_RDWR | O_NONBLOCK)

Then it invokes:

ioctl (fd, TIOCGSERIAL, &serinfo)

If that call returns no error, then it’s a serial device, apparently.

I found similar code in Serial Programming/termios, which suggested to also add the O_NOCTTY option.

There is one problem with this approach, though:

When I tested this code on BSD Unix (that is, Mac OS X), it worked as well. However, serial devices that are provided through Bluetooth cause the system (driver) to try to connect to the Bluetooth device, which takes a while before it’ll return with a timeout error. This is caused by just opening the device. And I can imagine that similar things can happen on Linux as well – ideally, I should not need to open the device to figure out its type. I wonder if there’s also a way to invoke ioctl functions without an open, or open a device in a way that it does not cause connections to be made?

What should I do?

You can also use setserial to get and set serial port information, in addition to dmesg.

Tested on Ubuntu 18.04:

setserial

# install it
sudo apt update
sudo apt install setserial

# Display (and sort) serial information for all /dev/ttyS* devices
setserial -g /dev/ttyS* | sort -V
# Display (and sort) serial information for all /dev/ttyUSB* devices
setserial -g /dev/ttyUSB* | sort -V

# To see extra info. such as the baud rate too, add `-G`:
setserial -g -G /dev/ttyS* | sort -V
setserial -g -G /dev/ttyUSB* | sort -V

Sample run and output. Notice that /dev/ttyS4 is the only port that appears to be alive and not “unknown” (whatever that means). (This /dev/ttyS4 device also shows up in the Arduino IDE even though it’s not an Arduino and I don’t know what it is.):

$ setserial -g -G /dev/ttyS* | sort -V
/dev/ttyS0 uart unknown port 0x03f8 irq 4 baud_base 115200 spd_normal skip_test
/dev/ttyS1 uart unknown port 0x02f8 irq 3 baud_base 115200 spd_normal skip_test
/dev/ttyS2 uart unknown port 0x03e8 irq 4 baud_base 115200 spd_normal skip_test
/dev/ttyS3 uart unknown port 0x02e8 irq 3 baud_base 115200 spd_normal
/dev/ttyS4 uart 16550A port 0x3060 irq 19 baud_base 115200 spd_normal skip_test
/dev/ttyS5 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS6 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS7 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS8 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS9 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS10 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS11 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS12 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS13 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS14 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS15 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS16 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS17 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS18 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS19 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS20 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS21 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS22 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS23 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS24 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS25 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS26 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS27 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS28 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS29 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS30 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal
/dev/ttyS31 uart unknown port 0x0000 irq 0 baud_base 0 spd_normal

dmesg

Use dmesg to also see some of this information:

# Show UART information, incl. baudrate, for /dev/ttyS* devices.
dmesg | grep ttyS

# Show UART information, incl. baudrate, for /dev/ttyUSB* devices.
dmesg | grep ttyUSB

Sample run and output:

$ dmesg | grep ttyS
[    1.624447] 0000:00:16.3: ttyS4 at I/O 0x3060 (irq = 19, base_baud = 115200) is a 16550A

Even better, watch the dmesg kernel ring buffer output live with the -w option:

dmesg -wH

Now, unplug your USB device you’re trying to identify and plug it back in to see which device it is, based on the messages that show up in the dmesg output, live.

I have a laptop which has only one serial port.

I went into:

/dev 

directory, and I found:

ttyS0
ttyS1
ttyS2
ttyS3

How do I know which of those “ttyS” refers to my serial port?

Cfinley's user avatar

Cfinley

1,4353 gold badges14 silver badges20 bronze badges

asked Apr 14, 2010 at 21:10

sivabudh's user avatar

1

I think it’s this command:

dmesg | grep tty

Running that on my own Linux box (which only has 1 Serial port) produces a single ttyS0 output line. Try it on your own, you will see what I mean.

answered Apr 14, 2010 at 21:24

sivabudh's user avatar

sivabudhsivabudh

3,0657 gold badges28 silver badges30 bronze badges

4

See which UARTs where detected in /proc/tty/driver/serial. A line with uart:unknown means: nothing detected (and likely not existent).

# cat /proc/tty/driver/serial
serinfo:1.0 driver revision:
0: uart:16550A port:000003F8 irq:4 tx:0 rx:0
1: uart:16550A port:000002F8 irq:3 tx:111780 rx:1321 RTS|DTR|DSR
2: uart:unknown port:000003E8 irq:4
3: uart:unknown port:000002E8 irq:3

If you see any of the CTS, DSR, (D)CD or RI flags (these are input signals), like on UART no. 1 above, you can even be pretty sure that there actually is something connected and driving these lines. Same is true for the rx-byte-count.

Seeing a positive tx-byte-count, RTS and/or DTR only reveals that some software accessed the device and ordered it to set those signals or send bytes here, but not if something was listening.

Note: you might see more ports available in hardware than ports reaching the outside of your computer in form of a connector.

answered Jun 30, 2016 at 15:45

Robert Siemer's user avatar

If you need to do this programmatically reading the output from dmesg can be troublesome, instead the folder /dev/serial/by-id has sym links that are named after identifiable data of your device and point to the specific /dev/tty* they are connected to.

I’m not sure if this is some special udev rule that is distribution specific, but it works well in Ubuntu, let me know if it works.

answered Dec 20, 2014 at 13:55

santileortiz's user avatar

santileortizsantileortiz

5231 gold badge5 silver badges6 bronze badges

1

ttyS0 through 3 correspond to COM1 through 4, respectively. They usually have the same hardware resources and are not always detectable, so they always exist.

answered Apr 14, 2010 at 21:17

Ignacio Vazquez-Abrams's user avatar

2

There is also the command setserial which uses /proc/tty/driver/serial to get it’s data.

# setserial -g /dev/ttyS[0123]
/dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4
/dev/ttyS1, UART: 16550A, Port: 0x02f8, IRQ: 3
/dev/ttyS2, UART: unknown, Port: 0x03e8, IRQ: 4
/dev/ttyS3, UART: unknown, Port: 0x02e8, IRQ: 3

answered Sep 12, 2016 at 15:19

Daniël W. Crompton's user avatar

1

  • Печать

Страницы: [1]   Вниз

Тема: как узнать номер ком порта (ttyS*)  (Прочитано 36004 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн
c0tt0nm0uF

в общем надо узнать номер ком порта который в моём пк один. Я вынужден работать с этим самым ком портом. но при команде “sudo ls -l /dev/ttyS*” вижу вот это http://img.by/?v=4yav2.png тоесть у меня 30 каких то портов. Как мне найти адрес именно того порта который у меня на задней панели пк


Оффлайн
_angus_


Оффлайн
c0tt0nm0uF

dmesg | grep ttyS

Спасибо! оказывается просто нулевой, но как его проверить? я закоротил 2 и 3 контакты и через minicom пытаюсь отправить команду “просто символ” по идее он должен прийти в ответ, нет?


Оффлайн
_angus_

Надо ещё контроль потока вовсе отключить, если только 2-3 замкнуты. что-то вроде

stty clocal -F /dev/ttyS0


Оффлайн
c0tt0nm0uF

Надо ещё контроль потока вовсе отключить, если только 2-3 замкнуты. что-то вроде

аппаратное управление потоком выключил через тот же minicom но всё равно он молчит.Но! когда я попробовал через putty то по идее всё получилось но не совсем.Дело в том что мне надо перепрошить baracuda 7200.11 (жесткий диск) и когда я к нему подключаю rx tx то он должен выдавать “LED:000000CC FAddr:0025BF67” а выдаёт только шумы http://img.by/?v=q8Ct.png

« Последнее редактирование: 22 Декабря 2013, 19:25:59 от c0tt0nm0uF »


Оффлайн
_angus_

А вы уверены, что это именно шумы, а не неверно установленная скорость? У 7200.11 скорость 38400, а по дефолту у UART под линуксом, кажется, таки 9600. И да, пересчёт транслятора у этих сигейтов может вызвать немалые проблемы, если у них не пустой пост-скановый дефектлист. (проверяется командой F3 T> V40)


Оффлайн
c0tt0nm0uF

да кажется я понял суть. на разных сайтах мурзилки разные и на одном говорится что мол “на прямую подключайте rs232 к харду а вот на другом ясно сказано что конкретно к моей баракуде надо подключатся по ttl ну я не совсем понимаю чем отличается rs232 от ttl, помойму протоколы разные, но я лучше куплю переходник usb to ttl (200 рублей стоит)


Оффлайн
_angus_

Опа. Это вы прямо к компорту диск цепляете? Сурово. Легко можно спалить контроллер. Разница в том, что у диска уровни напряжения 0..+5V(TTL), а у RS232, который на задней панели компа, -+(3..12)V. Нужен преобразователь уровня, в общем, какой-нибудь дата-кабель “от старого сименса” сгодится, если он USB, то от того ж USB и будет питаться, а если RS232, то ему надо внешнее питание.


Оффлайн
c0tt0nm0uF

Оу :( ну не силён я по аппаратной части XD  вот такой переходник собираюсь купить, пойдёт?http://savepic.net/4092781.htm сзади написанно usb to ttl 🙂

« Последнее редактирование: 22 Декабря 2013, 21:57:25 от c0tt0nm0uF »


Оффлайн
_angus_

Да, вполне, только я бы на RxD/TxD повесил резисторы ом по 100, а то нежные они, преобразователи эти.


  • Печать

Страницы: [1]   Вверх

The output from dmesg is not the result you want you still have to run the command:

setserial -g /dev/ttyS[0123456789]

The output would be like:

/dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4
/dev/ttyS1, UART: 16550A, Port: 0x1020, IRQ: 18
/dev/ttyS2, UART: unknown, Port: 0x03e8, IRQ: 4
/dev/ttyS3, UART: unknown, Port: 0x02e8, IRQ: 3
....
/dev/ttyS7, UART: unknown, Port: 0x1020, IRQ: 18
/dev/ttyS8, UART: unknown, Port: 0x03e8, IRQ: 4
/dev/ttyS9, UART: unknown, Port: 0x02e8, IRQ: 3

So as shown above The unkwon UART is not taken so you can use ttyS0 ot ttyS1.

Try this for your system and check.

More if you still use some old Ubuntu version < 14.04 you can use gtkterm which is a simple GTK+ terminal used to communicate with the serial port.

sudo apt-get install gtkterm

enter image description here

Добавить комментарий