Exploring BeagleBone: LKMs (by Derek Molloy)  V1.0
This project describes how you can build loadable kernel modules (LKMs) on your BeagleBone platform
 All Files Functions Variables Enumerations Enumerator Macros
Enumerations | Functions | Variables
led.c File Reference

A kernel module for controlling a simple LED (or any signal) that is connected to a GPIO. It is threaded in order that it can flash the LED. The sysfs entry appears at /sys/ebb/led49. More...

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/kobject.h>
#include <linux/kthread.h>
#include <linux/delay.h>
Include dependency graph for led.c:

Enumerations

enum  modes { OFF, ON, FLASH }
 

Functions

 MODULE_LICENSE ("GPL")
 
 MODULE_AUTHOR ("Derek Molloy")
 
 MODULE_DESCRIPTION ("A simple Linux LED driver LKM for the BBB")
 
 MODULE_VERSION ("0.1")
 
 module_param (gpioLED, uint, S_IRUGO)
 Param desc. S_IRUGO can be read/not changed. More...
 
 MODULE_PARM_DESC (gpioLED," GPIO LED number (default=49)")
 parameter description More...
 
 module_param (blinkPeriod, uint, S_IRUGO)
 Param desc. S_IRUGO can be read/not changed. More...
 
 MODULE_PARM_DESC (blinkPeriod," LED blink period in ms (min=1, default=1000, max=10000)")
 
static ssize_t mode_show (struct kobject *kobj, struct kobj_attribute *attr, char *buf)
 A callback function to display the LED mode. More...
 
static ssize_t mode_store (struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
 A callback function to store the LED mode using the enum above. More...
 
static ssize_t period_show (struct kobject *kobj, struct kobj_attribute *attr, char *buf)
 A callback function to display the LED period. More...
 
static ssize_t period_store (struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
 A callback function to store the LED period value. More...
 
static int flash (void *arg)
 The pointer to the thread task. More...
 
static int __init ebbLED_init (void)
 The LKM initialization function The static keyword restricts the visibility of the function to within this C file. The __init macro means that for a built-in driver (not a LKM) the function is only used at initialization time and that it can be discarded and its memory freed up after that point. In this example this function sets up the GPIOs and the IRQ. More...
 
static void __exit ebbLED_exit (void)
 The LKM cleanup function Similar to the initialization function, it is static. The __exit macro notifies that if this code is used for a built-in driver (not a LKM) that this function is not required. More...
 
 module_init (ebbLED_init)
 
 module_exit (ebbLED_exit)
 

Variables

static unsigned int gpioLED = 49
 Default GPIO for the LED is 49. More...
 
static unsigned int blinkPeriod = 1000
 The blink period in ms. More...
 
static char ledName [7] = "ledXXX"
 Null terminated default string – just in case. More...
 
static bool ledOn = 0
 Is the LED on or off? Used for flashing. More...
 
static enum modes mode = FLASH
 Default mode is flashing. More...
 
static struct kobj_attribute period_attr = __ATTR(blinkPeriod, 0666, period_show, period_store)
 
static struct kobj_attribute mode_attr = __ATTR(mode, 0666, mode_show, mode_store)
 
static struct attribute * ebb_attrs []
 
static struct attribute_group attr_group
 
static struct kobject * ebb_kobj
 
static struct task_struct * task
 The pointer to the kobject. More...
 

Detailed Description

A kernel module for controlling a simple LED (or any signal) that is connected to a GPIO. It is threaded in order that it can flash the LED. The sysfs entry appears at /sys/ebb/led49.

Author
Derek Molloy
Date
19 April 2015
See also
http://www.derekmolloy.ie/

Enumeration Type Documentation

enum modes
Enumerator
OFF 
ON 
FLASH 
34 { OFF, ON, FLASH };
Definition: led.c:34
Definition: led.c:34
Definition: led.c:34

Function Documentation

static void __exit ebbLED_exit ( void  )
static

The LKM cleanup function Similar to the initialization function, it is static. The __exit macro notifies that if this code is used for a built-in driver (not a LKM) that this function is not required.

168  {
169  kthread_stop(task); // Stop the LED flashing thread
170  kobject_put(ebb_kobj); // clean up -- remove the kobject sysfs entry
171  gpio_set_value(gpioLED, 0); // Turn the LED off, indicates device was unloaded
172  gpio_unexport(gpioLED); // Unexport the Button GPIO
173  gpio_free(gpioLED); // Free the LED GPIO
174  printk(KERN_INFO "EBB LED: Goodbye from the EBB LED LKM!\n");
175 }
static struct task_struct * task
The pointer to the kobject.
Definition: led.c:103
static struct kobject * ebb_kobj
Definition: led.c:102
static unsigned int gpioLED
Default GPIO for the LED is 49.
Definition: led.c:24
static int __init ebbLED_init ( void  )
static

The LKM initialization function The static keyword restricts the visibility of the function to within this C file. The __init macro means that for a built-in driver (not a LKM) the function is only used at initialization time and that it can be discarded and its memory freed up after that point. In this example this function sets up the GPIOs and the IRQ.

Returns
returns 0 if successful
132  {
133  int result = 0;
134 
135  printk(KERN_INFO "EBB LED: Initializing the EBB LED LKM\n");
136  sprintf(ledName, "led%d", gpioLED); // Create the gpio115 name for /sys/ebb/led49
137 
138  ebb_kobj = kobject_create_and_add("ebb", kernel_kobj->parent); // kernel_kobj points to /sys/kernel
139  if(!ebb_kobj){
140  printk(KERN_ALERT "EBB LED: failed to create kobject\n");
141  return -ENOMEM;
142  }
143  // add the attributes to /sys/ebb/ -- for example, /sys/ebb/led49/ledOn
144  result = sysfs_create_group(ebb_kobj, &attr_group);
145  if(result) {
146  printk(KERN_ALERT "EBB LED: failed to create sysfs group\n");
147  kobject_put(ebb_kobj); // clean up -- remove the kobject sysfs entry
148  return result;
149  }
150  ledOn = true;
151  gpio_request(gpioLED, "sysfs"); // gpioLED is 49 by default, request it
152  gpio_direction_output(gpioLED, ledOn); // Set the gpio to be in output mode and turn on
153  gpio_export(gpioLED, false); // causes gpio49 to appear in /sys/class/gpio
154  // the second argument prevents the direction from being changed
155 
156  task = kthread_run(flash, NULL, "LED_flash_thread"); // Start the LED flashing thread
157  if(IS_ERR(task)){ // Kthread name is LED_flash_thread
158  printk(KERN_ALERT "EBB LED: failed to create the task\n");
159  return PTR_ERR(task);
160  }
161  return result;
162 }
static char ledName[7]
Null terminated default string – just in case.
Definition: led.c:32
static struct attribute_group attr_group
Definition: led.c:97
static struct task_struct * task
The pointer to the kobject.
Definition: led.c:103
static struct kobject * ebb_kobj
Definition: led.c:102
static unsigned int gpioLED
Default GPIO for the LED is 49.
Definition: led.c:24
static bool ledOn
Is the LED on or off? Used for flashing.
Definition: led.c:33
static int flash(void *arg)
The pointer to the thread task.
Definition: led.c:110
static int flash ( void *  arg)
static

The pointer to the thread task.

The LED Flasher main kthread loop

Parameters
argA void pointer used in order to pass data to the thread
Returns
returns 0 if successful
110  {
111  printk(KERN_INFO "EBB LED: Thread has started running \n");
112  while(!kthread_should_stop()){ // Returns true when kthread_stop() is called
113  set_current_state(TASK_RUNNING);
114  if (mode==FLASH) ledOn = !ledOn; // Invert the LED state
115  else if (mode==ON) ledOn = true;
116  else ledOn = false;
117  gpio_set_value(gpioLED, ledOn); // Use the LED state to light/turn off the LED
118  set_current_state(TASK_INTERRUPTIBLE);
119  msleep(blinkPeriod/2); // millisecond sleep for half of the period
120  }
121  printk(KERN_INFO "EBB LED: Thread has run to completion \n");
122  return 0;
123 }
Definition: led.c:34
Definition: led.c:34
static unsigned int gpioLED
Default GPIO for the LED is 49.
Definition: led.c:24
static bool ledOn
Is the LED on or off? Used for flashing.
Definition: led.c:33
static enum modes mode
Default mode is flashing.
Definition: led.c:35
static unsigned int blinkPeriod
The blink period in ms.
Definition: led.c:28
static ssize_t mode_show ( struct kobject *  kobj,
struct kobj_attribute *  attr,
char *  buf 
)
static

A callback function to display the LED mode.

Parameters
kobjrepresents a kernel object device that appears in the sysfs filesystem
attrthe pointer to the kobj_attribute struct
bufthe buffer to which to write the number of presses
Returns
return the number of characters of the mode string successfully displayed
43  {
44  switch(mode){
45  case OFF: return sprintf(buf, "off\n"); // Display the state -- simplistic approach
46  case ON: return sprintf(buf, "on\n");
47  case FLASH: return sprintf(buf, "flash\n");
48  default: return sprintf(buf, "LKM Error\n"); // Cannot get here
49  }
50 }
Definition: led.c:34
Definition: led.c:34
static enum modes mode
Default mode is flashing.
Definition: led.c:35
Definition: led.c:34
static ssize_t mode_store ( struct kobject *  kobj,
struct kobj_attribute *  attr,
const char *  buf,
size_t  count 
)
static

A callback function to store the LED mode using the enum above.

53  {
54  // the count-1 is important as otherwise the \n is used in the comparison
55  if (strncmp(buf,"on",count-1)==0) { mode = ON; } // strncmp() compare with fixed number chars
56  else if (strncmp(buf,"off",count-1)==0) { mode = OFF; }
57  else if (strncmp(buf,"flash",count-1)==0) { mode = FLASH; }
58  return count;
59 }
Definition: led.c:34
Definition: led.c:34
static enum modes mode
Default mode is flashing.
Definition: led.c:35
Definition: led.c:34
MODULE_AUTHOR ( "Derek Molloy"  )
MODULE_DESCRIPTION ( "A simple Linux LED driver LKM for the BBB"  )
module_exit ( ebbLED_exit  )
module_init ( ebbLED_init  )

This next calls are mandatory – they identify the initialization function and the cleanup function (as above).

MODULE_LICENSE ( "GPL"  )
module_param ( gpioLED  ,
uint  ,
S_IRUGO   
)

Param desc. S_IRUGO can be read/not changed.

module_param ( blinkPeriod  ,
uint  ,
S_IRUGO   
)

Param desc. S_IRUGO can be read/not changed.

MODULE_PARM_DESC ( gpioLED  ,
" GPIO LED number (default=49)"   
)

parameter description

MODULE_PARM_DESC ( blinkPeriod  ,
" LED blink period in ms (min=1, default=1000, max=10000)"   
)
MODULE_VERSION ( "0.1"  )
static ssize_t period_show ( struct kobject *  kobj,
struct kobj_attribute *  attr,
char *  buf 
)
static

A callback function to display the LED period.

62  {
63  return sprintf(buf, "%d\n", blinkPeriod);
64 }
static unsigned int blinkPeriod
The blink period in ms.
Definition: led.c:28
static ssize_t period_store ( struct kobject *  kobj,
struct kobj_attribute *  attr,
const char *  buf,
size_t  count 
)
static

A callback function to store the LED period value.

67  {
68  unsigned int period; // Using a variable to validate the data sent
69  sscanf(buf, "%du", &period); // Read in the period as an unsigned int
70  if ((period>1)&&(period<=10000)){ // Must be 2ms or greater, 10secs or less
71  blinkPeriod = period; // Within range, assign to blinkPeriod variable
72  }
73  return period;
74 }
static unsigned int blinkPeriod
The blink period in ms.
Definition: led.c:28

Variable Documentation

struct attribute_group attr_group
static
Initial value:
= {
.name = ledName,
.attrs = ebb_attrs,
}
static char ledName[7]
Null terminated default string – just in case.
Definition: led.c:32
static struct attribute * ebb_attrs[]
Definition: led.c:87

The attribute group uses the attribute array and a name, which is exposed on sysfs – in this case it is gpio49, which is automatically defined in the ebbLED_init() function below using the custom kernel parameter that can be passed when the module is loaded.

unsigned int blinkPeriod = 1000
static

The blink period in ms.

struct attribute* ebb_attrs[]
static
Initial value:
= {
&period_attr.attr,
&mode_attr.attr,
NULL,
}
static struct kobj_attribute period_attr
Definition: led.c:81
static struct kobj_attribute mode_attr
Definition: led.c:82

The ebb_attrs[] is an array of attributes that is used to create the attribute group below. The attr property of the kobj_attribute is used to extract the attribute struct

struct kobject* ebb_kobj
static
unsigned int gpioLED = 49
static

Default GPIO for the LED is 49.

char ledName[7] = "ledXXX"
static

Null terminated default string – just in case.

bool ledOn = 0
static

Is the LED on or off? Used for flashing.

enum modes mode = FLASH
static

Default mode is flashing.

struct kobj_attribute mode_attr = __ATTR(mode, 0666, mode_show, mode_store)
static
struct kobj_attribute period_attr = __ATTR(blinkPeriod, 0666, period_show, period_store)
static

Use these helper macros to define the name and access levels of the kobj_attributes The kobj_attribute has an attribute attr (name and mode), show and store function pointers The period variable is associated with the blinkPeriod variable and it is to be exposed with mode 0666 using the period_show and period_store functions above

struct task_struct* task
static

The pointer to the kobject.