0% found this document useful (0 votes)
83 views4 pages

Serial Device Driver Project

This document describes work done on a serial device driver project. It details the implementation of both a poll-based driver (serp.c) and an interrupt-based driver (seri.c) with various enhancements. These include error handling, minimizing global variables, eliminating race conditions, supporting O_NONBLOCK, adding ioctl operations, and interrupting processes inside read() syscalls. Test files were also created to test the drivers' functionality. Issues were encountered when trying to use a newer version of the usocat testing program versus the original version provided for labs.

Uploaded by

Tiaga
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
83 views4 pages

Serial Device Driver Project

This document describes work done on a serial device driver project. It details the implementation of both a poll-based driver (serp.c) and an interrupt-based driver (seri.c) with various enhancements. These include error handling, minimizing global variables, eliminating race conditions, supporting O_NONBLOCK, adding ioctl operations, and interrupting processes inside read() syscalls. Test files were also created to test the drivers' functionality. Issues were encountered when trying to use a newer version of the usocat testing program versus the original version provided for labs.

Uploaded by

Tiaga
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

 

Universidade do Porto - Faculdade de Engenharia


Mestrado Integrado em Engenharia Electrotécnica e de Computadores
Sistemas Operativos — 2018/19
 

Serial Device Driver Project


Group number 201709727_201606535

Ana Rita Martinho, up201709727

André Ribeiro Aragão, up201606535

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.

Minimization of global variables


Global variables are only used in the module's initialization and finalization functions -
seri_init() and seri_exit(), respectively.
In other functions when such data is need it is obtained by accessing the arguments of
the function itself. Therefore, the use of global variables is minimized.

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

Elimination of race conditions


We implemented an additional spinlock named “multi_user_lock” and an int variable
named “being_used” that is 1 if the device is already being used, and 0 if not. Both variables are
in the structure seri_dev_t, defined at the beginning of the file. This way we ensure the
elimination of race conditions: The lock is acquired at the beginning of seri_open(), and released
immediately if “being_used” is already 1. Otherwise, “being_used” is incremented and no other
user will be able to use the device. The lock is released when exiting.

Use of O_NONBLOCK flag


The O_NONBLOCK flag value is checked at the start of both read and write functions to
ensure the program exits when, otherwise, it would block (or busy wait). It is passed as an
argument in the open() syscalls present in the test files (test_write, test_read and test_ioctl).
 
Universidade do Porto - Faculdade de Engenharia
Mestrado Integrado em Engenharia Electrotécnica e de Computadores
Sistemas Operativos — 2018/19
 

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.

Interrupting a process inside a read() syscall


There is no need to implement such feature in write() because we only copy data from
one buffer to another, as opposed to the read() function that has got a waiting loop.
To ensure a process never gets stuck trying to receive data that will never arrive, using
the returning value “-ERESTARTSYS” from function wait_event_interruptible_timeout(), it stops
as soon as it receives a signal, such as “ctrl” + “c”.

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
 

Newest version of usocat.c


We would like to address here some conclusions regarding the newest version of
usocat.c provided. We encountered some difficulties trying to send or receive a file (for
example, usocat.c) when following the instructions provided via email. Using the first version of
usocat, and our test files to debug our program, we didn’t encounter any issues.
When trying to run our test programs with the new version of usocat the interrupt handler
wasn’t working.

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”.

You might also like