1、hwmon驱动框架介绍
hwmon即hardware monitoring framework,硬件监视框架。比如可以把温度传感器、风扇、电源管理等设备的驱动都利用hwmon框架去实现,在设备的归类上比较容易理解。
2、hwmon驱动框架分析
2.1、hwmon驱动框架加载、卸载机制
//hwmon驱动框架的加载函数
static int __init hwmon_init(void)
{
······
}
//hwmon驱动框架的卸载函数
static void __exit hwmon_exit(void)
{
······
}
subsys_initcall(hwmon_init);
module_exit(hwmon_exit);
(1)hwmon框架是可以选择编译进内核,或者单独编译成ko文件手动进行加载、卸载;
(2)subsys_initcall(hwmon_init):如果是编译进内核,则hwmon_init函数会被放到".initcall4.init"段,内核启动时会自动调用;如果编译成ko文件,就是调用insmod命令进行加载;
(3)module_exit(hwmon_exit):如果是编译进内核,则hwmon_exit函数被放到".exitcall.exit"段,内核关闭的时候会调用;如果编译成ko文件,就是调用rmmod命令进行加载;
(4)对静态加载驱动和动态加载驱动不熟悉可参考博客:https://blog.csdn.net/weixin_42031299/article/details/124394613;
2.2、hwmon驱动框架的加载函数
static int __init hwmon_init(void)
{
hwmon_pci_quirks();
//创建hwmon类
hwmon_class = class_create(THIS_MODULE, "hwmon");
if (IS_ERR(hwmon_class)) {
printk(KERN_ERR "hwmon.c: couldn't create sysfs class\n");
return PTR_ERR(hwmon_class);
}
return 0;
}
(1)加载函数很简单,主要工作就是创建hwmon类;
(2)效果:在/sys/class目录下可以看到hwmon文件夹,里面暂时是空的,因为只创建了hwmon类还没有创建属于这个类的设备;
2.3、hwmon驱动框架的卸载函数
static void __exit hwmon_exit(void)
{
class_destroy(hwmon_class);
}
操作就是销毁hwmon类;
2.4、向hwmon框架注册驱动的函数
#define HWMON_ID_PREFIX "hwmon"
#define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d"
/*
*函数返回值:hwmon函数返回一个struct device指针,指向一个刚创建的hwmon类设备;
*传参:一般传NULL,如果不是NULL,则传入的struct device指针指向的设备是新创建的hwmon类设备的父节点;
*/
struct device *hwmon_device_register(struct device *dev)
{
struct device *hwdev;
int id, err;
·····
//计算hwmon类设备名字的后缀
id = id & MAX_ID_MASK;
//创建hwmon类的设备
hwdev = device_create(hwmon_class, dev, MKDEV(0, 0), NULL,
HWMON_ID_FORMAT, id);
······
}
return hwdev;
}
(1)注册函数主要功能:创建一个属于hwmon类的设备,返回设备的struct device指针;
(2)hwmon类设备的命名:在注册hwmon类设备时,注册函数会自动设置名字,名字格式是"hwmon+后缀名",其中后缀名就是标号,从0开始增加;比如:hwmon0、hwmon1、······
(3)注册完一个hwmon类设备后,会在"/sys/class/hwmon"目录下看到新增一个文件夹"hwmon+后缀名";
2.5、向hwmon框架卸载驱动的函数
void hwmon_device_unregister(struct device *dev)
{
int id;
if (likely(sscanf(dev_name(dev), HWMON_ID_FORMAT, &id) == 1)) {
//销毁设备
device_unregister(dev);
spin_lock(&idr_lock);
idr_remove(&hwmon_idr, id);
spin_unlock(&idr_lock);
} else
dev_dbg(dev->parent,
"hwmon_device_unregister() failed: bad class ID!\n");
}
(1)销毁调用hwmon_device_register()创建的hwmon设备,直接将设备指针传入即可;
(2)还涉及到设备占用的标号要标记为空闲;
3、注册hwmon类设备的流程总结
(1)内核要加载hwmon驱动框架,一般都是把hwmon驱动编译进内核;
(2)hwmon驱动框架做的工作很少,就是创建了hwmon类,这个类就是个空壳,即没有填充类属性,也没有填充类下面的设备属性,效果上看就是创建了/sys/class/hwmon目录,
将来我们把hwmon设备都放到这个目录下;
(3)调用hwmon_device_register()注册hwmon设备,就是在/sys/class/hwmon目录给我们的设备创建一个文件夹,名字是hwmon框架设置的;
(4)我们hwmon驱动拿到hwmon驱动框架创建的设备struct device结构体,去设置设备的属性,也就是在sysfs中创建设备文件夹下面的文件,并指定文件的show方法和store方法;