android中device_attr 设备属性节点 以备后用

1. 在sys下创建一个节点

static ssize_t gsensor_vendor_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{	
	char  val;	
	//val = simple_strtoul(buf, NULL, 10);	
	sscanf(buf, "%d", &val);
	if(val == 0)
	{		
		gpio_set_value(MMA8452_CON_PIN, 0);	
	}
	else
	{		
		gpio_set_value(MMA8452_CON_PIN, 1);	
	}	
	return strlen(buf);
}

static DEVICE_ATTR(vendor, 0777, gsensor_vendor_show, gsensor_vendor_store);

static struct kobject *android_gsensor_kobj;

static int gsensor_sysfs_init(void)
{
	int ret ;

	android_gsensor_kobj = kobject_create_and_add("android_gsensor", NULL);
	if (android_gsensor_kobj == NULL) {
		mmaprintk(KERN_ERR
		       "MMA8452 gsensor_sysfs_init:"\
		       "subsystem_register failed\n");
		ret = -ENOMEM;
		goto err;
	}

	ret = sysfs_create_file(android_gsensor_kobj, &dev_attr_vendor.attr);   // "vendor"
	if (ret) {
		mmaprintk(KERN_ERR
		       "MMA8452 gsensor_sysfs_init:"\
		       "sysfs_create_group failed\n");
		goto err4;
	}

	return 0 ;
err4:
	kobject_del(android_gsensor_kobj);
err:
	return ret ;
}

2.创建一个设备节点

ssize_t led_3g_green_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
	u8 val;
	val = simple_strtoul(buf, NULL, 10);
	if(val == 0){
		gpio_set_value(MX53_HMS_3G_LED_GREEN_EN, 0);
	}else{
		gpio_set_value(MX53_HMS_3G_LED_GREEN_EN, 1);
	}
	return count;
}

ssize_t led_3g_green_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	sprintf(buf, "%d\n", gpio_get_value(MX53_HMS_3G_LED_GREEN_EN));
	return strlen(buf);
}

ssize_t led_3g_amber_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
	u8 val;
	val = simple_strtoul(buf, NULL, 10);
	if(val == 0){
		gpio_set_value(MX53_HMS_3G_LED_AMBER_EN, 0);
	}else{
		gpio_set_value(MX53_HMS_3G_LED_AMBER_EN, 1);
	}
	return count;
}

ssize_t led_3g_amber_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	sprintf(buf, "%d\n", gpio_get_value(MX53_HMS_3G_LED_AMBER_EN));
	return strlen(buf);
}

static DEVICE_ATTR(led_3g_green, S_IRUGO|S_IWUSR, led_3g_green_show, led_3g_green_store);
static DEVICE_ATTR(led_3g_amber, S_IRUGO|S_IWUSR, led_3g_amber_show, led_3g_amber_store);

static struct attribute* leds_mxc_gpio_attrs[] = 
{
	&dev_attr_led_3g_green.attr,
	&dev_attr_led_3g_amber.attr,
	NULL 
};
	
static const struct attribute_group leds_mxc_gpio_group =
{
	.attrs = leds_mxc_gpio_attrs,
};


result = sysfs_create_group(&drv_data->pdev->dev.kobj, &leds_mxc_gpio_group);
	if (result) {
		dev_err(&pdev->dev, "Create device file failed! ERRNO: %d\n",result);
		goto free_drv_data;
	}

以上两种方法创建的节点,通过串口,能够进行读写的操作。

<think>我们正在处理一个来自Android内核构建环境中的System.map文件的一行内容。这一行表示在系统符号映射表中定义了一个设备属性(dev_attr)的符号。 具体行内容为:253874:ffffffc011add2a8 d dev_attr_brightness 其中: - 253874:可能是行号或索引(在System.map中通常不是这样,但可能是工具添加的行号) - ffffffc011add2a8:符号的地址(64位内核地址,ffffffc0开头表示在内核空间) - d:符号类型,这里表示该符号位于初始化数据段(data section) - dev_attr_brightness:符号名 在Linux内核中,`dev_attr_<name>`这样的符号通常是通过`DEVICE_ATTR`宏定义创建的设备属性文件。这个属性文件会出现在/sys/class/.../.../brightness中,用于控制设备的亮度。 但是,注意:这里用户并没有提出具体问题,只是给出了一个System.map中的条目。因此,我们可能需要解释这个条目的含义,或者如果用户的问题是关于如何在内核中创建这样的属性,那么我们可以给出示例代码。 假设用户想知道这个符号在内核中是如何定义的,我们可以给出一个创建亮度属性的示例。 然而,由于用户没有明确问题,我们只能根据上下文推测。可能用户是在进行内核驱动开发,想要了解如何创建sysfs属性。因此,我们给出一个创建亮度属性的简单示例。 下面是一个简单的内核模块示例,它创建了一个名为brightness的设备属性,可以通过sysfs进行读写。 注意:在内核模块中,我们通常使用DEVICE_ATTR宏来定义设备属性,然后使用device_create_filedevice_remove_file来在设备目录下创建和删除属性文件。 示例代码: </think>在Linux内核驱动开发中,`dev_attr_brightness` 是通过 `DEVICE_ATTR` 宏创建的设备属性节点,用于在 `/sys/` 文件系统中暴露硬件控制接口(如屏幕背光亮度)。以下是详细解释和实现代码: ### 实现原理 1. **宏定义** 使用 `DEVICE_ATTR` 宏声明属性: ```c static DEVICE_ATTR(brightness, 0644, show_brightness, store_brightness); ``` - `brightness`:属性名,生成节点 `dev_attr_brightness` - `0644`:文件权限 - `show_brightness`:读回调函数 - `store_brightness`:写回调函数 2. **回调函数实现** ```c static ssize_t show_brightness(struct device *dev, struct device_attribute *attr, char *buf) { int brightness = get_hw_brightness(); // 获取硬件亮度值 return sprintf(buf, "%d\n", brightness); } static ssize_t store_brightness(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int value; if (kstrtoint(buf, 10, &value)) return -EINVAL; set_hw_brightness(value); // 设置硬件亮度 return count; } ``` 3. **属性注册/注销** 在驱动探测/移除时操作: ```c static int my_probe(struct platform_device *pdev) { device_create_file(&pdev->dev, &dev_attr_brightness); return 0; } static int my_remove(struct platform_device *pdev) { device_remove_file(&pdev->dev, &dev_attr_brightness); return 0; } ``` ### `System.map` 条目含义 - `ffffffc011add2a8`: 符号在内存中的地址(内核虚拟地址) - `d`: 符号类型(`d` = 初始化数据段) - `dev_attr_brightness`: 驱动中通过 `DEVICE_ATTR` 生成的静态结构体变量 ### 使用场景 用户空间通过操作 `/sys/class/backlight/<device>/brightness` 文件控制亮度: ```bash # 读取亮度 cat /sys/class/backlight/panel0-backlight/brightness # 设置亮度为50 echo 50 > /sys/class/backlight/panel0-backlight/brightness ``` ### 关键数据结构 ```c // DEVICE_ATTR 展开后生成的静态结构体 static struct device_attribute dev_attr_brightness = { .attr = {.name = "brightness", .mode = 0644}, .show = show_brightness, .store = store_brightness, }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值