Für eine Hausaufgabe habe ich einen Zeichen Gerätetreiber geschrieben. Es scheint OK zu funktionieren. Ich kann es lesen und schreiben. Das Problem ist, dass, wenn ich das Gerät lese, es Endlosschleifen ausführt und den Inhalt des Nachrichtenpuffers immer wieder ausdruckt.endlos Schleife beim Lesen von Zeichen Gerät
Dies scheint wie es sollte ziemlich geradlinig sein. Verwenden Sie einfach copy_to_user(), aber es hat sich als sehr problematisch erwiesen.
Wie auch immer, hier ist der Code. Ich denke, das Problem liegt in der Funktion gdev_read(). Die printk's dienen sowohl als Debugging- als auch als Diskussionspunkte, da ich das Projekt im Unterricht präsentieren muss.
/*
* Implement a generic character pseudo-device driver
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
#include <asm/uaccess.h>
/* you need these, or the kernel will be tainted */
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("A simple sample character device driver");
/*
* function prototypes
*/
int init_module(void);
void cleanup_module(void);
static ssize_t gdev_read(struct file *, char *, size_t, loff_t *);
static ssize_t gdev_write(struct file *, const char *, size_t, loff_t *);
static int gdev_open(struct inode *, struct file *);
static int gdev_release(struct inode *, struct file *);
/* macros */
#define TRUE 1
#define FALSE 0
#define MAX_MSG_LEN 64
/*
* global variables
*/
static dev_t dev_num; /* device number, for new device */
static char *mesg; /* buffer for message */
/* file operations structure, so my device knows how to act */
static struct file_operations fops = {
.owner = THIS_MODULE,
.read = gdev_read,
.write = gdev_write,
.open = gdev_open,
.release = gdev_release,
};
/* character device struct. Declaired here, but initialized elsewhere */
struct cdev *gdev;
int init_module(void)
{
int err;
printk(KERN_ALERT "in init_module\n");
if(alloc_chrdev_region(&dev_num, 0, 1, "/dev/gdev")){
printk(KERN_INFO "Could not allocate device numbers\n");
printk(KERN_INFO "Module gdev not loaded\n");
return -1;
}
/* now I need to make the device and register it */
gdev = cdev_alloc();
gdev->owner = THIS_MODULE;
gdev->ops = &fops;
err = cdev_add(gdev, dev_num, 1);
if(err){
printk(KERN_NOTICE "Error %d adding gdev", err);
return err;
}
mesg = (char *)vmalloc(MAX_MSG_LEN);
printk(KERN_INFO "Module gdev successfully loaded.\n");
printk(KERN_INFO "gdev Major Number: %d\n", MAJOR(dev_num));
return 0;
}
void cleanup_module(void)
{
printk(KERN_ALERT "in cleanup_module\n");
unregister_chrdev_region(dev_num, 3);
vfree(mesg);
cdev_del(gdev);
printk(KERN_INFO "Module gdev unregistered\n");
}
static ssize_t gdev_read(struct file *filp, char *page,
size_t len, loff_t *offset)
{
ssize_t bytes = len < MAX_MSG_LEN ? len : MAX_MSG_LEN;
printk(KERN_ALERT "in gdev_read\n");
if(copy_to_user(page, mesg, bytes)){
return -EFAULT;
}
return bytes;
}
static ssize_t gdev_write(struct file *filp, const char *page,
size_t len, loff_t *offset)
{
ssize_t bytes = len < MAX_MSG_LEN ? len : MAX_MSG_LEN;
printk(KERN_ALERT "in gdev_write\n");
if(copy_from_user(mesg, page, bytes)){
return -EFAULT;
}
return bytes;
}
static int gdev_open(struct inode *inode, struct file *filp)
{
printk(KERN_ALERT "in gdev_open\n");
return 0;
}
static int gdev_release(struct inode *inode, struct file *filp)
{
printk(KERN_ALERT "in gdev_release\n");
/* doesn't do anything because it doesn't need too */
return 0;
}
hm. Gut. Nachdem ich ein paar Tage mehr im Web verbracht habe, habe ich festgestellt, dass ich keine Endlosschleifen bekomme, wenn ich 0 von gdev_read zurückgebe. Es werden jedoch keine Daten gedruckt. Ich wünschte, ich könnte das herausfinden. – skothar