hwmon子系统——属性文件及其读写函数自定义逻辑

本文详细介绍了Linux内核中的hwmon子系统,包括属性文件的创建、读写函数的自定义逻辑,以及设备注册函数`hwmon_device_register_with_groups`和`hwmon_device_register_with_info`的使用。通过对传感器驱动的分析,展示了如何通过hwmon子系统监控硬件传感器状态,并自定义属性文件的读写操作。文中还特别讨论了两种设备注册方式的不同,以及动态资源管理在驱动注册过程中的作用。
摘要由CSDN通过智能技术生成

hwmon子系统——属性文件

hwmon子系统作为Linux内核中的一个子系统,用于监控硬件传感器的状态和提供对硬件传感器的访问接口。

在应用层,对传感器信息的读取,本质上是对驱动中hwmon子系统在注册传感器设备时所创建的各个属性文件进行读取操作

在Linux系统下,这些属性文件是直观存在的,如下图中的路径(my_hwmon为驱动中手动修改的结果,默认是hwmon);
需要注意,下面这一长串目录才是hwmon子系统根据驱动流程所创建的最原始且完整的目录,其他父级目录能够进入这个目录基本都是存在链接进行指向,并非完整的目录;
在这里插入图片描述
目录下的name文件存储了当前集成传感器的芯片设备的设备名,EMC1413为一种温度传感器;
在这里插入图片描述
目录下存在各种temp为前缀的文件(温度传感器的属性文件),这些就是驱动在注册设备时所创建的各种属性文件;
在这里插入图片描述
这些传感器所对应的芯片设备,实际是挂在从I2C-1总线上所扩展的一个I2C-Mux设备上,hwmon子系统和i2c子系统很大程度上不能算作一种从属关系,更多类似于一种协作关系,不过目录结构上还是将hwmon子系统对应的目录创建在了i2c子系统的目录之下;

hwmon子系统——设备注册函数

目前驱动中将一个hwmon子系统下的设备注册到驱动中时,主要有三个注册用的函数:hwmon_device_register

/* hwmon_device_register() is deprecated */
struct device *hwmon_device_register(struct device *dev);

hwmon_device_register_with_groups

struct device *hwmon_device_register_with_groups(
				  struct device *dev, 
				  const char *name,
				  void *drvdata,
				  const struct attribute_group **groups);

hwmon_device_register_with_info

struct device *hwmon_device_register_with_info(
				struct device *dev,
				const char *name, 
				void *drvdata,
				const struct hwmon_chip_info *info,
				const struct attribute_group **extra_groups);

其中hwmon_device_register作为早期版本的注册函数已经弃用,不做分析;

hwmon_device_register_with_groups以及hwmon_device_register_with_info进行设备注册时,都需要将设备的属性信息进行传递,区别在于,hwmon_device_register_with_groups只能以groups方式传递,hwmon_device_register_with_info则能既能够使用info传递,也能够使用extra_groups进行传递(但是info不能为空,否则会异常return,extra_groups代码流程看只是在attribute_group不止1个时使用);

hwmon子系统——hwmon_device_register_with_groups注册时属性文件的指定及读写函数

hwmon_device_register_with_groups方式注册时,在驱动程序侧将会有较为繁琐的属性信息创建流程,下方的emc1402_group是一个attribute_group类型的全局静态变量,存有emc1402对应的各种属性信息;

static int emc1403_probe(struct i2c_client *client)
{
   
	struct thermal_data *data;
	struct device *hwmon_dev;
	const struct i2c_device_id *id = i2c_match_id(emc1403_idtable, client);

	data = devm_kzalloc(&client->dev, sizeof(struct thermal_data),
			    GFP_KERNEL);
	if (data == NULL)
		return -ENOMEM;

	data->regmap = devm_regmap_init_i2c(client, &emc1403_regmap_config);
	if (IS_ERR(data->regmap))
		return PTR_ERR(data->regmap);

	mutex_init(&data->mutex);

	switch (id->driver_data) {
   
	case emc1404:
		data->groups[2] = &emc1404_group;
		fallthrough;
	case emc1403:
		data->groups[1] = &emc1403_group;
		fallthrough;
	case emc1402:
		data->groups[0] = &emc1402_group;
	}

	if (id->driver_data == emc1402)
		data->groups[1] = &emc1402_alarm_group;

	hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev,
							   client->name, data,
							   data->groups);
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值