Linux Device Driver Development Cookbook
eBook - ePub

Linux Device Driver Development Cookbook

Develop custom drivers for your embedded Linux applications

  1. 356 pages
  2. English
  3. ePUB (mobile friendly)
  4. Available on iOS & Android
eBook - ePub

Linux Device Driver Development Cookbook

Develop custom drivers for your embedded Linux applications

About this book

Over 30 recipes to develop custom drivers for your embedded Linux applications.

Key Features

  • Use Kernel facilities to develop powerful drivers
  • Via a practical approach, learn core concepts of developing device drivers
  • Program a custom character device to get access to kernel internals

Book Description

Linux is a unified kernel that is widely used to develop embedded systems. As Linux has turned out to be one of the most popular operating systems used, the interest in developing proprietary device drivers has also increased. Device drivers play a critical role in how the system performs and ensures that the device works in the manner intended.

By offering several examples on the development of character devices and how to use other kernel internals, such as interrupts, kernel timers, and wait queue, as well as how to manage a device tree, you will be able to add proper management for custom peripherals to your embedded system. You will begin by installing the Linux kernel and then configuring it. Once you have installed the system, you will learn to use the different kernel features and the character drivers. You will also cover interrupts in-depth and how you can manage them. Later, you will get into the kernel internals required for developing applications. Next, you will implement advanced character drivers and also become an expert in writing important Linux device drivers.

By the end of the book, you will be able to easily write a custom character driver and kernel code as per your requirements.

What you will learn

  • Become familiar with the latest kernel releases (4.19+/5.x) running on the ESPRESSObin devkit, an ARM 64-bit machine
  • Download, configure, modify, and build kernel sources
  • Add and remove a device driver or a module from the kernel
  • Master kernel programming
  • Understand how to implement character drivers to manage different kinds of computer peripherals
  • Become well versed with kernel helper functions and objects that can be used to build kernel applications
  • Acquire a knowledge of in-depth concepts to manage custom hardware with Linux from both the kernel and user space

Who this book is for

This book will help anyone who wants to develop their own Linux device drivers for embedded systems. Having basic hand-on with Linux operating system and embedded concepts is necessary.

Trusted by 375,005 students

Access to over 1 million titles for a fair monthly price.

Study more efficiently using our study tools.

Information

Year
2019
Print ISBN
9781838558802
Edition
1
eBook ISBN
9781838555863

Managing Interrupts and Concurrency

When implementing a device driver, a developer has to resolve two main problems:
  • How to exchange data with peripherals
  • How to manage interrupts that peripherals generate to the CPU
The first point was covered (at least for char drivers) in previous chapters, while the second one (and its related matter) will be the main topic of this chapter.
In the kernel, we can consider the CPU (or the internal core executing some code) running in two main execution contexts — the interrupt context and the process context. The interrupt context is very easy to understand; in fact, the CPU is in this context each time it executes an interrupt handler (that is, special code the kernel executes each time an interrupt occurs). In addition to this, interrupts can be generated by the hardware or even by the software; that's why we talk about hardware interrupts and software interrupts (we'll take a closer look at software interrupts in the following sections), which in turn define the hardware interrupt context and the software interrupt context.
On the other hand, the process context is when the CPU (or one of its internal cores) executes some code of a process in the kernel space (processes also execute in the user space, but we are not covering that here), that is, when the CPU executes the code of a system call that has been invoked by a process (see Chapter 3, Working with Char Drivers). In this situation, it's very common to yield the CPU and then suspend the current process because some data from the peripheral is not ready to be read; for instance; this can be done by asking to the scheduler to take the CPU and then assign it to another process. When this happens we usually say that the current process has gone to sleep, and when data is newly available we say that a process has been awakened, and, it restarts its execution where it was previously interrupted.
In this chapter, we'll see how to do all these actions, how a device driver developer can ask the kernel to suspend the current reading process because the peripheral is not ready to serve the request, and also how to wake up a sleeping process. We'll also see how to manage concurrent access to our driver's methods to avoid data corruption due to a race condition, and how to manage time flow in order to do a specific action after a well-defined amount of time, respecting the possible time constraints a peripheral may require.
We will also look at how to exchange data between a char driver and the userspace, and how to handle those kernel events a driver should be able to manage. The first (and probably the most important) example is how to manage interrupts, followed by how to defer a job "later in time," and how to wait for an event. We can do all these using the following recipes:
  • Implementing an interrupt handler
  • Deferring jobs
  • Managing time with kernel timers
  • Waiting for an event
  • Doing atomic operations

Technical requirements

For more information on this chapter, you can visit the Appendix.
The code and other files used in this chapter can be downloaded from GitHub at https://github.com/giometti/linux_device_driver_development_cookbook/tree/master/chapter_05.

Implementing an interrupt handler

Inside the kernel, an interrupt handler is a function associated with a CPU interrupt line (or pin) that Linux executes whenever the peripheral connected with this line changes the pin status; when this happens, an interrupt request is generated for the CPU, and it's captured by the kernel, which in turn executes the proper handler.
In this recipe, we will see how to install an interrupt handler which the kernel executes each time an interrupt occurs on a well-defined line.

Getting ready

The simplest code to implement an interrupt handler is the code in linux/drivers/misc/dummy-irq.c. Here is the handler:
static int irq = -1;

static irqreturn_t dummy_interrupt(int irq, void *dev_id)
{
static int count = 0;

if (count == 0) {
printk(KERN_INFO "dummy-irq: interrupt occurred on IRQ %d\n",
irq);
count++;
}

return IRQ_NONE;
}
Here is the code to install or to remove it:
static int __init dummy_irq_init(void)
{
if (irq < 0) {
printk(KERN_ERR "dummy-irq: no IRQ given. Use irq=N\n");
return -EIO;
}
if (request_irq(irq, &dummy_interrupt, IRQF_SHARED, "dummy_irq", &irq)) {
printk(KERN_ERR "dummy-irq: cannot register IRQ %d\n", irq);
return -EIO;
}
printk(KERN_INFO "dummy-irq: registered for IRQ %d\n", irq);
return 0;
}

static void __exit dummy_irq_exit(void)
{
printk(KERN_INFO "dummy-irq unloaded\n");
free_irq(irq, &irq);
}
This code is really simple, and, as we can see, it calls the request_irq() function in the dummy_irq_init() module initialization function, and the free_irq() function in the dummy_irq_exit() module exit function. Then, these two functions respectively ask the kernel to connect the dummy_interrupt() interrupt handler to the irq interrupt line and, in the opposite operation, to detach the handler from it.
This code briefly shows how to install an interrupt handler; however, it doesn't show how a device driver's developer can install its own handler; that's why in the next section we're going to do a practical example using a real interrupt line simulated with a General Purpose Input Output line (GPIO).
In order to implement a management for our first interrupt request (IRQ) handler, we can use a normal GPIO as an interrupt line; however, before doing so, we have to verify that our GPIO line correctly detects high and low input levels.
To manage GPIOs we're going to use its sysfs interface so, first of all, we have to verify that it is currently enabled for our kernel by checking if the /sys/class/gpio directory exists. If not we'll have to enable the CONFIG_GPIO_SYSFS kernel configuration entry by using the kernel configuration menu (make menuconfig); the can be done by going to Device Drivers, then GPIO Support, and enabling the /sys/class/gpio/... (sysfs interface) menu entry.
A way to quickly check if the entry is enabled is by using the following command line:
$ rgrep CONFIG_GPIO_SYSFS .config
CONFIG_GPIO_SYSFS=y
Otherwise, if it is not enabled, we'll get the following output, and then we must enable it:
$ rgrep CONFIG_GPIO_SYSFS .config
# CONFIG_GPIO_SYSFS is not set
If everything is in place, we should get something something similar to the following:
# ls /sys/class/gpio/
export gpiochip446 gpiochip476 unexport
The gpiochip446 and gpiochip476 directories represent the two ESPRESSObin's GPIOs controller as we saw in the previous chapter describing the device tree. (See The Armada 3720 section in Appendix of Chapter 4, Using the Device Tree, Configuring CPU's pins for specific peripherals section). The export and unexport files are used to get access to GPIO lines.
To do our job, we need to get access to the MPP2_20 CPU line, which is mapped on pin 12 of the ESPRESSObin extension #2; that is, the connector P8 (or J18) on the ESPRESSObin schematics. (See the Technical requirements section in Chapter 1, Installing the Development System). In the CPU datasheet, we discover that the MPP2_20 line is attached to the second pinctrl controller (named south bridge and mapped as pinctrl_sb: pinctrl@18800 in the device tree). To know which is the right gpiochip device to use, we can still use the sysfs as follows:
# ls ...

Table of contents

  1. Title Page
  2. Copyright and Credits
  3. About Packt
  4. Contributors
  5. Preface
  6. Installing the Development System
  7. A Peek Inside the Kernel
  8. Working with Char Drivers
  9. Using the Device Tree
  10. Managing Interrupts and Concurrency
  11. Miscellaneous Kernel Internals
  12. Advanced Char Driver Operations
  13. Additional Information: Working with Char Drivers
  14. Additional Information: Using the Device Tree
  15. Additional Information: Managing Interrupts and Concurrency
  16. Additional Information: Miscellaneous Kernel Internals
  17. Additional Information: Advanced Char Driver Operations
  18. Other Books You May Enjoy

Frequently asked questions

Yes, you can cancel anytime from the Subscription tab in your account settings on the Perlego website. Your subscription will stay active until the end of your current billing period. Learn how to cancel your subscription
No, books cannot be downloaded as external files, such as PDFs, for use outside of Perlego. However, you can download books within the Perlego app for offline reading on mobile or tablet. Learn how to download books offline
Perlego offers two plans: Essential and Complete
  • Essential is ideal for learners and professionals who enjoy exploring a wide range of subjects. Access the Essential Library with 800,000+ trusted titles and best-sellers across business, personal growth, and the humanities. Includes unlimited reading time and Standard Read Aloud voice.
  • Complete: Perfect for advanced learners and researchers needing full, unrestricted access. Unlock 1.4M+ books across hundreds of subjects, including academic and specialized titles. The Complete Plan also includes advanced features like Premium Read Aloud and Research Assistant.
Both plans are available with monthly, semester, or annual billing cycles.
We are an online textbook subscription service, where you can get access to an entire online library for less than the price of a single book per month. With over 1 million books across 990+ topics, we’ve got you covered! Learn about our mission
Look out for the read-aloud symbol on your next book to see if you can listen to it. The read-aloud tool reads text aloud for you, highlighting the text as it is being read. You can pause it, speed it up and slow it down. Learn more about Read Aloud
Yes! You can use the Perlego app on both iOS and Android devices to read anytime, anywhere — even offline. Perfect for commutes or when you’re on the go.
Please note we cannot support devices running on iOS 13 and Android 7 or earlier. Learn more about using the app
Yes, you can access Linux Device Driver Development Cookbook by Rodolfo Giometti in PDF and/or ePUB format, as well as other popular books in Computer Science & Desktop Applications. We have over one million books available in our catalogue for you to explore.