Exchanging data with a peripheral means sending or receiving data to and from it, and, to do so, we have already seen that we have to use the write() and read() system calls, whose prototypes are defined in the kernel, as follows:
ssize_t write(struct file *filp,
const char __user *buf, size_t count,
loff_t *ppos);
ssize_t read(struct file *filp,
char __user *buf, size_t count,
loff_t *ppos);
On the other hand, their counterparts in user space look like the following:
ssize_t write(int fd, const void *buf, size_t count);
ssize_t read(int fd, void *buf, size_t count);
The preceding prototypes (both in the kernel or user space) look similar but, of course, they have different meanings and, as driver developers we must know perfectly what these meanings are to do our job accurately.
Let's start...