3
votes

I have recently started learning to write Linux device drivers for a specific project that I am working on. Previously most of the work I have done has been with devices running no OS so Linux drivers and development is somewhat new to me. For the project I am working on I have an embedded system running a Linux based operating system. I have an external device with is controlled via RS232 that I need to write a driver for.

Questions:

1) Is there a way to access serial ports from withing kernel space (and possibly use serial.h, serial_core.h, etc.), how is this usually done, any good examples?

2) From what I found it seems like it would be much easier to access the serial ports in user space by just opening dev/ttyS* and writing to it. When writing a driver for a device like this (RS232 device) is it preferred to do it in user space or is there a way to write a kernel module? How does one decide to write a driver as a kernel module over user space or vise versa?

Are drivers only for generic devices such as UART/serial and then above that is userspace or should this driver be written as a kernel module? I appreciate the help, I have been unable to find much information to answer my questions.

1
Your embedded device runs without a host OS? (in that case there will be no /dev/ttySx, and certainly not a device driver supporting that device node)wildplasser
You probably should not be writing any kernel "drivers" for this serial device. The kernel executes in a privileged CPU mode, and should not be compromised with unnecessary functionality that belongs in userspace. You (should) want your code to be portable, and that means keep it userspace, where APIs are stable. Also you seem confused as to what a "RS232 device driver" does. The driver should only transfer data; it works at the physical layer. It should not examine or process the data in any way (that's for the data-link or line-discipline layer).sawdust
If you have /dev/ttyS*, then you already have a device driver for the UART.DoxyLover
I understand that there is already a UART driver however this does not solve my problem. I want to write a kernel module for a specific device that communicates thru RS232. I want know if there is a way to use the existing serial driver, serial.h (not the tty driver which is what /dev/ttyS* refers to), and "layer" my driver above it so that I can use its functionality rather that rewriting a serial driver myself. Is this possible to do, if so, how?Aaron Redepenning

1 Answers

2
votes

There are a few times when a module that communicates over a serial port may be in the kernel. The pppd (point to point protocol daemon) is one example as Linux has some kernel code devoted to that since it is a high traffic use of serial and it also needs to turn around and put the IP packets into kernel space.

Most other uses would work better from user space since you have a good API that already takes care of a lot of the errors that can happen. This also lessens the chance that your errors will result in massive system failure.

Doing things like this from user space does result in some latency. Reads and writes are buffered, and it's often difficult to tell where in the write operations the hardware actually is, and canceling an already succeeded write call isn't really doable from user space, even if the hardware hasn't yet received the bytes.

I would suggest attempting to do it from user space first and then move to OS driver if necessary. Even if it is necessary to move this into an OS level driver, you'll likely be able to get some progress made from user space.