Linux DEVICE_ATTR 介紹及使用示例

1.介紹

使用DEVICE_ATTR,可以實現驅動在sys目錄自動創建文件,我們只需要實現show和store函數即可.

然後在應用層就能通過cat和echo命令來對sys創建出來的文件進行讀寫驅動設備,實現交互.

2.DEVICE_ATTR()宏定義

DEVICE_ATTR()定義位於include/linux/device.h中,定義如下所示:

#define DEVICE_ATTR(_name, _mode, _show, _store) \
    struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)

其中_mode定義如下:

  • 400    擁有者能夠讀,其他任何人不能進行任何操作;
  • 644    擁有者都能夠讀,但只有擁有者可以編輯;
  • 660    擁有者和組用戶都可讀和寫,其他人不能進行任何操作;
  • 664    所有人都可讀,但只有擁有者和組用戶可編輯;
  • 700    擁有者能夠讀、寫和執行,其他用戶不能任何操作;
  • 744    所有人都能讀,但只有擁有者才能編輯和執行;
  • 755    所有人都能讀和執行,但只有擁有者才能編輯;
  • 777    所有人都能讀、寫和執行(該設置通常不是好想法)。

當然也可以用S_IWUSR(用戶可寫),S_IRUSR(用戶可讀)等宏代替.

以下面DEVICE_ATTR()定義爲例:

複製代碼

static ssize_t show_my_device(struct device *dev,
                  struct device_attribute *attr, char *buf)   //cat命令時,將會調用該函數
{
    return buf;
}

static ssize_t set_my_device(struct device *dev,
                 struct device_attribute *attr,
                 const char *buf, size_t len)   //echo命令時,將會調用該函數.
{
    return len;
}
static DEVICE_ATTR(my_device_test, S_IWUSR|S_IRUSR, show_my_device, set_my_device);   //定義一個名字爲my_device_test的設備屬性文件

複製代碼

最終將宏展開爲:

struct device_attribute dev_attr_my_device_test ={  
    .attr = {.name = "my_device_test", .mode = S_IWUSR|S_IRUSR },     
    .show    = show_my_device,                 
    .store    = set_my_device,             
}

然後再通過device_create_file()或者sysfs_create_file()便來創建上面my_device_test設備文件.

3.使用示例

示例代碼如下:

複製代碼

#include <board.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/regulator/consumer.h>
#include <sound/soc.h>
#include <sound/jack.h>


static  char mybuf[100]="123";
static ssize_t show_my_device(struct device *dev,
                  struct device_attribute *attr, char *buf)        //cat命令時,將會調用該函數
{
    return sprintf(buf, "%s\n", mybuf);
}

static ssize_t set_my_device(struct device *dev,
                 struct device_attribute *attr,
                 const char *buf, size_t len)        //echo命令時,將會調用該函數
{
    sprintf(mybuf, "%s", buf);
    return len;
}
static DEVICE_ATTR(my_device_test, S_IWUSR|S_IRUSR, show_my_device, set_my_device);
                //定義一個名字爲my_device_test的設備屬性文件
                
struct file_operations mytest_ops={
         .owner  = THIS_MODULE,
};

static int major;
static struct class *cls;
static int mytest_init(void)
{
         struct device *mydev;   
         major=register_chrdev(0,"mytest", &mytest_ops);
         cls=class_create(THIS_MODULE, "mytest_class");
         mydev = device_create(cls, 0, MKDEV(major,0),NULL,"mytest_device");    //創建mytest_device設備    
    
    if(sysfs_create_file(&(mydev->kobj), &dev_attr_my_device_test.attr)){    //在mytest_device設備目錄下創建一個my_device_test屬性文件
            return -1;}
            
         return 0;
}

static void mytest_exit(void)
{
         device_destroy(cls, MKDEV(major,0));
         class_destroy(cls);
         unregister_chrdev(major, "mytest");
}

module_init(mytest_init);
module_exit(mytest_exit);
MODULE_LICENSE("GPL");

複製代碼

效果如下:

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