——————————————————————
在新字符设备驱动中为了规范处理 (描述一个设备所需要的设为一个结构体)
/*对于一个设备 有设备号 主设备号 次设备号 操作函数*/
/*LED设备结构体 描述一个设备 用一个结构体表示*/
struct newchrled_dev
{
/*cdev表示字符设备 结构体初始化就是初始化结构体变量*/
struct cdev cdev ;//包含了操作函数集 和 设备号 包含头文件 #include <linux/cdev.h>
struct class *class; /*类*/
struct device *device; /*设备*/
dev_t devid; /*设备号 32位*/
int major ;/*主设备号 高12位*/
int minor ;/*次设备号 低20位*/
};
————————————————————————
/*定义结构体变量*/
struct newchrled_dev newchrled ; /*led设备*/
除下方其余都一样(与前一章的led驱动)
————————————————————————————————
/* 新字符设备实验*/
/* 申请字符设备号*/
/*如果给定主设备号了 如果没有给定怎么办 提高代码可用性*/
newchrled.major = 0 ; /*对major进行手动清零 表示由系统申请设备号*/
if(newchrled.major)
{
/*2_____代表了给定主设备号*/
/*使用MKDEV来构建设备号 主设备号+次设备号=构成设备号 次设备为0*/
newchrled.devid = MKDEV(newchrled.major,0);
/*注册字符设备函数:初始的设备号 申请的数量 设备名字 有返回值*/
ret = register_chrdev_region(newchrled.devid,NEWCHRLED_COUNT,NEWCHRLED_NAME);
}
else
{
/* 2————没有给定主设备号 */
/*向系统申请设备号函数:申请设备号 次设备号的基地址 个数 设备名字*/
ret = alloc_chrdev_region(&newchrled.devid , 0,NEWCHRLED_COUNT ,NEWCHRLED_NAME );
/*提取出主设备号和次设备号 查看*/
//MAJOR 和MINOR 提起】取主次设备号函数
newchrled.major = MAJOR(newchrled.devid);
newchrled.minor = MINOR(newchrled.devid);
}
if(ret < 0) //
{
printk("newchrled chrdev_region error \r\n");
//return -1;
//使用goto进行返回值
goto failed_devid;
}
printk("newchrled major = %d ;newchrled minor = %d \r\n", newchrled.major,newchrled.minor);
---------------------------------------------------------------------------------------------------------------
在新子符设备中有一重要结构体 struct cdev cdev ;//包含了操作函数集 和 设备号 包含头文件
//需要对其进行初始化
/*3 注册字符设备*/
newchrled.cdev.owner = THIS_MODULE;
cdev_init( &newchrled.cdev,&newchrled_fops );//初始化结构体
//初始化之后用cdev_add向系统添加字符设备
//cdev 结构体 设备号 添加的设备数量
/*申请字符设备个数*/
#define NEWCHRLED_COUNT 1
ret = cdev_add( &newchrled.cdev ,newchrled.devid,NEWCHRLED_COUNT );
if(ret < 0)
{
goto failed_cdevadd;
}
-----------------------------------------------
/*4 自动创建设备节点*/
/*创建类--返回值是类*/
#define NEWCHRLED_NAME "newchrled"
newchrled.class =class_create(THIS_MODULE,NEWCHRLED_NAME);
if(IS_ERR(newchrled.class))//判断类是否正确 用于判断结构体
{
ret = PTR_ERR(newchrled.class);
//return PTR_ERR(newchrled.class);
goto failed_class;
}
/*创建设备--返回值是设备*/
//哪个类下面 父设备 设备号 可能会使用的一些数据 设备名字
/*最终会在/dev/newchrled 中找设备*/
newchrled.device = device_create( newchrled.class ,NULL, newchrled.devid ,NULL ,NEWCHRLED_NAME);
if(IS_ERR(newchrled.device))//判断设备是否正确
{
//return PTR_ERR(newchrled.device);
ret = PTR_ERR(newchrled.device);
goto failed_device;
}
/*goto之后都会执行 */
failed_device:
/*摧毁类*/
class_destroy(newchrled.class);
failed_class:
/*1 删除字符设备*/
cdev_del(&newchrled.cdev);
failed_cdevadd:
/*注销字符设备*/
unregister_chrdev_region(newchrled.devid, NEWCHRLED_COUNT);
failed_devid:
return -12;//直接返回错误码