What is the difference when you send/receive data via Linux serial device file like ttyS3 and when you directly read/write from/to UART FIFO buffers? What situation is more safe and better?

How device file ttyS and UART FIFO buffers are connected, how do they communicate?

Will Linux have a problem if we directly read/write from FIFO buffers, instead of using drivers made for that purpose?

  • \$\begingroup\$ Through the serial driver. \$\endgroup\$ – Ignacio Vazquez-Abrams Sep 11 '15 at 7:25
  • \$\begingroup\$ What problem are you trying to solve? \$\endgroup\$ – CL. Sep 11 '15 at 7:53
  • \$\begingroup\$ When I read data from device file (communicating with my GSM module) I am receiving what I need, but it somehow repeats data and reading me data that was received earlier, maybe it is a problem in linux UART device driver, so that file is not correctly erased or it is a problem with FIFO buffers, I dont know. @CL. \$\endgroup\$ – Junior Sep 11 '15 at 8:06
  • 1
    \$\begingroup\$ You should use the OS driver whenever possible, because it makes your software independent of the actual hardware (USB-serial converter? Bluethooth remote serial interface?). Use the hardware directly only when you realy realy have to. \$\endgroup\$ – Wouter van Ooijen Sep 11 '15 at 8:08
  • 1
    \$\begingroup\$ The chance that such a problem is in the device drivers is not zero, but I would worry about a meteorite strike first. \$\endgroup\$ – Wouter van Ooijen Sep 11 '15 at 8:10

The device driver itself works by ultimately by just writing to the UART FIFO and control registers.

The main reason why you typically would want to use the driver rather than writing to the UART directly is because the driver gives you a layer of abstraction. It lets you treat that UART like other UARTs, and even sometimes like any other file. You do not need to know which bit is the Data Ready Bit and what the divisor registers are for the UART you happened to be using since the driver makes all UARTs look pretty much the same. Additionally, the driver typically gives you a nice big managed buffer on top of the FIFOs and handles all the interrupts, which requires writing some specialized code under Linux.

That said, there are times when writing directly to the UART can give you control that is not available though the driver. Here is a project where I skip the Linux device driver on a Raspberry PI and go directly to the UART to be able to generate signals for a WS2812B...


This would not be possible to do via the driver because it depends on some quirks of the specific UART, along with some state transitions that there is no way to reliably get the driver to do in the right order.

In cases where you do decide to write directly to the UART, it is probably a good idea to disable the driver to avoid conflicts. For example, if you are trying to read bytes out of the FIFO via your userspace program, it is likely that the driver will also be reading bytes and will likely win because it gets gets triggered off of interrupts. Similarly, you might change some register directly while the driver assumes that register will stay set to whatever it initialized it to (or vice versa).


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.