Skip to content
Advertisement

Serial port hangs on close()

I developed this simple kernel module, which emulates a serial port by using a FIFO queue and a timer (read from hardware : out from the queue, write to hardware : insert in the queue).
Source code is shown next.

JavaScript

Then, I wrote a simple test-application which configures the port settings (baud rate, parity, stop bits, etc) and starts a write + read transaction, reading the previously written string.
Source code is shown next.

JavaScript

My problem is: the test application works fine (i can write and read my own string) until it reaches the close(2) function: there it hangs forever, without reaching the end of the program (I must close it with CTRL+C, and then it closes properly as the kernel module calls the tiny_shutdown() function).
I also tried to write a simple program to open and close the /dev/ttytiny0 device, but the result is the same (although I noticed that, if i remove the close(2) operation, the program still hangs without terminating, but this time I couldn’t shut it down with CTRL+C).
Any link/reference to books or material on the subject will be highly appreciated.
Thanks in advance!

Edit : Reporting here the kernel log messages (while running test application)

JavaScript

Note that the sequence tiny_stop_rx() – tiny_tx_empty() – tiny_set_mctrl() – tiny_shutdown() gets called when I terminate the test-application execution with CTRL+C.
Other repeated messages (the sequence tiny_timer() – tiny_tx_chars() – tiny_stop_tx()) are generated by the timer which checks if something has to be transmitted (but the queue is empty, so it sleeps again).
Of course, the test-application logs show a correct behavior, until reaching the close() function.

Advertisement

Answer

Your implementation returns 0 from tx_empty() which means “not empty“.

From kernel.org/doc/Documentation/serial/driver:

tx_empty(port)

This function tests whether the transmitter fifo and shifter for the port described by ‘port’ is empty. If it is empty, this function should return TIOCSER_TEMT, otherwise return 0. If the port does not support this operation, then it should return TIOCSER_TEMT.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement