Components of Device Driver

To interact with the hardware, driver needs to communicate with the kernel and before that, it must notify the kernel about its presence. This is achieved by the “init” call by which the driver is registered with the kernel and allocated the memory it wants. At the time of system shut down, the driver is unregistered using the “exit” call that also frees all the resources occupied by the driver. The calls that are used to define the “init” and “exit” functions are:
module_init(init_function_name);
module_exit(exit_function_name);

We can write our own init and exit functions while writing a device driver that would be called by the above two calls respectively. The simplest init function could be as follows:
static int init_function_name(void)
{
printk(KERN_ALERT “Hello”);
return 0;
}

Similarly, we can write the exit function as well. As you can see, for getting the kernel logs, we use the printk() function that is similar to the C function printf() but requires an optional special log level string (here KERN_ALERT – log level 1) to indicate the type of severity of the error message. There are eight log levels in total and the default is KERN_WARNING(log level 4).

One of the most important component in the device driver is the file operations(“fops” in short) structure. This structure specifies the capability of the device for which the driver is being written. It contains the pointers to the functions written for the operations to be supported by the device. The basic fops structure can be described as below:
static struct file_operations fops=
{
.read=my_read;
.write=my_write;
.open=my_open;
.release=my_release;
}

The above defines that whenever the device has to read something, my_read function(written by the developer) will be called. Similarly, the pointers to the other functions are the corresponding names of the functions mentioned against them.

If the device for which the driver is being written supports the interrupt facility, the driver must register the Interrupt Service Routine(ISR) in the init function that would be called whenever an interrupt is received in the device. This is achieved by using the kernel function request_irq() that requires the interrupt handler and then enables the interrupt line for receiving the interrupts. On the other side, free_irq() kernel function is used to free the interrupt handler and the interrupt line when the driver unloads. We will address them in our future posts in detail.

(…Previous Article)                                                                                       (…Next Article)

Gautam Vashisht

Leave a Reply

Your email address will not be published. Required fields are marked *