在驱动中添加syfs系统接口

近日研究红外传感器驱动,发现adb shell进入sys/kernel目录下存在pac7673文件夹,其中实现两个接口,分别是enable_proximity和poll_period_ms_proximity,同过echo和cat分别可以对这两个接口进行读和写,我们来看下在驱动中他是如何实现的。
首先在红外传感器pac7673驱动包含了pac7673.h这个头文件,里面先定义了一个结构体

struct sensor_device_attribute{
    struct device_attribute dev_attr;
    int index;
};

其中结构体device_attribute在device.h中定义,路径为kernel/include/linux/device.h。
还有这样的宏定义:

#define SENSOR_ATTR(_name, _mode, _show, _store, _index)    \
    { .dev_attr = __ATTR(_name, _mode, _show, _store),  \
      .index = _index }

#define SENSOR_DEVICE_ATTR(_name, _mode, _show, _store, _index) \
struct sensor_device_attribute sensor_dev_attr_##_name      \
    = SENSOR_ATTR(_name, _mode, _show, _store, _index)

函数宏DEVICE_ATTR内封装的是__ATTR(_name,_mode,_show,_stroe)方法,_show表示的是读方法,_stroe表示的是写方法。

当然_ATTR不是独生子女,他还有一系列的姊妹__ATTR_RO宏只有读方法,__ATTR_NULL等等

如对设备的使用 DEVICE_ATTR,对总线使用 BUS_ATTR,对驱动使用 DRIVER_ATTR ,对类 别 (class) 使用 CLASS_ATTR, 这四个高级的宏来自于

typedef struct {
    struct i2c_client *client;
    struct pac7673_platform_data *pdata;
    struct class *pac7673_class;
    struct device *pac7673_device;
    struct input_dev *input_dev;
    *struct kobject *kobj;*
    struct delayed_work pac7673_work;
    unsigned int major_id;
    int irq;
    atomic_t enabled;
    atomic_t period_ms;
    struct wake_lock irq_lock;
} pac7673_data_t;

接下来在probe函数中做了如下处理

pac7673data.kobj = kobject_create_and_add("pac7673", kernel_kobj);
    if (!pac7673data.kobj) {
        goto failed_kobj_create;
    }

    err = sysfs_create_group(pac7673data.kobj, &pac7673_attribute_group);
    if (err) {
        goto failed_sysfs_create_group;
    }

先通过kobject_create_and_add(“pac7673”, kernel_kobj)创建了一个名为pac7673的文件夹,再通过sysfs_create_group(pac7673data.kobj, &pac7673_attribute_group)创建目录下的属性文件组
,其中pac7673_attribute_group使我们自定义的相关属性文件,这样我们就在文件系统注册了这样的一个接口。
接下来就是对接口的一些配置

static SENSOR_DEVICE_ATTR(enable_proximity, S_IRUGO | S_IWUGO,
        pac7673_show_enable, pac7673_store_enable, 0);

static SENSOR_DEVICE_ATTR(poll_period_ms_proximity, S_IRUGO | S_IWUGO,
        pac7673_show_polling_rate, pac7673_store_polling_rate, 0);

这样就在pac7673目录下生成两个文件接口enable_proximity和poll_period_ms_proximity。
再把这两个接口添加到属性组中去

static struct attribute *pac7673_attributes[] = {
        &sensor_dev_attr_enable_proximity.dev_attr.attr,
    &sensor_dev_attr_poll_period_ms_proximity.dev_attr.attr,
        NULL
};

static const struct attribute_group pac7673_attribute_group = {
        .attrs = pac7673_attributes,
};

结构体数组pac7673_attributes[]中成员变量的名字必须是&sensor_dev_attr_enable_proximity.dev_attr.attr和&sensor_dev_attr_poll_period_ms_proximity.dev_attr.attr。

最后再来看具体的功能函数的实现

static ssize_t pac7673_show_enable(struct device *dev,
        struct device_attribute *attr,
        char *buf)
{
    int ret;

    ret = sprintf(buf, "%d\n", atomic_read(&pac7673data.enabled));

    return ret;
}

static ssize_t pac7673_store_enable(struct device *dev,
        struct device_attribute *attr,
        const char *buf, size_t size)
{
    unsigned long enable;

    if (strict_strtoul(buf, 10, &enable))
        return -EINVAL;

    if (atomic_read(&pac7673data.enabled) == !!enable) {
        return size;
    }

    atomic_set(&pac7673data.enabled, !!enable);

    if (!!enable) {
        enable_irq(pac7673data.irq);
        pac7673_write_reg(0x11, 0x8c);
    } else {
        pac7673_write_reg(0x11, 0x0c);
        disable_irq(pac7673data.irq);
    }

    return size;
}

这两个函数分别是实现enable_proximity接口的读写功能。

static ssize_t pac7673_show_polling_rate(struct device *dev,
        struct device_attribute *attr,
        char *buf)
{
    int ret;

    ret = sprintf(buf, "%d\n", atomic_read(&pac7673data.period_ms));

    return ret;
}

static ssize_t pac7673_store_polling_rate(struct device *dev,
        struct device_attribute *attr,
        const char *buf, size_t size)
{
    unsigned long interval_ms;

    if (strict_strtoul(buf, 10, &interval_ms))
        return -EINVAL;

    if (interval_ms < 10)
        interval_ms = 10;

    if (interval_ms > 500)
        interval_ms = 500;

    atomic_set(&pac7673data.period_ms, interval_ms);

    return size;
}

这两个函数是实现poll_period_ms_proximity接口读写功能。

上面几个函数功能是对pac7673_data_t结构体中定义的atomic_t enabled和atomic_t period_ms这两个参数进行读写。分别控制的是中断的使能和工作队列的延时时间。
到这两个syfs系统接口就实现了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值