FeatureImage10

Chapter 16: Embedded Kernel Programming

Chapter 16: Embedded Kernel Programming

/Chapter 16: Embedded Kernel Programming
Chapter 16: Embedded Kernel Programming2019-01-22T23:22:56+00:00

Introduction

In this chapter, you are introduced to Linux kernel programming on an embedded device such as a Beagle board. Kernel programming is an advanced topic that requires in-depth study of the source code for the Linux kernel; however, this chapter is structured as a practical step-by-step guide to the focused task of writing Linux loadable kernel modules (LKMs) that interface to general-purpose inputs/outputs (GPIOs). The first example is a straightforward “Hello World” module that can be used to establish a configuration for LKM development on the board. The second LKM example introduces interrupt service routines (ISRs), and interfaces a simple GPIO button and LED circuit to Linux kernel space. Two further examples are provided that introduce the kobject interface and the use of kernel threads to build kernel-space sysfs devices for the board. By the end of this chapter, you should be familiar with the steps required to write kernel code, and appreciate the programming constraints that such development entails.

After completing this chapter, you should be able to do the following:

  • Write a basic Linux loadable kernel module (LKM) that can receive a kernel argument.
  • Build, load, and unload a custom LKM on a Beagle board.
  • Undertake the steps required to build a module for embedded devices that can control GPIOs.
  • Appreciate some of the concepts required to build LKMs on an embedded Linux device, such as interrupts, kobjects, and kernel threads.
Writing a Linux Loadable Kernel Module Part 1

In the series of three articles that are linked here, I describe how you can write a Linux loadable kernel module (LKM) for an embedded Linux device. I begin with a straightforward “Hello World!” loadable kernel module (LKM) and work towards developing a module that can control GPIOs on the BeagleBone through the use of IRQs. This is a complex topic, which I have broken up over a number of articles, each providing a practical example and outcome. There are entire books written on this topic, so it is difficult to cover absolutely every aspect. I have aligned the tasks performed against the configurations that are provided within the book.

The first article, “Writing a Linux Kernel Module — Part 1: Introduction,” was released on the 15th April 2015. It is focused on the system configuration, tools and code required to build and deploy a “Hello World!” kernel module. Please click on the image page on the left to view the full article at my blog site.

Get Source Code

Source Code for this Series of Articles

All of the code for this discussion is available in the GitHub repository for the book Exploring BeagleBone. The code can be viewed publicly at: the ExploringBB GitHub Kernel Project directory, and/or you can clone the repository on your BeagleBone (or other Linux device) by typing:

DoxygenHTML DoxygenPDF

The /extras/kernel/ directory and its sub-directories provide the source code for this series of articles. The auto-generated Doxygen documentation for these code examples is available in HTML format and PDF format.

Get Source Code

The second article, “Writing a Linux Kernel Module — Part 2: A Character Device,” was released on the 18th April 2015. This article describes a straightforward character driver that can be used to pass information between a Linux user-space program and a loadable kernel module (LKM), which is running in Linux kernel space. In this example, a C user-space application sends a string to the LKM. The LKM then responds with the message that was sent along with the number of letters that the sent message contains. Later in the article I describe why we need to solve synchronization problems that arise with this approach, and I provide a version of the program that uses mutexes to provide a solution.

The third article “Writing a Linux Kernel Module — Part 3: Buttons and LEDs” is focused on education and training rather than a deep practical need — I believe that if you can read a button press and flash an LED then you are well on your way to interfacing to most digital devices. Therefore, there are three different LKMs described in this article, each with its own individual purpose and needs:

http://www.derekmolloy.ie/kernel-gpio-programming-buttons-and-leds/
  • Example 1: Button Press, LED Light: In this example an LED lights when a button is pressed — simple! (no not really). To perform this task, the concept of kernel interrupts is introduced and the use of the library of code that can be accessed using linux/gpio.h. This example is used to test the interrupt performance.
  • Example 2: Enhanced Button GPIO Driver: This example is used to introduce kobjects and a mechanism for adding your own entries to Sysfs. This allows you to send data to and receive data from the LKM at run time. The example also introduces the use of timing in kernel code.
  • Example 3: Enhanced LED GPIO Driver: This example is used to flash an LED, which allows for a discussion on Linux kthreads. Essentially, an LED is flashed at a frequency using a kernel module, which can be controlled from Linux user space.

Video Demonstration

A short YouTube video is provided here that presents an overview of the functionality of the LKMs that are developed in this article.

Video 1: A video of the functionality of the LKMs that are described in this article.

Recommended Books on the Content in this Chapter

The following books contain further information on Linux kernel development. It is difficult to get up-to-date books on Linux development, but most of the principles described in these books hold true today:

14 Comments

  1. Rakesh May 7, 2015 at 1:49 am - Reply

    Hi Derek,

    Thanks a lot. I am referring your book for Beagle bone development, its amazing. This book solves hundreds of my questions.
    Thanks once again.
    I would like to run and Dubug the program (/ExploringBB/extras/kernel/gpio_test), the same that you have explained in part3: Buttons and LEDs.
    Actually my target is : I want to put breakpoint in interrupt handler of button press. So when i press the button the program should stop on that breakpoint.
    Please guide for how to proceed.
    Thanks.

    • Derek May 7, 2015 at 12:01 pm - Reply

      Hi Rakesh, I don’t know how you could do that. Sorry, Derek.

      • Rakesh May 15, 2015 at 2:01 am - Reply

        Actually, I would like to run (/ExploringBB/extras/kernel/gpio_test) program in Elclipse IDE with run time debugger.
        one solution i did that, with the use of BBBchroot i solved some of the errors like
        #include
        #include
        #include
        #include
        #include

        but still some errors i need to resolve
        /BBBchroot/usr/src/linux-headers-3.8.13-bone50/include/linux/init.h:255:13: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘parse_early_param’
        /BBBchroot/usr/src/linux-headers-3.8.13-bone50/include/linux/init.h:256:13: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘parse_early_options’
        /BBBchroot/usr/src/linux-headers-3.8.13-bone50/include/linux/linkage.h:5:25: fatal error: asm/linkage.h: No such file or directory

  2. Rakesh May 7, 2015 at 1:52 am - Reply

    for the above program to run, i am using Eclipse IDE.

    Rakesh.

  3. Rakesh K May 29, 2015 at 7:34 am - Reply

    Hi,
    how can i do debugging in kernel for ADC using eclipse luna.

    • Derek May 29, 2015 at 10:51 pm - Reply

      I don’t think that is possible.

  4. David Rodriguez June 23, 2015 at 5:09 pm - Reply

    Hello Derek, I have a problem with my beaglebone I installed via ssh an rt kernel using rsync and after the reboot my beaglebone refuses ssh connection how can I fix this?

    • Derek June 24, 2015 at 1:51 pm - Reply

      Hi there, on solution is that you can use the USB UART TTL 3V3 cable that is described in Chapter 1 to connect to the BBB and ensure that the sshd is running. Alternatively, you could attach a monitor, keyboard, mouse and do the same. Kind regards, Derek.

      • David June 25, 2015 at 5:52 am - Reply

        thank you Derek Ill have to buy it because I disabled the HDMI for pwm outputs and…

      • David June 25, 2015 at 6:00 pm - Reply

        Do I need the HDMI for flashing? or can I just reinstall debian and work with it?

        • Derek June 26, 2015 at 9:48 pm - Reply

          Hi David, No HDMI is not required for flashing — see the guide in Chapter 2. Kind regards, Derek.

  5. Fointard June 28, 2015 at 5:56 pm - Reply

    Hi Derek,
    I’ve been trying to get an LED kernel driver running on my BBB but i’m always getting an error when trying to access the pins :

    [ 195.251541] gpio_request: gpio-53 (sysfs) status -16
    [ 195.251569] gpio_request: gpio-54 (sysfs) status -16
    [ 195.251593] gpio_request: gpio-55 (sysfs) status -16
    [ 195.251617] gpio_request: gpio-56 (sysfs) status -16

    I think -16 stands for EBUSY which is not weird because the default LED kernel driver is actually using the pins (default heartbeat when we boot the board etc…). My driver actually works and make the LEDs blink but I don’t think this is a clean way to do it.

    What i’d like to know is this : how can I disable the default LED kernel driver so that I don’t get this error and the pins are unsused when I request them ? I think I might have to rebuild a custom kernel or mess with the device tree but I just don’t know where to start. Can you help ?

    PS : my code is on GitHub : https://github.com/Fointard/SLD

    • Derek June 30, 2015 at 11:32 am - Reply

      Hi Fointard, my guess is that the device tree overlay notes exclusive use of these pins with GPIO-LEDs and therefore when you use them in your module the requests appear. You would probably have to disable the GPIO-LEDs entry in the DTS for the BBB and then it would be fine (see Chapter 6 and Chapter 3). Kind regards, Derek.

  6. Brett May 11, 2016 at 6:00 pm - Reply

    Excellent addition, very great read. Might have to use soon as well: has anyone else noticed that P9_15 AKA GPIO_48 has stopped responding after updating to the latest 8.3 kernel? I’ve been using that pin as a toggle for months but this kernel broke the function for reasons I cannot discern. An LKM may fix it.

Leave A Comment

Exploring BeagleBone

This is the companion site for the book “Exploring BeagleBone: Tools and Techniques for Building with Embedded Linux” by Derek Molloy. The site structures and contains all of the digital media that is described in the book. Each chapter in the book links to an individual web page, which can be accessed using the menu on the top right-hand side of this page when you close this menu. For details of the book itself, click here.

Recent Works

Latest from Derek Molloy YouTube Channel

Oops, something went wrong.