Skip to content
Snippets Groups Projects
Commit a1098446 authored by Peter Gerwinski's avatar Peter Gerwinski
Browse files

Beispiel-Treiber von Merlin Klaßen

parent ddb5ef4b
No related branches found
No related tags found
No related merge requests found
obj-m += mydriver2.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
From: Merlin Klaßen <merlin.klassen@hs-bochum.de>
To: Peter Gerwinski <peter.gerwinski@hs-bochum.de>
Subject: code für Treiber-Entwicklung
Hi.
Hier der Link den ich verwendet habe:
http://sysplay.in/blog/tag/character-device-files/
... und mein Quellcode (mit Makefile) im Anhang.
Gruß Merlin
/* see http://www.tldp.org/LDP/lkmpg/2.6/html/x569.html */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/module.h> /* Needed by all modules */
#include <linux/init.h> /* Needed for the macros */
#include <linux/fs.h>
#include <asm/uaccess.h> /* for put_user */
#include <linux/device.h>
#include <linux/cdev.h>
//#define _BSD_SOURCE
//#include <sys/types.h>
//#include <sys/stat.h>
//#include <fcntl.h>
//#include <unistd.h>
#define DRIVER_AUTHOR "Merlin Klaszen"
#define DRIVER_DESC "My first own driver"
#define DRIVER_LICENSE "Dual BSD/GPL"
#define SUCCESS 0
#define DEVICE_NAME "mydriver2" /* Dev name as it appears in /proc/devices */
#define DEVICE_COUNT 1
#define BUF_LEN 80
static int device_open(struct inode *, struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
static int Device_Open = 0;
static char msg [ BUF_LEN ];
static char *msg_Ptr;
static dev_t dev; /* a basic device struct, contains Major and Minor(-offset) */
static struct cdev chardev; /* will be bound to dev, to add special fields for character devices */
static struct class *cdc; /* the 'class' of the device(s) */
static struct device *myDev; /* the struct, that represents the actual thing, which we will see in the file system */
static struct file_operations fops =
{
.read = device_read,
.write = device_write,
.open = device_open,
.release = device_release
};
static int __init mydriver1_init ( void )
{
int e = alloc_chrdev_region ( &dev, 0, DEVICE_COUNT, DEVICE_NAME );
if ( e < 0 )
{
printk ( KERN_ALERT "Registering %s failed with %d\n", DEVICE_NAME, e );
return e;
}
cdev_init ( &chardev, &fops );
chardev.owner = THIS_MODULE;
chardev.ops = & fops;
e = cdev_add ( &chardev, dev, 1 );
if ( e )
{
printk ( KERN_INFO "%s: Error %d adding device", DEVICE_NAME, e );
return e;
}
cdc = class_create ( THIS_MODULE, "myCharDevClass" );
myDev = device_create ( cdc, NULL, dev, NULL, "myCharDev-%d-%d", MAJOR(dev), MINOR(dev) );
printk ( KERN_INFO "%s: Hello, world\n", DEVICE_NAME );
printk ( KERN_INFO "%s: Major: %d, Minor %d.\n", DEVICE_NAME, MAJOR(dev), MINOR(dev) );
sprintf ( msg, "Try to write into this file\n" );
return SUCCESS;
}
static void __exit mydriver1_exit ( void )
{
printk ( KERN_INFO "%s: Goodbye, world\n", DEVICE_NAME );
device_destroy ( cdc, dev );
class_destroy ( cdc );
cdev_del ( &chardev );
unregister_chrdev_region ( dev, DEVICE_COUNT );
}
static int device_open ( struct inode *inode, struct file *file )
{
if ( Device_Open )
{
return -EBUSY;
}
Device_Open++;
msg_Ptr = msg;
try_module_get ( THIS_MODULE );
printk ( KERN_INFO "%s was opened.\n", DEVICE_NAME );
return SUCCESS;
}
static int device_release ( struct inode *inode, struct file *file )
{
Device_Open--;
module_put(THIS_MODULE);
printk ( KERN_INFO "%s was closed.\n", DEVICE_NAME );
return 0;
}
static ssize_t device_read ( struct file *fp, char *buf, size_t len, loff_t * off )
{
int bytes_read = 0;
/* At the end of the message, return 0 signifying end of file */
if (*msg_Ptr == 0)
{
return 0;
}
/* Actually put the data into the buffer */
while ( len && *msg_Ptr )
{
put_user(*(msg_Ptr++), buf++);
len--;
bytes_read++;
}
printk ( KERN_INFO "%s: Someone read.\n", DEVICE_NAME );
/* return the number of bytes put into the buffer */
return bytes_read;
}
static ssize_t device_write ( struct file *fp, const char *buf, size_t len, loff_t * off )
{
int bytes_written = 0;
char c = ' ';
msg_Ptr = msg;
if ( len >= BUF_LEN )
{
len = 79;
}
while ( len && c )
{
get_user ( c, buf );
if ( (c>='a') && (c<='z') )
{
c = c & ~0x20;
}
*msg_Ptr = c;
msg_Ptr++;
len--;
bytes_written++;
buf++;
}
if ( *(msg_Ptr - 1) ) /* make sure the string is terminated */
{
*msg_Ptr = '\0';
}
msg_Ptr = msg;
printk ( KERN_INFO "%s: Someone wrote.\n", DEVICE_NAME );
return bytes_written;
}
module_init(mydriver1_init);
module_exit(mydriver1_exit);
MODULE_AUTHOR(DRIVER_AUTHOR); /* Who wrote this module? */
MODULE_DESCRIPTION(DRIVER_DESC); /* What does this module do */
MODULE_LICENSE(DRIVER_LICENSE);
/*
MODULE_SUPPORTED_DEVICE("testdevice");
* This module may use /dev/testdevice. The MODULE_SUPPORTED_DEVICE macro might
* be used in the future to help automatic configuration of modules, but is
* currently unused other than for documentation purposes.
*/
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment