I want to know whether Linux kernel device driver of serial port device, e.g. /dev/tty1, /dev/tty2, support poll() operation?
Or tell me where is the kernel source code of serial port device?
In my case, some sensors will send data to ARM CPU via serial port each second. And I think one way is to use a timer for periodically read from the serial port. Another way should use poll(), read it when data is ready.
Unless your serial port is a special case, using poll() or select() would seamlessly work.
If your serial port was controlled via USB, you would have to take care about what happens if the USB to serial is disconnected, but this does not seem to be the case for you.
Related
I need to write a program (C++) that uses a serial port to communicate with another device. The other device isn't even built yet so I need a software emulator For various reasons there is no point going into here, the software emulator needs to run on a different machine. I would like to send the data via UDP from the software emulator to the machine my program is running on and have it received by another serial interface type program that in some way acts as a serial port (serial tty device).
I also want to test my program in an automated fashion in a VM. Ideally my test program would also use UDP and would use the same UDP-serial interface program to forward the data back and forwards between my test program and the program under test.
Time is very tight. I don't really have time to learn to write and install kernel level device drivers.
I would be very grateful for any pointers as to how I can create some sort of "pipe" or "loopback" pseudo-serial device.
I am working on Linux.
Credit to meuh for his tip-off.
socat UDP:127.0.0.1:5001,bind=127.0.0.1:5000 \
PTY,link=/dev/ttyS0,raw,echo=0,waitslave
This listens on UDP port 5000 on the loopback network interface. All data received is sent to the virtual serial device at /dev/ttyS0. All data received on the virtual serial device is sent to UDP address 127.0.0.1:5001.
The IP address can be remote.
The command must be run as root, as must the process connecting to the serial port. To avoid this use a different file path, e.g. /tmp/ttyS99.
Apparently the file path specified must not already exist. However my PC has /dev/ttyS0 all the way to /dev/ttyS31 despite not having any serial ports, and using /dev/ttyS0 works fine. I suppose if I actually had a real serial port this wouldn't work.
I am a beginner to Linux drivers and I started with writing an application for a cdc-acm based USB device in linux. Therefore, I have used the cdc_acm driver. The USB device that I am using has 2 Bulk endpoints (read and write) and one interrupts endpoint.
Now, my question is whether all these endpoints operate on the same /dev/ttyACM0 file, and how does the write call on this tty file get convert into acm_write_bulk fops call?
If I write a data to trigger a USB functionality into the ttyACM0 file, will the data get sent through bulk out endpoint? Or how should I send the data to the bulk endpoint directly from user space. Should I write any supporting driver in kernel space?
Similarly, how do I read the data from interrupt endpoint in the userspace?
I appreciate your help in advance.
There is no need to write a kernel space driver. You can open /dev/ttyACM0 with the open system call, set parameters for it using termios (optional), and then use the read and write system calls to read and write bulk data from your device. These system calls are easiest to access from C and C++, but most languages have a library you can use to access serial ports.
I don't know of a great way to read data from the interrupt endpoint in Linux but you can at least look into the TIOCMGET, TIOCGICOUNT, and TIOCMIWAIT ioctls in you really need to do that.
The Linux serial port interface abstracts away all details about USB, endpoints, and bulk transfers, so you can use a simpler, more abstract API to communicate with the serial port. In fact, you can use the same code on any type of serial port, regardless of which kernel driver implements the serial port. It might help you to search the Internet for things like "linux serial port programming" or "posix serial port programming" to understand more about how to do this.
If you really are curious about how the Linux CDC ACM driver works, and how it converts a write system call into the corresponding USB transfer, you can read the source of the cdc-acm driver. However, that is way beyond what you need to do to simply use a serial port.
I'm having an embedded linux device. I'm using ttyO2 as my console.
However, at the same time my MCU need to perform RS232 communicate with a device through ttyO2.
Now lets say if the MCU and the device are communicating, and I type some characters in the console terminal, or there runs another thread that will invoke function printf() , will that conflicts with the 232 communication? is the printf() outputting to the ttyO2?
Thanks
I'm using ttyO2 as my console.
so you configured serial port as console, printf() output will be redirected to console. i.e serial port.
If your board is communicating over RS232 with an external device, then then board and the device are connected with a serial cable. How can you also connect the the serial terminal?
In any case, using the same serial port as console and as a communication port is a bad idea, because there are a lot of things that can be printed: the console I/O, the kernel debug, other programs output to stdout and so on.... Do you think you can have a stable communication with all that "junk" on the wire?
I'm using a linux OS and was wondering if there were any file descriptors I could poll/select which would trigger when data was waiting to be read from a usb device. I am also using the libusb library and have yet to find file descriptors which I can use.
Use libusb's polling functions to hook its file descriptors into your event loop. select will wake up whenever there's activity that libusb will need to handle, which includes but probably is not limited to data being available for reading.
No, USB devices are not always "stream" devices, so reading from a file descriptor doesn't always make sense. However, if your USB device provides a serial port driver, you can listen for incoming data on the serial port device (just like any other serial port handled by your OS).
I am trying to communicate with a device over a RS-485 half duplex serial line. When I send a command to the device, it processes the command and replies immediately after processing. The problem is I have to turn my RS-485 chip into receive mode immediately after sending the command in order to receive the reply of the device. But because my write function of the UART is a non-blocking IO operation I have no way of knowing when to turn my RS-485 chip into receive mode.
How can I do a blocking write operation into the UART that the function will not exit unless all of the bytes are actually sent over the serial line?
What is your hardware platform? I have solved that problem before (atmel AT91SAM9260) by configuring the hardware to automatically set the RTS signal. That is your best bet unless you modify the serial drivers in the kernel (and sometimes not even doing that you can do it)