(1)驱动的入口和出口:
module_init(chrdevbase_init);
module_exit(chrdevbase_exit);
(2)括号里面的就是驱动的入口和出口函数:
static int __init chrdevbase_init(void)
static void __exit chrdevbase_exit(void)
(3)需要在驱动入口函数注册字符设备驱动
1,在自身给出主设备号的时候,用下面的函数来注册和注销
设备号(id)= MKDEV(主设备号,次设备号0);
register_chrdev_region(设备号, 设备个数, 设备名字);
unregister_chrdev_region(主设备号, 设备名字); //下面自动分配的函数也是用这个函数注销设备
2,需要系统自动分配的时候使用下面的函数来注册
alloc_chrdev_region(设备号,次设备号0,设备号个数,设备名)
//下面的函数可写可不写,只是可以知道分配设备号的主设备号和次设备号
newchrled.major = MAJOR(newchrled.devid);
newchrled.minor = MINOR(newchrled.devid);
3,初始化cdev
struct cdev cdev; /* cdev */
cdev.owner = THIS_MODULE;
cdev_init(&cdev, &newchrled_fops); //初始化cdev
cdev_add(&cdev, 设备号, 设备个数); //添加cdev
4,自动分配设备结点,需要类和设备的创建,下面是创建类和设备
struct class *class; /* 类 */
class = class_create(THIS_MODULE, 节点名);
class_destroy(class); //摧毁类
struct device *device; /* 设备 */
device = device_create(class, NULL, devid, NULL, 节点名);
device_destroy(class,设备号); //摧毁设备
(4)上面的函数里面有字符设备操作集(chrdevbase_fops),需要初始化一下
static struct file_operations chrdevbase_fops = {
.owner = THIS_MODULE,
.open = chrdevbase_open,
.read = chrdevbase_read,
.write = chrdevbase_write,
.release = chrdevbase_release,
};
***在操作设备函数里面(read,write),将数据发送给用户空间的函数如下
//buf 缓冲区
//readbuf 内存分配(结构体)
//cnt 长度(不需要改变直接就是cnt)
ret = copy_to_user(buf, readbuf, cnt);
***“下面函数的目的是从用户空间拷贝数据到内核空间
//buf 缓冲区
//readbuf 内存分配(结构体)
//cnt 长度
ret = copy_from_user(buf, readbuf, cnt);