ورود

View Full Version : مبتدی: درایور موس



zahra faraji
دوشنبه 17 آذر 1393, 09:26 صبح
با سلام خدمت دوستان محترم
من یه ماژول کرنل نوشتم که مختصات موس را می خواند و درون فایل ourmouse واقع در پوشه dev می‌نویسد. اما بعد از نصب ماژول و mknod کردن فایل ourmouse با ماینر 0 و ماژر 60، زمانی که آن را cat می‌کنم خطای invalid argument می دهد. کدم هم به شکل زیر است:

static int mouse_users = 0; /* User count */
static int mouse_dx = 0; /* Position changes */
static int mouse_dy = 0;
static int mouse_event = 0; /* Mouse has moved */
static unsigned char mouse_buttons = 0;
#define MOD_INC_USE_COUNT;
#define MOD_DEC_USE_COUNT;

#define OURMOUSE_BASE 0x300

static int mouse_intr = 5;
static struct wait_queue *mouse_wait;
static DEFINE_SPINLOCK(mouse_lock);
static void ourmouse_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
printk(KERN_INFO "interrupt");
char delta_x;
char delta_y;
unsigned char new_buttons;

delta_x = inb(OURMOUSE_BASE);
delta_y = inb(OURMOUSE_BASE+1);
new_buttons = inb(OURMOUSE_BASE+2);

if(delta_x || delta_y || new_buttons != mouse_buttons)
{
/* Something happened */

spin_lock(&mouse_lock);
mouse_event = 1;
mouse_dx += delta_x;
mouse_dy += delta_y;
mouse_buttons = new_buttons;
spin_unlock(&mouse_lock);

wake_up_interruptible(&mouse_wait);
}
}


static int open_mouse(struct inode *inode, struct file *file)
{
printk(KERN_INFO "open");
if(mouse_users++)
return 0;

MOD_INC_USE_COUNT;

if(request_irq(mouse_intr, ourmouse_interrupt, 0, "ourmouse", NULL))
{
mouse_users--;
MOD_DEC_USE_COUNT;
return -EBUSY;
}
mouse_dx = 0;
mouse_dy = 0;
mouse_event = 0;
mouse_buttons = 0;
return 0;
}

static int close_mouse(struct inode *inode, struct file *file)
{
printk(KERN_INFO "close");
if(--mouse_users)
return 0;
free_irq(ourmouse_interrupt, NULL);
MOD_DEC_USE_COUNT;
return 0;
}
static ssize_t write_mouse(struct file *file, const char *buffer, size_t
count, loff_t *ppos)
{
printk(KERN_INFO "write");
return -EINVAL;
}

static unsigned int mouse_poll(struct file *file, poll_table *wait)
{
printk(KERN_INFO "poll");
poll_wait(file, &mouse_wait, wait);
if(mouse_event)
return POLLIN | POLLRDNORM;
return 0;
}
static ssize_t mouse_read(struct file *file, char *buffer,
size_t count, loff_t *pos)
{
printk(KERN_INFO "read");
int dx, dy;
unsigned char button;
unsigned long flags;
int n;

if(count<3)
return -EINVAL;

/*
* Wait for an event
*/

while(!mouse_event)
{
if(file->f_flags&O_NDELAY)
return -EAGAIN;
interruptible_sleep_on(&mouse_wait);
if(signal_pending(current))
return -ERESTARTSYS;
}
/* Grab the event */

spin_lock_irqsave(&mouse_lock, flags);

dx = mouse_dx;
dy = mouse_dy;
button = mouse_buttons;

if(dx<=-127)
dx=-127;
if(dx>=127)
dx=127;
if(dy<=-127)
dy=-127;
if(dy>=127)
dy=127;

mouse_dx -= dx;
mouse_dy -= dy;

if(mouse_dx == 0 && mouse_dy == 0)
mouse_event = 0;

spin_unlock_irqrestore(&mouse_lock, flags);
if(put_user(button|0x80, buffer))
return -EFAULT;
if(put_user((char)dx, buffer+1))
return -EFAULT;
if(put_user((char)dy, buffer+2))
return -EFAULT;

for(n=3; n < count; n++)
if(put_user(0x00, buffer+n))
return -EFAULT;

return count;
}

struct file_operations our_mouse_fops = {
NULL, /* Mice don't seek */
mouse_read, /* You can read a mouse */
write_mouse, /* This won't do a lot */
NULL, /* No readdir - not a directory */
mouse_poll, /* Poll */
NULL, /* No ioctl calls */
NULL, /* No mmap */
open_mouse, /* Called on open */
NULL, /* Flush - 2.2+ only */
close_mouse, /* Called on close */
};


static struct miscdevice our_mouse = {
1, "ourmouse", &our_mouse_fops
};

__init ourmouse_init(void)
{

if(check_region(OURMOUSE_BASE, 3)){
printk(KERN_INFO "no check_region");
return -ENODEV;
}
request_region(OURMOUSE_BASE, 3, "ourmouse");
misc_register(&our_mouse);

return 0;
}

#ifdef MODULE

int init_module(void)
{
if(ourmouse_init()<0){
return -ENODEV;
}
return 0;
}

void cleanup_module(void)
{
misc_deregister(&our_mouse);
release_region(OURMOUSE_BASE, 3);
}


#endif

zahra faraji
دوشنبه 17 آذر 1393, 14:26 عصر
لطفا یکی کمک کنه دیگه...
مشکل کجاست؟:افسرده::افسرده:

zahra faraji
سه شنبه 18 آذر 1393, 16:09 عصر
سلام به همه دوستان محترم
من کد تابع mouse_read رو تغییر دادم. به شکل زیر
int dx, dy;
unsigned char button;
unsigned long flags;
int n;
pr_info("I have been read\n");
if(count<3)
{
pr_info("error count\n");
return -EINVAL;
}


DECLARE_WAITQUEUE(wait, current);
int res = 0;
if(!mouse_event && (file->f_flags&O_NDELAY))
{
pr_info("error mouse_event\n");
return -EWOULDBLOCK;
}
res = wait_event_interruptible(mouse_wait, mouse_event);

if((res == -ERESTARTSYS))
pr_info("res: %d ", res);
if(signal_pending(current) )
pr_info("signal_pendingggggggg");

if(signal_pending(current) || (res == -ERESTARTSYS))
{
return -ERESTARTSYS;
}


spin_lock_irqsave(&mouse_lock, flags);

dx = mouse_dx;
dy = mouse_dy;
button = mouse_buttons;

if(dx<=-127)
dx=-127;
if(dx>=127)
dx=127;
if(dy<=-127)
dy=-127;
if(dy>=127)
dy=127;

mouse_dx -= dx;
mouse_dy -= dy;

if(mouse_dx == 0 && mouse_dy == 0)
mouse_event = 0;

spin_unlock_irqrestore(&mouse_lock, flags);
if(put_user(button|0x80, buffer))
return -EFAULT;
if(put_user((char)dx, buffer+1))
return -EFAULT;
if(put_user((char)dy, buffer+2))
return -EFAULT;

for(n=3; n < count; n++)
if(put_user(0x00, buffer+n))
return -EFAULT;

pr_info("buffer: %02x ", buffer);

return count;


متوجه شدم که تابع wait_event_interruptible مقدار -512 رو برمیگردونه. همین طور signal_pending(current)
هم دچار مشکل هستش. کسی میتونه علت رو بهم بگه؟
میتونه به خاطر minor یا major درایور باشه؟