Serial Device Driver Project
Serial Device Driver Project
Summary
We have implemented a poll-based device driver (serp.c) with the features described in
Lab 3.
After that, we implemented the interrupt-based device driver (seri.c) with the features
described in Lab 4. Subsequently, we implemented enhancements to the interrupt-based device
driver, as described in Lab 5:
- Error Handling
- Minimization of global variables
- Elimination of race conditions
- Use of O_NONBLOCK flag
- Ioctl operations
- Interrupting a process inside a read() syscall
We tried to make the code as readable as possible, using variables with logical names
(for example, “number_of_characters_fifo_received” as opposed to something like “fifo1”) and
making brief comments where we think the code is not explicit enough.
We would like to address the fact that our device driver was tested and implemented
based on the version of usocat.c made available for the lab classes. It was brought to our
attention there was an update of the usocat.c file approximately 3 days before the submission
deadline. We didn’t have time to make it work correctly with this new version so we will send the
usable usocat.c in the zip file.
Universidade do Porto - Faculdade de Engenharia
Mestrado Integrado em Engenharia Electrotécnica e de Computadores
Sistemas Operativos — 2018/19
Enhancements
Error Handling
By analysing the errno library we were able to implement the returning values that better
express the errors predicted in our program. All error name’s are explain in seri.c.
Example
After minimizing global variables, static struct seri_dev_t *serie_device is no longer
accessed as global variable but is now access through struct file *filep in seri_write() as follows:
((struct seri_dev_t *)filep->private_data)->tx_fifo
ioctl() operations
We wrote the ioctl() function in order to empower the user (working in user space) with
the ability to change and review parameters only available in kernel space, such as:
- Getting the current LCR value
- Configuring the LCR parameters and, therefore, changing it’s value
- Resetting the LCR value
- Changing the baudrate
In order for the function to work it was added to the file operations struct.
In addition, we provide a test file (test_ioctl.c) which calls ioctl() with the different macros
available so it tests all the available operations.
Test files
Both DD’s serp and seri have 2 test files: test_read and test_write. Seri DD also has a
file to test the ioctl operations, named test_ioctl. The way they are meant to work is very
straightforward:
- Type “make” to make all the executable files in the .../test directory
- Run the program you want by typing:
- ./test_read to test the read operation *
- ./test_write to test the write operation
- ./test_ioctl to test the ioctl operations (only implemented in Seri DD)
- Follow the instructions presented in the terminal to ensure the correct behavior of the
test programs
All programs are very easy to use to ensure the optimal feedback from the user.
* To the tester: In Seri DD, since the file is being opened with the O_NONBLOCK flag
(line 23), if there isn’t already a character in the receiver buffer, it will return immediately (as it’s
supposed). If you desire, you may remove the O_NONBLOCK flag from line 23 and recompile.
After that, you can run ./test_read in the host device and only after that send a character.
Universidade do Porto - Faculdade de Engenharia
Mestrado Integrado em Engenharia Electrotécnica e de Computadores
Sistemas Operativos — 2018/19
Reading a data file from the serial port using the new usocat.c
When trying to send a file, our device driver wouldn’t stop trying to acquire new data by
itself. We investigated the issue and came to the conclusion that the count value that is being
passed to the DD by the new version of usocat.c is 4096 (when the file it is trying to transfer is
10795 bytes), which is not to be expect by our program - we expect the full lenght of the file so
we can process all data, and not segments of data (in this case, 3 segments of size: 4096, 4096
and 2603) so the program has to be called multiple times. This causes our program to have
unexpected results.
Writing a data file to the serial port using the new usocat.c
When trying to send a file, we weren’t even able to run the program since we received
the error “Permission denied”.