- How To Check and Use Serial Ports Under Linux
- Display Detected System’s Serial Support Under Linux
- A note about USB based serial ports
- Listing and using USB serial ports on Linux
- Use the setserial command to check and use serial ports
- Debian/Ubuntu Linux install setserial using the apt-get command/apt command
- CentOS/RHEL/Oracle Linux install setserial using the yum command
- Using setserial to list serial ports and devices
- Listing or displaying USB serial ports on Linux
- Linux serial console programs
- Cocnlusion
- Linux Serial Ports Using C/C++
- Overview
- Everything Is A File
- Basic Setup In C
- Configuration Setup
- Control Modes (c_cflags)
- PARENB (Parity)
- CSTOPB (Num. Stop Bits)
- Number Of Bits Per Byte
- Flow Control (CRTSCTS)
- CREAD and CLOCAL
- Local Modes (c_lflag)
- Disabling Canonical Mode
- Disable Signal Chars
- Input Modes (c_iflag)
- Software Flow Control (IXOFF, IXON, IXANY)
- Disabling Special Handling Of Bytes On Receive
- Output Modes (c_oflag)
- VMIN and VTIME (c_cc)
- Baud Rate
- Custom Baud Rates
- Saving termios
- Reading And Writing
- Writing
- Reading
- Closing
- Full Example (Standard Baud Rates)
- Issues With Getty
- Exclusive Access
- Changing Terminal Settings Are System Wide
How To Check and Use Serial Ports Under Linux
Display Detected System’s Serial Support Under Linux
Simple run the dmesg command:
$ dmesg | grep tty
A note about USB based serial ports
USB to RS232 adapter cable connects from the USB port of a computer to a device. Such serial to USB adapter connects to devices for configuration or programming under Linux. Here is what the dmesg command displays when you enter USB adapter:
$ dmesg
## use grep command/egrep command to filter out USB devices ##
$ dmesg | grep -i serial
$ dmesg | grep -i FTDI
Listing and using USB serial ports on Linux
Here is how it looks when I attached USB device:
$ sudo dmesg | more
Use the setserial command to check and use serial ports
The setserial is a program designed to set and/or report the configuration information associated with a serial port. This information includes what I/O port and IRQ a particular serial port is using, and whether or not the break key should be interpreted as the Secure Attention Key, and so on.
Debian/Ubuntu Linux install setserial using the apt-get command/apt command
$ sudo apt install setserial
CentOS/RHEL/Oracle Linux install setserial using the yum command
$ sudo yum install setserial
Fedora Linux user try the dnf command:
$ sudo dnf install setserial
Using setserial to list serial ports and devices
Now we installed required package. Open the termial and then type the following setserial command:
$ setserial -g /dev/ttyS[0123]
If you get an error/warning that reads as “Permission denied,” try running the command as the root user. For example, I am running it using the sudo command/su command:
$ sudo setserial -g /dev/ttyS[0123]
The setserial with -g option help to find out what physical serial ports your Linux box has.
Listing or displaying USB serial ports on Linux
Try:
$ sudo setserial -g /dev/ttyUSB[01]
- No ads and tracking
- In-depth guides for developers and sysadmins at Opensourceflare✨
- Join my Patreon to support independent content creators and start reading latest guides:
- How to set up Redis sentinel cluster on Ubuntu or Debian Linux
- How To Set Up SSH Keys With YubiKey as two-factor authentication (U2F/FIDO2)
- How to set up Mariadb Galera cluster on Ubuntu or Debian Linux
- A podman tutorial for beginners – part I (run Linux containers without Docker and in daemonless mode)
- How to protect Linux against rogue USB devices using USBGuard
Join Patreon ➔
Linux serial console programs
Once serial ports identified you can configure Linux box and use serial ports using various utilities:
- minicom– The best friendly serial communication program for controlling modems and connecting to dump devices
- wvidial or other GUI dial up networking program – a PPP dialer with built-in intelligence.
- Screen Command: Set Baud Rate [ Terminal Communication ]
- getty / agetty – agetty opens a tty port, prompts for a login name and invokes the /bin/login command.
- grub / lilo configuration – To configure serial port as the system console
Cocnlusion
You learned how to list or check serial ports including USB based adptor on Linux.
🐧 Get the latest tutorials on Linux, Open Source & DevOps via
Category | List of Unix and Linux commands |
---|---|
Documentation | help • mandb • man • pinfo |
Disk space analyzers | df • duf • ncdu • pydf |
File Management | cat • cp • less • mkdir • more • tree |
Firewall | Alpine Awall • CentOS 8 • OpenSUSE • RHEL 8 • Ubuntu 16.04 • Ubuntu 18.04 • Ubuntu 20.04 |
Linux Desktop Apps | Skype • Spotify • VLC 3 |
Modern utilities | bat • exa |
Network Utilities | NetHogs • dig • host • ip • nmap |
OpenVPN | CentOS 7 • CentOS 8 • Debian 10 • Debian 8/9 • Ubuntu 18.04 • Ubuntu 20.04 |
Package Manager | apk • apt |
Processes Management | bg • chroot • cron • disown • fg • glances • gtop • jobs • killall • kill • pidof • pstree • pwdx • time • vtop |
Searching | ag • grep • whereis • which |
Shell builtins | compgen • echo • printf |
Text processing | cut • rev |
User Information | groups • id • lastcomm • last • lid/libuser-lid • logname • members • users • whoami • who • w |
WireGuard VPN | Alpine • CentOS 8 • Debian 10 • Firewall • Ubuntu 20.04 |
Comments on this entry are closed.
I don’t know if this is the place, but I’m looking for information that is similar. I have 2 machines setup through a null modem. I want to read through the com port from one machine to the other. The sending machine is running Windows sending through COM1: and the receiving computer is Linux Red Hat. Any help on this would be appreciated.
You can use pyserial ,its a python package,can be used to read and write in serial ports
another simple serial console program not mentioned is gtkterm.
I want to advise you that probably there is an error in the last sentence “seserial with -g option help to find out what physical serial ports your Linux box has.”; isn’t it setserial?
I have 4 standard serial ports defined, /dev/ttyS0-4, but I added a PCI-E 16 port serial adapter, and I have not found a way to connect anything to the upper 16 ports.
How do you create the virtual links? what options do you give setserial to define the new ports?
it dosn’t work 🙁 I can’t connect to my ASA using debian.
Daemon is a program called getty used by UNIX/Linux systems. There are many different versions of getty. The first modem detected is /dev/ttys0 or /dev/ttys1. To create a link to the devices file so that you can view modem information. Type ln -s /dev/ttys1 /dev/modem.
It is essential to set the modem to AUTO ANSWER using getty.
download minicom from alioth.debian.org/projects/minicom.
create a modem config file by entering minicom -s from the root command line
select the options you want to configure using AT commands
connect to the modem by typing in minicom
Thanks very useful..save my time 🙂
Hi,everybody
I have a serial PCI card with two ports but neither of them is working, on Linux fedora 16. I have tried using “gtkterm” and “minicom” but unfortunately I can’t make a serial connection to my Cisco lab. Here is my output when I issue the command: “setserial -g /dev/ttyS[0123]”.
/dev/ttyS0, UART: 16550A, Port: 0xec00, IRQ: 16
/dev/ttyS1, UART: 16550A, Port: 0xe880, IRQ: 16
/dev/ttyS2, UART: unknown, Port: 0x03e8, IRQ: 4
/dev/ttyS3, UART: unknown, Port: 0x02e8, IRQ: 3
also I want to mention that when I try to connet throught the terminal it generates a message like so: ” Cannot open /dev/ttyS0: Permission denied”.
any help please.
abdel
Check the permissions on /dev/ttyS0… Likely problem is it’s owned by root, and is part of the uucp group. Add yourself to the uucp group, and all should be better. I’m curious to know if this is enough for you as I am having problems communicating with a serial port on Linux as well. I got past the permissions stuff, but it is still not working.
Thanks Tom,
I actually I tried but it’s does not work, still says “permission denied”. I would appreciate if you explain to me step by step the procedure how to do it, I’m knew to Linux.
Best Regards
Abdel
1) ls -la /dev/ttyS0 — This will report the permissions on the port. Typically, this will say crw-rw—- 1 root uucp. The “c” in the string indicates that it’s a “character device” the first “rw” indicates that the owner has read/write permission. The second “rw” means that the group has read/write permissions. The “—” indicates that the rest of the world has no permissions. After the “—-“, “root” indicates that the owner of the device is root, and that the group id is “uucp”. So, you either need to be root, or a member of the uucp group to have read/write access to the port.
2) To add yourself to the uucp group (to get read/write access), you need to edit the file /etc/group, and add your user name to the line that begins with “uucp:” User names are separated by commas, so add a comma, then your user name to the end of the line. You will need root permissions to edit this file.
3) log out, and log back in because group associations are made at login time, and are not queried on each request.
Thanks Tom,
here is my output from the group file I have added my username to it but does not work.
I will just give up.Thanks a lot for your help I relay appreciate it.
Your entry in /etc/group is incorrect. If you read my previous post, I said to add your user id to the line that _begins_ with uucp. You added uucp to the group of users that can access your account. You want an entry in the /etc/group file that looks something like:
The critical element is that it’s the line that begins with uucp
It works. I just add my username to ” dialout ” and it worked fine. Iwould like to thank you for you time and support.
Best Regards
Abdel
hi,
I have connected the SIM300(gsm model) to my pc running ubuntu. I need a code to send a AT command to the GSM module and it should read and display the reply.
Please let me know steps.
I tried so many methods and codes, but no use…
i need C code(program).
all my ttyS* shows unknown, earlier it was working fine, now it doesnt recognise
setserial -g /dev/ttyS*
/dev/ttyS0, UART: unknown, Port: 0x03f8, IRQ: 4
/dev/ttyS1, UART: unknown, Port: 0x02f8, IRQ: 3
/dev/ttyS2, UART: unknown, Port: 0x03e8, IRQ: 4
/dev/ttyS3, UART: unknown, Port: 0x02e8, IRQ: 3
#cat /etc/redhat-release
CentOS Linux release 6.0 (Final)
#dmesg | grep tty
console [tty0] enabled
can u pls help me
tried spending time in google two days, still no success, tried connecting a brand new device too, still no success.
Sorry, but that second sentence is not necessarily true. I have a PC with two dual com port adapters. Windows sees them as COM1 -> COM4 (there is no built in COM port). Linux sees them as /dev/ttyS4->/dev/ttyS7.
/dev/ttyS0-/devttyS3 are apparently reserved, exist whether or not a physical port exists, and /dev/ttyS0 for certain is “special” in that it is used by the default terminal window:
I think minicom still superior to other console utility.
Hi All tried all of the above and still get permission denied . HELP
Kevin
/bpq$ setserial -g /dev/ttyS[012345657
/bpq$ setserial -g /dev/ttyS[012345657]
sudo setserial -g /dev/ttyS1
Hiiiiiiiii
Please help me
i am install minicom and use serial modem sim300 v7.03 but there is problem to type AT cmd on minicom console…….
Edgeports are very easy to use the firmware is on Ubuntu they are from 2 ports to 16+ I bought my last two of them on ebay.
Jim
Hi all..
I got problem to connect with my USB serial port,
i already create
ln -s /dev/ttyUS0
and check dmesg | grep tty
[ 0.000000] console [tty0] enabled
[ 7.722004] systemd[1]: Created slice system-getty.slice.
[ 3659.524452] usb 1-1.1: FTDI USB Serial Device converter now attached to ttyUSB0
[ 4850.183339] ftdi_sio ttyUSB0: FTDI USB Serial Device converter now disconnected from ttyUSB0
[ 4857.907567] usb 1-1.1: FTDI USB Serial Device converter now attached to ttyUSB0
when running SDNC program and select com1 will shown “port is already in use”
hi, have are you\
i have a problem with machine xnc . old version sistem operating linux,
pc removed battery cmos . but change battery do it so machine different data serial port linux dont recognized machine.
how can you slove this problem
your help wil be welcome
Источник
Linux Serial Ports Using C/C++
Article by:Geoffrey Hunter
Date Published: | June 24, 2017 |
Last Modified: | November 24, 2020 |
Overview
Unluckily, using serial ports in Linux is not the easiest thing in the world. When dealing with the termios.h header, there are many finicky settings buried within multiple bytes worth of bitfields. This page is an attempt to help explain these settings and show you how to configure a serial port in Linux correctly.
Everything Is A File
In typical UNIX style, serial ports are represented by files within the operating system. These files usually pop-up in /dev/ , and begin with the name tty* .
Common names are:
- /dev/ttyACM0 — ACM stands for the ACM modem on the USB bus. Arduino UNOs (and similar) will appear using this name.
- /dev/ttyPS0 — Xilinx Zynq FPGAs running a Yocto-based Linux build will use this name for the default serial port that Getty connects to.
- /dev/ttyS0 — Standard COM ports will have this name. These are less common these days with newer desktops and laptops not having actual COM ports.
- /dev/ttyUSB0 — Most USB-to-serial cables will show up using a file named like this.
- /dev/pts/0 — A pseudo terminal. These can be generated with socat .
A listing of the /dev/ directory in Linux with a connected Arduino. The Arduino serial port is present as /dev/ttyACM0.
To write to a serial port, you write to the file. To read from a serial port, you read from the file. Of course, this allows you to send/receive data, but how do you set the serial port parameters such as baud rate, parity, e.t.c? This is set by a special tty configuration struct .
Basic Setup In C
First we want to include a few things:
Then we want to open the serial port device (which appears as a file under /dev/ ), saving the file descriptor that is returned by open() :
One of the common errors you might see here is errno = 2 , and strerror(errno) returns No such file or directory . Make sure you have the right path to the device and that the device exists!
Another common error you might get here is errno = 13 , which is Permission denied . This usually happens because the current user is not part of the dialout group. Add the current user to the dialout group with:
You must log out and back in before these group changes come into effect.
At this point we could technically read and write to the serial port, but it will likely not work, because the default configuration settings are not designed for serial port use. So now we will set the configuration correctly.
When modifying any configuration value, it is best practice to only modify the bit you are interested in, and leave all other bits of the field untouched. This is why you will see below the use of &= or |= , and never = when setting bits.
Configuration Setup
We need access to the termios struct in order to configure the serial port. We will create a new termios struct, and then write the existing configuration of the serial port to it using tcgetattr() , before modifying the parameters as needed and saving the settings with tcsetattr() .
We can now change tty ’s settings as needed, as shown in the following sections. Before we get onto that, here is the definition of the termios struct if you’re interested (pulled from termbits.h ):
Control Modes (c_cflags)
The c_cflag member of the termios struct contains control parameter fields.
PARENB (Parity)
If this bit is set, generation and detection of the parity bit is enabled. Most serial communications do not use a parity bit, so if you are unsure, clear this bit.
CSTOPB (Num. Stop Bits)
If this bit is set, two stop bits are used. If this is cleared, only one stop bit is used. Most serial communications only use one stop bit.
Number Of Bits Per Byte
The CS fields set how many data bits are transmitted per byte across the serial port. The most common setting here is 8 ( CS8 ). Definitely use this if you are unsure, I have never used a serial port before which didn’t use 8 (but they do exist). You must clear all of the size bits before setting any of them with &=
Flow Control (CRTSCTS)
If the CRTSCTS field is set, hardware RTS/CTS flow control is enabled. The most common setting here is to disable it. Enabling this when it should be disabled can result in your serial port receiving no data, as the sender will buffer it indefinitely, waiting for you to be “ready”.
CREAD and CLOCAL
Setting CLOCAL disables modem-specific signal lines such as carrier detect. It also prevents the controlling process from getting sent a SIGHUP signal when a modem disconnect is detected, which is usually a good thing here. Setting CLOCAL allows us to read data (we definitely want that!).
Local Modes (c_lflag)
Disabling Canonical Mode
UNIX systems provide two basic modes of input, canonical and non-canonical mode. In canonical mode, input is processed when a new line character is received. The receiving application receives that data line-by-line. This is usually undesirable when dealing with a serial port, and so we normally want to disable canonical mode.
Canonical mode is disabled with:
Also, in canonical mode, some characters such as backspace are treated specially, and are used to edit the current line of text (erase). Again, we don’t want this feature if processing raw serial data, as it will cause particular bytes to go missing!
If this bit is set, sent characters will be echoed back. Because we disabled canonical mode, I don’t think these bits actually do anything, but it doesn’t harm to disable them just in case!
Disable Signal Chars
When the ISIG bit is set, INTR , QUIT and SUSP characters are interpreted. We don’t want this with a serial port, so clear this bit:
Input Modes (c_iflag)
The c_iflag member of the termios struct contains low-level settings for input processing. The c_iflag member is an int .
Software Flow Control (IXOFF, IXON, IXANY)
Clearing IXOFF , IXON and IXANY disables software flow control, which we don’t want:
Disabling Special Handling Of Bytes On Receive
Clearing all of the following bits disables any special handling of the bytes as they are received by the serial port, before they are passed to the application. We just want the raw data thanks!
Output Modes (c_oflag)
The c_oflag member of the termios struct contains low-level settings for output processing. When configuring a serial port, we want to disable any special handling of output chars/bytes, so do the following:
Both OXTABS and ONOEOT are not defined in Linux. Linux however does have the XTABS field which seems to be related. When compiling for Linux, I just exclude these two fields and the serial port still works fine.
VMIN and VTIME (c_cc)
VMIN and VTIME are a source of confusion for many programmers when trying to configure a serial port in Linux.
An important point to note is that VTIME means slightly different things depending on what VMIN is. When VMIN is 0, VTIME specifies a time-out from the start of the read() call. But when VMIN is > 0, VTIME specifies the time-out from the start of the first received character.
Let’s explore the different combinations:
VMIN = 0, VTIME = 0: No blocking, return immediately with what is available
VMIN > 0, VTIME = 0: This will make read() always wait for bytes (exactly how many is determined by VMIN ), so read() could block indefinitely.
VMIN = 0, VTIME > 0: This is a blocking read of any number of chars with a maximum timeout (given by VTIME ). read() will block until either any amount of data is available, or the timeout occurs. This happens to be my favourite mode (and the one I use the most).
VMIN > 0, VTIME > 0: Block until either VMIN characters have been received, or VTIME after first character has elapsed. Note that the timeout for VTIME does not begin until the first character is received.
VMIN and VTIME are both defined as the type cc_t , which I have always seen be an alias for unsigned char (1 byte). This puts an upper limit on the number of VMIN characters to be 255 and the maximum timeout of 25.5 seconds (255 deciseconds).
“Returning as soon as any data is received” does not mean you will only get 1 byte at a time. Depending on the OS latency, serial port speed, hardware buffers and many other things you have no direct control over, you may receive any number of bytes.
For example, if we wanted to wait for up to 1s, returning as soon as any data was received, we could use:
Baud Rate
Rather than use bit fields as with all the other settings, the serial port baud rate is set by calling the functions cfsetispeed() and cfsetospeed() , passing in a pointer to your tty struct and a enum :
If you want to remain UNIX compliant, the baud rate must be chosen from one of the following:
Some implementation of Linux provide a helper function cfsetspeed() which sets both the input and output speeds at the same time:
Custom Baud Rates
As you are now fully aware that configuring a Linux serial port is no trivial matter, you’re probably unfazed to learn that setting custom baud rates is just as difficult. There is no portable way of doing this, so be prepared to experiment with the following code examples to find out what works on your target system.
GNU/Linux Method
If you are compiling with the GNU C library, you can forgo the standard enumerations above just specify an integer baud rate directly to cfsetispeed() and cfsetospeed() , e.g.:
termios2 Method
This method relied on using a termios2 struct, which is like a termios struct but with sightly more functionality. I’m unsure on exactly what UNIX systems termios2 is defined on, but if it is, it is usually defined in termbits.h (it was on the Xubuntu 18.04 with GCC system I was doing these tests on):
Which is very similar to plain old termios , except with the addition of the c_ispeed and c_ospeed . We can use these to directly set a custom baud rate! We can pretty much set everything other than the baud rate in exactly the same manner as we could for termios , except for the reading/writing of the terminal attributes to and from the file descriptor — instead of using tcgetattr() and tcsetattr() we have to use ioctl() .
Let’s first update our includes, we have to remove termios.h and add the following:
Please read the comment above about BOTHER . Perhaps on your system this method will work!
Saving termios
After changing these settings, we can save the tty termios struct with tcsetattr() :
Reading And Writing
Now that we have opened and configured the serial port, we can read and write to it!
Writing
Writing to the Linux serial port is done through the write() function. We use the serial_port file descriptor which was returned from the call to open() above.
Reading
Reading is done through the read() function. You have to provide a buffer for Linux to write the data into.
Closing
This is a simple as:
Full Example (Standard Baud Rates)
Issues With Getty
Getty can cause issues with serial communication if it is trying to manage the same tty device that you are attempting to perform serial communications with.
To Stop Getty:
Getty can be hard to stop, as by default if you try and kill the process, a new process will start up immediately.
These instructions apply to older versions of Linux, and/or embedded Linux.
- Load /etc/inittab in your favourite text editor.
- Comment out any lines involving getty and your tty device.
- Save and close the file.
- Run the command
$ init q to reload the /etc/inittab file.
Exclusive Access
It can be prudent to try and prevent other processes from reading/writing to the serial port at the same time you are.
One way to accomplish this is with the flock() system call:
Changing Terminal Settings Are System Wide
Although getting and setting terminal settings are done with a file descriptor, the settings apply to the terminal device itself and will effect all other system applications that are using or going to use the terminal. This also means that terminal setting changes are persistant after the file descriptor is closed, and even after the application that changed the settings is terminated 1 .
Источник