ATTR 是设备属性,比如说DEVICE_ATTR(_name, _mode, _show, _store)
类似的还有BUS_ATTR,CLASS_ATTR,在这个目录里有比较详细的说明,对应的目录就是/sys/bus; /sys/class
DEVICE_ATTR(_name, _mode, _show, _store)
_name:名称,也就是将在sys fs中生成的文件名称。
_mode:上述文件的访问权限,与普通文件相同,UGO的格式。
_show:显示函数,cat该文件时,此函数被调用。
_store:写函数,echo内容到该文件时,此函数被调用。
下面看看DEVICE_ATTR的定义:
#define DEVICE_ATTR(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
终于找到dev_attr_xxx定义的地方了!
#define __ATTR(_name,_mode,_show,_store) { \
.attr = {.name = __stringify(_name), .mode = _mode }, \
.show = _show, \
.store = _store, \
}
Kobject模型例子:
1.kobject.txt文档发现内核中有现成的kobject例子,就在samples/kobject/目录下的kobject-sample.c文件中。 这个例子的作用是在/sys/kernel目录下新建一个kobject-example的目录,并在该目录下生成baz、bar、foo这三个属性文件。详细代码可以在内核源码目录下找到。
2. 一个蓝牙的GPIO实例:
#include <linux/kobject.h>
#include <linux/string.h>
#include <linux/sysfs.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/wakelock.h>
#ifdef UNINEW_WIFI
extern void mxc_mmc_force_detect(int id);
ssize_t wifipower_store(struct kobject *kobj, struct kobj_attribute *attr,const char *buf, size_t count)
{
int var;
sscanf(buf, "%du", &var);
gpio_set_value(GAEI_AVN_WLAN_EN_PIN,var);
mxc_mmc_force_detect(1);
return count;
}
static struct kobj_attribute wifipower_attr = {
.attr = {
.name = "wifipower",
.mode = 0666,
},
.show = NULL,
.store = wifipower_store,
};
#endif
#if 0
extern int gaei_avn_bt_power_change(int status);
ssize_t btpower_store(struct kobject *kobj, struct kobj_attribute *attr,const char *buf, size_t count)
{
int var;
// sscanf(buf, "%du", &var);
gaei_avn_bt_power_change(var);
return count;
}
#endif
extern int gaei_avn_bt_reset_change(int status);
ssize_t btreset_store(struct kobject *kobj, struct kobj_attribute *attr,const char *buf, size_t count)
{
int var;
sscanf(buf, "%d", &var);
gaei_avn_bt_reset_change(var);
//printk(KERN_INFO "var = %d\n",var);
return count;
}
extern int gps_reset_change(int status);
ssize_t gpsreset_store(struct kobject *kobj, struct kobj_attribute *attr,const char *buf, size_t count)
{
int var;
sscanf(buf, "%d", &var);
gps_reset_change(var);
//printk(KERN_INFO "var = %d\n",var);
return count;
}
#if 0
static struct kobj_attribute btpower_attr = {
.attr = {
.name = "btpower",
.mode = 0666,
},
.show = NULL,
.store = btpower_store,
};
#endif
static struct kobj_attribute btreset_attr = {
.attr = {
.name = "btreset",
.mode = 0666,
},
.show = NULL,
.store = btreset_store,
};
static struct kobj_attribute gpsreset_attr = {
.attr = {
.name = "gpsreset",
.mode = 0666,
},
.show = NULL,
.store = gpsreset_store,
};
static struct attribute *attrs[]=
{
#ifdef UNINEW_WIFI
&wifipower_attr.attr,
#endif
//&btpower_attr.attr,
&btreset_attr.attr,
&gpsreset_attr.attr,
NULL,
};
static struct attribute_group attr_group = {
.attrs = attrs,
};
static struct kobject *m_kobj;
static int __init u_init(void)
{
int retval;
m_kobj = kobject_create_and_add("pio", NULL);
if (!m_kobj)
return -ENOMEM;
retval = sysfs_create_group(m_kobj, &attr_group);
if (retval)
kobject_put(m_kobj);
return retval;
}
late_initcall(u_init);
/******************/