#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/device.h>
MODULE_LICENSE("GPL");
#define DEVICE_NAME ("my_dev")
int MAJOR_NUM = 666;
int g_val;
struct device *dev;
struct class *myclass;
static ssize_t global_read(struct file *filp, char __user *buf, size_t len, loff_t *off)
{
int ret;
char val[20];
printk(KERN_ERR "###### global_read \n");
sprintf(val, "%d\n", g_val);
//ssize_t simple_read_from_buffer(void __user *to, size_t count,loff_t *ppos, const void *from, size_t available);
ret = simple_read_from_buffer(buf, len, off, val, strlen(val));
return ret;
}
static ssize_t global_write(struct file *filp, const char __user *buf, size_t len, loff_t *off)
{
int ret, temp;
char val[20];
//simple_write_to_buffer(void *to, size_t available, loff_t *ppos,const void __user *from, size_t count);
ret = simple_write_to_buffer(val, strlen(val), off, buf, len);
sscanf(val, "%d", &temp);
g_val = temp;
return ret;
}
struct file_operations fileops = {
.read = global_read,
.write = global_write,
};
static int __init globalvar_init(void)
{
int ret;
g_val = 0;
printk(KERN_ERR "golabvar_init \n");
ret = register_chrdev(MAJOR_NUM, "my_driver", &fileops);
if(ret)
{
printk(KERN_ERR "register_chrdev fail \n");
}
else
{
printk(KERN_ERR "register_chrdev sucess \n");
//注册一个类,使mdev可以在"/dev/"目录下 面建立设备节点
myclass = class_create(THIS_MODULE, DEVICE_NAME);
//创建一个设备节点,节点名为DEVICE_NAME
dev = device_create(myclass, NULL, MKDEV(MAJOR_NUM, 0), NULL, DEVICE_NAME);
if(!dev)
{
printk(KERN_ERR "device_create faile \n");
}
}
return 0;
}
static void __exit globalvar_exit(void)
{
printk("golabvar_exit \n");
device_destroy(myclass, MKDEV(MAJOR_NUM, 0));
class_destroy(myclass);
unregister_chrdev(MAJOR_NUM, "globalvar");
}
module_init(globalvar_init);
module_exit(globalvar_exit);
makefile
obj-m := mknode.o
mknode-objs := auto_mknode.o
KID :=/lib/modules/`uname -r`/build
PWD := $(shell pwd)
all:
make -C $(KID) M=${PWD} modules
clean:
rm -rf *.o .cmd *.ko *.mod.c .tmp_versions
参考:
在2.6里已经用udev取代devfs,为解决上面那样手动创建节点的麻烦,我们可以在程序里加上创建节点这项,如下:
以字符设备char_dev为例,在驱动初始化的代码里调用class_create为该设备创建一个class,再为每个设备调用 class_device_create创建对应的设备,这样的module被加载时,undev daemon就会自动在/dev下创建char_dev设备文件。大概方法如下:
struct class *myclass = class_create(THIS_MODULE, “char_dev”);
class_device_create(myclass, NULL, MKDEV(major_num, 0), NULL, “char_dev”);
class_device_create(myclass, NULL, MKDEV(major_num, 0), NULL, “char_dev”);
当然,在exit函数中要把创建的class移除:
class_destory(&xxx_dev->cdev);
class_device_desotry(my_class,MKDEV(major_num,0));
下面介绍下函数class_creat和class_device_creat的原型:
class_create()
-------------------------------------------------
linux-2.6.22/include/linux/device.h
struct class *class_create(struct module *owner, const char *name)
class_create - create a struct class structure
@owner: pointer to the module that is to "own" this struct class
@name: pointer to a string for the name of this class.
在/sys/class/下创建类目录
class_device_create()
-------------------------------------------------
linux-2.6.22/include/linux/device.h
struct class_device *class_device_creat (struct class *cls,
struct class_device *parent,
dev_t devt,
struct device *device,
const char *fmt, ...)
class_device_create - creates a class device and registers it with sysfs
@cls: pointer to the struct class that this device should be registered to.
@parent: pointer to the parent struct class_device of this new device, if any.
@devt: the dev_t for the char device to be added.
@device: a pointer to a struct device that is assiociated with this class device.
@fmt: string for the class device's name
-------------------------------------------------
linux-2.6.22/include/linux/device.h
struct class *class_create(struct module *owner, const char *name)
class_create - create a struct class structure
@owner: pointer to the module that is to "own" this struct class
@name: pointer to a string for the name of this class.
在/sys/class/下创建类目录
class_device_create()
-------------------------------------------------
linux-2.6.22/include/linux/device.h
struct class_device *class_device_creat (struct class *cls,
struct class_device *parent,
dev_t devt,
struct device *device,
const char *fmt, ...)
class_device_create - creates a class device and registers it with sysfs
@cls: pointer to the struct class that this device should be registered to.
@parent: pointer to the parent struct class_device of this new device, if any.
@devt: the dev_t for the char device to be added.
@device: a pointer to a struct device that is assiociated with this class device.
@fmt: string for the class device's name
void class_destroy(struct class *cls);/*销毁/sys/class下的类 */
void class_device_destroy(struct class *cls, dev_t devt); /*销毁
一个类设备*/
参数含义同上
补充:
在Linux2.6中,针对上面的这个问题不同的版本有些修改,使用前要先查看下/.../include/linux/device.h里的函数声明,如我用的是Linux2.6.29,里面就没有
class_device_create函数,而直接使用device_create就可以了,而在之前的版本如Linux2.6.15,里面就要用class_device_create函数