After the modifications are in place and the new driver version has been recompiled and correctly loaded into ESPRESSObin's kernel, we can again execute our testing program, chrdev_test. We should get the following output:
# ./chrdev_test chrdev
file chrdev opened
wrote 11 bytes into file chrdev
data written are: 44 55 4d 4d 59 20 44 41 54 41 00
read 11 bytes from file chrdev
data read are: 00 00 00 00 00 00 00 00 00 00 00
From the serial console, we should see something as similar to the following:
chrdev_legacy:chrdev_open: chrdev opened
chrdev_legacy:chrdev_write: should write 11 bytes (*ppos=0)
chrdev_legacy:chrdev_write: got 11 bytes (*ppos=11)
chrdev_legacy:chrdev_read: should read 11 bytes (*ppos=11)
chrdev_legacy:chrdev_read: return 11 bytes (*ppos=22)
chrdev_legacy:chrdev_release: chrdev released
OK. We got exactly what we expected! In fact, from kernel messages, we can see the calling of chrdev_open() and then what happens when chrdev_write() and chrdev_read() are called: 11 bytes are transferred and the ppos pointer is moved as we expected. Then, chrdev_release() is called and the file definitely closed.
Now a question: what happens if we call the preceding command again?
Well, we should expect exactly the same output; in fact, each time the file is opened, ppos is re-positioned at the file beginning (that is, to 0) and we continue reading and writing at the same positions.
The following is the output of this second execution:
# ./chrdev_test chrdev
file chrdev opened
wrote 11 bytes into file chrdev
data written are: 44 55 4d 4d 59 20 44 41 54 41 00
read 11 bytes from file chrdev
data read are: 00 00 00 00 00 00 00 00 00 00 00
Additionally, the following are the related kernel messages:
chrdev_legacy:chrdev_open: chrdev opened
chrdev_legacy:chrdev_write: should write 11 bytes (*ppos=0)
chrdev_legacy:chrdev_write: got 11 bytes (*ppos=11)
chrdev_legacy:chrdev_read: should read 11 bytes (*ppos=11)
chrdev_legacy:chrdev_read: return 11 bytes (*ppos=22)
chrdev_legacy:chrdev_release: chrdev released
If we wish to read the data just written data, we can modify the chrdev_test program in such a way it will close and then reopen the file after calling write():
...
printf("wrote %d bytes into file %s\n", n, argv[1]);
dump("data written are: ", buf, n);
}
close(fd);
ret = open(argv[1], O_RDWR);
if (ret < 0) {
perror("open");
exit(EXIT_FAILURE);
}
printf("file %s reopened\n", argv[1]);
fd = ret;
for (c = 0; c < sizeof(buf); c += n) {
ret = read(fd, buf, sizeof(buf));
...
$ patch -p2 < modify_close_open_to_chrdev_test.patch
Now, if we try to execute chrdev_test again, we should get the following output:
# ./chrdev_test chrdev
file chrdev opened
wrote 11 bytes into file chrdev
data written are: 44 55 4d 4d 59 20 44 41 54 41 00
file chrdev reopened
read 11 bytes from file chrdev
data read are: 44 55 4d 4d 59 20 44 41 54 41 00
Perfect! Now, we read exactly what we wrote and, from the kernel space, we get the following messages:
chrdev_legacy:chrdev_open: chrdev opened
chrdev_legacy:chrdev_write: should write 11 bytes (*ppos=0)
chrdev_legacy:chrdev_write: got 11 bytes (*ppos=11)
chrdev_legacy:chrdev_release: chrdev released
chrdev_legacy:chrdev_open: chrdev opened
chrdev_legacy:chrdev_read: should read 11 bytes (*ppos=0)
chrdev_legacy:chrdev_read: return 11 bytes (*ppos=11)
chrdev_legacy:chrdev_release: chrdev released
Now, we can see perfectly what happens to ppos, and how the chrdev_read() and chrdev_write() methods work in order to exchange data with the user space.