led设备节点添加

说在前面. 最近因为工作原因,天天在操作和调试led. 是时候写个总结啦.

在Android机中,一般都会把led设备的节点创建到/sys/class/leds下面. 创建节点的操作通常放在probe函数里面做.

这个时候需要做的包括:

  • 定义一个struct drvdata(在.h文件中,或者在driver的c文件中都可以),并且在这个结构里面包含struct led_classdev abc_led;
struct drvdata {
	struct led_classdev abc_led;
};

 

  • 在probe函数中,声明一个1中的struct drvdata的指针变量drvdata_t,并且把这个变量和driver中的device绑定. 下面是对于i2c设备的操作,其他类型的设备操作类似.
drvdata_t = devm_kzalloc(&client->dev, sizeof(struct drvdata), GFP_KERNEL);
  • 接着就是把这个结构下面的abc_led的成员给填好并且调用函数led_classdev_register.也就是在probe里面调用下面的函数,当然也可以直接在probe里面写函数内容,就是不太好看.
static int abc_led_register(struct device *dev, struct drvdata *data)
{
	data->led.name = "abc_led";

	data->led.brightness = LED_OFF;
	data->led.max_brightness = LED_HALF;
	data->led.default_trigger = "none";
	data->led.brightness_set = abc_led_set;
	data->led.brightness_get = abc_led_get;

	return led_classdev_register(dev, &data->abc_led);
}
  • 之后就是真的节点的注册了.en,要做好错误处理.
err = sysfs_create_group(&drvdata_t->led.dev->kobj, &abc_attr_group);
if (err)
	goto xxx;
  • 接着需要实现的是abc_attr_group结构;
static ssize_t led_on_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
    //TODO: set gpio or send cmd to the device
	return count;
}

static ssize_t led_on_show(struct device *dev, struct device_attribute *attr,char *buf)
{
    //TODO: get gpio value or read from the cmd
	return snprintf(buf, PAGE_SIZE,"%d\n", 0);
}


static DEVICE_ATTR(led_on, 0664, led_on_show, led_on_store);


static struct attribute *abc_attrs[] = {
	&dev_attr_led_on.attr,
	NULL
};

static const struct attribute_group abc_attr_group = {
	.attrs = abc_attrs,
};

上面就可以创建出/sys/class/leds/abc_led/led_on节点了. 当然led_on_show和led_on_store要根据具体情况实现.

另外,需要在remove函数中进行unregister呀.

就是一个简短的小总结. 迈小步,不停步. 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章