新手请教设备驱动的问题

内核编译和嵌入式产品的设计与开发
回复
haoyew
帖子: 1
注册时间: 2009-08-24 22:42

新手请教设备驱动的问题

#1

帖子 haoyew » 2009-08-24 22:47

在学习设备驱动,直接使用书上的范例想试试一个hello world 的字符驱动,结果搞了一天都不成功。还望帮着看看,多谢。
BTW: make all的结果报了很多错,屏幕显示不完。
Makefile:

obj-m := chardev.o
CURRENT_PATH := $(shell pwd)
KDIR := /usr/src/linux-headers-2.6.28-15-generic
all:
$(MAKE) -C $(KDIR) SUBDIRS=$(CURRENT_PATH) modules
clean:
rm -rf *.cmd *.o *.ko *.mod.c *.symvers *.order *.markers

c文件:
#include <linux/module.h>

#include <linux/init.h>

#include <linux/fs.h>

//#include <asm-x86/uaccess.h>

MODULE_LICENSE("GPL");



#define MAJOR_NUM 200 /*主设备号*/



static ssize_t chardev_read(struct file *, char *, size_t, loff_t*);

static ssize_t chardev_write(struct file *, const char *, size_t, loff_t*);



struct file_operations chardev_fops =

{

 read: chardev_read, write: chardev_write,

};

static int chardev_var = 0; /*"chardev"设备的全局变量*/



static int __init chardev_init(void)

{

 int ret;



 ret = register_chrdev(MAJOR_NUM, "chardev", &chardev_fops);

 if (ret)

 {

  printk("chardev register failure");

 }

 else

 {

  printk("chardev register success");

 }

 return ret;

}



static void __exit chardev_exit(void)

{

 int ret;



 ret = unregister_chrdev(MAJOR_NUM, "chardev");

 if (ret)

 {

  printk("chardev unregister failure");

 }

 else

 {

  printk("chardev unregister success");

 }

}



static ssize_t chardev_read(struct file *filp, char *buf, size_t len, loff_t *off)

{

 if (copy_to_user(buf, &chardev_var, sizeof(int)))

 {

  return - EFAULT;

 }

 return sizeof(int);

}



static ssize_t chardev_write(struct file *filp, const char *buf, size_t len, loff_t *off)

{

 if (copy_from_user(&chardev_var, buf, sizeof(int)))

 {

  return - EFAULT;

 }

 return sizeof(int);

}



module_init(chardev_init);

module_exit(chardev_exit);
SanLine
帖子: 4
注册时间: 2009-08-30 22:57

Re: 新手请教设备驱动的问题

#2

帖子 SanLine » 2009-08-30 23:01

ubuntu的源代码下了没啊?
头像
xhylyx
帖子: 353
注册时间: 2007-04-09 15:19

Re: 新手请教设备驱动的问题

#3

帖子 xhylyx » 2009-08-31 9:15

帮你调好了,你注意区分2.4内核和2.6内核驱动的接口是不一样的
看你的Makefile你用的 是2.6的内核

Makefile:

代码: 全选

obj-m := mydev.o
KERNELDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

modules:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

modules_install:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
	rm -rf *.ko
	rm -rf *.mod.*
	rm -rf .*.cmd
	rm -rf *.o
	rm *~

驱动代码:

代码: 全选

#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>

MODULE_LICENSE("GPL");

#define MAJOR_NUM 200

static ssize_t chardev_read(struct file *filp, char *buf, size_t len, loff_t *off);
static ssize_t chardev_write(struct file *filp, const char *buf, size_t len, loff_t *off);

struct file_operations chardev_fops=
{
	.owner  = THIS_MODULE,
	.read   = chardev_read,
	.write  = chardev_write,
};

static int chardev_var = 0;

static int __init chardev_init(void)
{
	int ret;

	ret = register_chrdev(MAJOR_NUM, "chardev", &chardev_fops);

	if(ret)
	{
		printk("chardev register failure");
	}
	else
	{
		printk("charedv register success");
	}

	return ret;
}

static void __exit chardev_exit(void)
{
	unregister_chrdev(MAJOR_NUM, "chardev");
}

static ssize_t chardev_read(struct file *filp, char *buf, size_t len, loff_t *off)
{
	if(copy_to_user(buf, &chardev_var, sizeof(int)))
	{
		return -EFAULT;
	}
	
	return sizeof(int);
}

static ssize_t chardev_write(struct file *filp, const char *buf, size_t len, loff_t *off)
{
	if(copy_from_user(&chardev_var, buf, sizeof(int)))
	{
		return -EFAULT;
	}
	
	return sizeof(int);
}

module_init(chardev_init);
module_exit(chardev_exit);
回复