An introductory character driver to support the second article of my series on Linux loadable kernel module (LKM) development. This module maps to /dev/ebbchar and comes with a helper C program that can be run in Linux user space to communicate with this the LKM. This version has mutex locks to deal with synchronization problems.
More...
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/mutex.h>
|
#define | DEVICE_NAME "ebbchar" |
| The device will appear at /dev/ebbchar using this value. More...
|
|
#define | CLASS_NAME "ebb" |
| The device class – this is a character device driver. More...
|
|
|
| MODULE_LICENSE ("GPL") |
| The license type – this affects available functionality. More...
|
|
| MODULE_AUTHOR ("Derek Molloy") |
| The author – visible when you use modinfo. More...
|
|
| MODULE_DESCRIPTION ("A simple Linux char driver for the BBB") |
| The description – see modinfo. More...
|
|
| MODULE_VERSION ("0.1") |
| A version number to inform users. More...
|
|
static | DEFINE_MUTEX (ebbchar_mutex) |
| Macro to declare a new mutex. More...
|
|
static int | dev_open (struct inode *, struct file *) |
| The prototype functions for the character driver – must come before the struct definition. More...
|
|
static int | dev_release (struct inode *inodep, struct file *filep) |
| The device release function that is called whenever the device is closed/released by the userspace program. More...
|
|
static ssize_t | dev_read (struct file *filep, char *buffer, size_t len, loff_t *offset) |
| This function is called whenever device is being read from user space i.e. data is being sent from the device to the user. In this case is uses the copy_to_user() function to send the buffer string to the user and captures any errors. More...
|
|
static ssize_t | dev_write (struct file *filep, const char *buffer, size_t len, loff_t *offset) |
| This function is called whenever the device is being written to from user space i.e. data is sent to the device from the user. The data is copied to the message[] array in this LKM using message[x] = buffer[x]. More...
|
|
static int __init | ebbchar_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. More...
|
|
static void __exit | ebbchar_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 (ebbchar_init) |
| A module must use the module_init() module_exit() macros from linux/init.h, which identify the initialization function at insertion time and the cleanup function (as listed above) More...
|
|
| module_exit (ebbchar_exit) |
|
An introductory character driver to support the second article of my series on Linux loadable kernel module (LKM) development. This module maps to /dev/ebbchar and comes with a helper C program that can be run in Linux user space to communicate with this the LKM. This version has mutex locks to deal with synchronization problems.
- Author
- Derek Molloy
- Date
- 7 April 2015
- Version
- 0.1
- See also
- http://www.derekmolloy.ie/ for a full description and follow-up descriptions.
The device class – this is a character device driver.
#define DEVICE_NAME "ebbchar" |
The device will appear at /dev/ebbchar using this value.
static DEFINE_MUTEX |
( |
ebbchar_mutex |
| ) |
|
|
static |
Macro to declare a new mutex.
static int dev_open |
( |
struct inode * |
inodep, |
|
|
struct file * |
filep |
|
) |
| |
|
static |
The prototype functions for the character driver – must come before the struct definition.
The device open function that is called each time the device is opened This will only increment the numberOpens counter in this case.
- Parameters
-
inodep | A pointer to an inode object (defined in linux/fs.h) |
filep | A pointer to a file object (defined in linux/fs.h) |
115 if(!mutex_trylock(&ebbchar_mutex)){
116 printk(KERN_ALERT
"EBBChar: Device in use by another process");
120 printk(KERN_INFO
"EBBChar: Device has been opened %d time(s)\n",
numberOpens);
static int numberOpens
Counts the number of times the device is opened.
Definition: ebbcharmutex.c:31
static ssize_t dev_read |
( |
struct file * |
filep, |
|
|
char * |
buffer, |
|
|
size_t |
len, |
|
|
loff_t * |
offset |
|
) |
| |
|
static |
This function is called whenever device is being read from user space i.e. data is being sent from the device to the user. In this case is uses the copy_to_user() function to send the buffer string to the user and captures any errors.
- Parameters
-
filep | A pointer to a file object (defined in linux/fs.h) |
buffer | The pointer to the buffer to which this function writes the data |
len | The length of the b |
offset | The offset if required |
138 printk(KERN_INFO
"EBBChar: Sent %d characters to the user\n",
size_of_message);
142 printk(KERN_INFO
"EBBChar: Failed to send %d characters to the user\n", error_count);
static short size_of_message
Used to remember the size of the string stored.
Definition: ebbcharmutex.c:30
static char message[256]
Memory for the string that is passed from userspace.
Definition: ebbcharmutex.c:29
static int dev_release |
( |
struct inode * |
inodep, |
|
|
struct file * |
filep |
|
) |
| |
|
static |
The device release function that is called whenever the device is closed/released by the userspace program.
- Parameters
-
inodep | A pointer to an inode object (defined in linux/fs.h) |
filep | A pointer to a file object (defined in linux/fs.h) |
169 mutex_unlock(&ebbchar_mutex);
170 printk(KERN_INFO
"EBBChar: Device successfully closed\n");
static ssize_t dev_write |
( |
struct file * |
filep, |
|
|
const char * |
buffer, |
|
|
size_t |
len, |
|
|
loff_t * |
offset |
|
) |
| |
|
static |
This function is called whenever the device is being written to from user space i.e. data is sent to the device from the user. The data is copied to the message[] array in this LKM using message[x] = buffer[x].
- Parameters
-
filep | A pointer to a file object |
buffer | The buffer to that contains the string to write to the device |
len | The length of the array of data that is being passed in the const char buffer |
offset | The offset if required |
157 sprintf(
message,
"%s(%d letters)", buffer, len);
159 printk(KERN_INFO
"EBBChar: Received %d characters from the user\n", len);
static short size_of_message
Used to remember the size of the string stored.
Definition: ebbcharmutex.c:30
static char message[256]
Memory for the string that is passed from userspace.
Definition: ebbcharmutex.c:29
static void __exit ebbchar_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.
100 mutex_destroy(&ebbchar_mutex);
105 printk(KERN_INFO
"EBBChar: Goodbye from the LKM!\n");
static int majorNumber
Store the device number – determined automatically.
Definition: ebbcharmutex.c:28
#define DEVICE_NAME
The device will appear at /dev/ebbchar using this value.
Definition: ebbcharmutex.c:20
static struct class * ebbcharClass
The device-driver class struct pointer.
Definition: ebbcharmutex.c:32
static int __init ebbchar_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.
- Returns
- returns 0 if successful
63 printk(KERN_INFO
"EBBChar: Initializing the EBBChar LKM\n");
68 printk(KERN_ALERT
"EBBChar failed to register a major number\n");
71 printk(KERN_INFO
"EBBChar: registered correctly with major number %d\n",
majorNumber);
77 printk(KERN_ALERT
"Failed to register device class\n");
80 printk(KERN_INFO
"EBBChar: device class registered correctly\n");
87 printk(KERN_ALERT
"Failed to create the device\n");
90 printk(KERN_INFO
"EBBChar: device class created correctly\n");
91 mutex_init(&ebbchar_mutex);
#define CLASS_NAME
The device class – this is a character device driver.
Definition: ebbcharmutex.c:21
static int majorNumber
Store the device number – determined automatically.
Definition: ebbcharmutex.c:28
static struct device * ebbcharDevice
The device-driver device struct pointer.
Definition: ebbcharmutex.c:33
static struct file_operations fops
Definition: ebbcharmutex.c:48
#define DEVICE_NAME
The device will appear at /dev/ebbchar using this value.
Definition: ebbcharmutex.c:20
static struct class * ebbcharClass
The device-driver class struct pointer.
Definition: ebbcharmutex.c:32
MODULE_AUTHOR |
( |
"Derek Molloy" |
| ) |
|
The author – visible when you use modinfo.
MODULE_DESCRIPTION |
( |
"A simple Linux char driver for the BBB" |
| ) |
|
The description – see modinfo.
A module must use the module_init() module_exit() macros from linux/init.h, which identify the initialization function at insertion time and the cleanup function (as listed above)
The license type – this affects available functionality.
A version number to inform users.
struct class* ebbcharClass = NULL |
|
static |
The device-driver class struct pointer.
struct device* ebbcharDevice = NULL |
|
static |
The device-driver device struct pointer.
struct file_operations fops |
|
static |
Initial value:=
{
}
static int dev_open(struct inode *, struct file *)
The prototype functions for the character driver – must come before the struct definition.
Definition: ebbcharmutex.c:113
static ssize_t dev_read(struct file *, char *, size_t, loff_t *)
This function is called whenever device is being read from user space i.e. data is being sent from th...
Definition: ebbcharmutex.c:132
static ssize_t dev_write(struct file *, const char *, size_t, loff_t *)
This function is called whenever the device is being written to from user space i.e. data is sent to the device from the user. The data is copied to the message[] array in this LKM using message[x] = buffer[x].
Definition: ebbcharmutex.c:155
static int dev_release(struct inode *, struct file *)
The device release function that is called whenever the device is closed/released by the userspace pr...
Definition: ebbcharmutex.c:168
Devices are represented as file structure in the kernel. The file_operations structure from /linux/fs.h lists the callback functions that you wish to associated with your file operations using a C99 syntax structure. char devices usually implement open, read, write and release calls
Store the device number – determined automatically.
Memory for the string that is passed from userspace.
Counts the number of times the device is opened.
Used to remember the size of the string stored.