建立裝置檔案_使用DEVICE_ATTR例項分析
在android中操作驅動時,很多時候都是使用的sysfs檔案系統來進行直接操作。即通過操作一個節點檔案,直接實現對kernel層的資料操作。這個時候,就不得不提一個巨集:DEVICE_ATTR。
DEVICE_ATTR巨集定義在include/linux/device.h中,所以一般需要新增標頭檔案:
#include <linux/device.h>
函式原型是:
#define DEVICE_ATTR(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store);
DEVICE_ATTR 巨集宣告有四個引數,分別是名稱(_name)、許可權位(_mode:一般使用S_IRUGO | S_IWUSR或者0664)、讀函式(_show)、寫函式(_store)。
其中讀函式和寫函式是讀寫功能函式的函式名。呼叫DEVICE_ATTR生成的對應的檔案在/sys/devices/目錄中對應的device下面。
程式碼主要實現過程如下:
static ssize_t test_czd_show(struct device *dev,struct device_attribute *attr, char *buf) //讀函式的封裝定義,自己根據需要新增相應的操作
{
return sprintf(buf, “%s\n”, “czd:test code”);
}
static ssize_t test_czd_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count) //寫函式的封裝定義,自己根據需要新增相應的操作
{
return count;
}
static DEVICE_ATTR(test_czd, S_IRUGO | S_IWUSR, test_czd_show, test_czd_store);//建立裝置節點檔案test_czd
當你想要實現的介面名字是test_czd的時候,需要實現結構體struct attribute *dev_attrs[],其中成員變數的名字必須是&dev_attr_test_czd.attr,即&dev_attr_xxxx.attr,xxxx表示節點名字
static struct attribute *dev_attrs[] = {
&dev_attr_test_czd.attr,
NULL,
};
然後再封裝:
static struct attribute_group dev_attr_group = {
.attrs = dev_attrs,
};
然後在probe函式中呼叫:sysfs_create_group(&client->dev.kobj, &dev_attr_group);//建立介面sysfs
在remove函式中呼叫:sysfs_remove_group(&client->dev.kobj, &dev_attr_group);//在remove中移除介面sysfs
原理:當我們將資料echo到介面中時,在上層實際上完成了一次write操作,對應到kernel呼叫了驅動中的store。同理,當我們cat一個介面時則會呼叫show。到這裡,
只是簡單的建立了android層到kernel的橋樑,真正實現對硬體操作的,還是在show和store中完成的。
如何使用:
通過adb連線,在shell下輸入以下:
1、cd到對應目錄,cd /sys/devices/platform/xxxx //xxxx表示對應的裝置,然後cat test_czd 此時可以讀出該介面的資訊,也就是執行test_czd_show這個函式
2、cd到對應目錄,cd /sys/devices/platform/xxxx //xxxx表示對應的裝置,然後echo 01 > test_czd 這樣就執行test_czd_store
當然_ATTR還有一些同類的巨集函式,我們應該根據需要來使用不同的巨集函式:
對裝置的使用:DEVICE_ATTR
對驅動使用:DRIVER_ATTR
對匯流排使用:BUS_ATTR
對類別 (class) 使用:CLASS_ATTR
---------- 愛生活,愛安卓,愛Linux ----------