基本裝置結構¶
請參閱針對 struct device 的 kerneldoc。
程式設計介面¶
發現裝置的匯流排驅動程式使用此方法向核心註冊裝置
int device_register(struct device * dev);
匯流排應初始化以下欄位
parent
name
bus_id
bus
當裝置的引用計數變為 0 時,會從核心中移除裝置。 可以使用以下方法調整引用計數
struct device * get_device(struct device * dev);
void put_device(struct device * dev);
get_device() 將返回指向傳遞給它的 struct device 的指標(如果引用尚未為 0)(如果它已經在被移除的過程中)。
驅動程式可以使用以下方法訪問裝置結構中的鎖
void lock_device(struct device * dev);
void unlock_device(struct device * dev);
屬性¶
struct device_attribute {
struct attribute attr;
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
};
裝置驅動程式可以透過 sysfs 匯出裝置的屬性。
有關 sysfs 如何工作的更多資訊,請參見 sysfs - 用於匯出核心物件的_檔案系統。
正如在 您從未想了解的關於 kobject、kset 和 ktype 的一切 中所解釋的那樣,裝置屬性必須在生成 KOBJ_ADD uevent 之前建立。 實現這一點的唯一方法是定義一個屬性組。
屬性使用名為 DEVICE_ATTR 的宏宣告
#define DEVICE_ATTR(name,mode,show,store)
示例:
static DEVICE_ATTR(type, 0444, type_show, NULL);
static DEVICE_ATTR(power, 0644, power_show, power_store);
輔助宏可用於模式的常用值,因此上述示例可以簡化為:
static DEVICE_ATTR_RO(type);
static DEVICE_ATTR_RW(power);
這聲明瞭兩個型別為 struct device_attribute 的結構,分別名為 'dev_attr_type' 和 'dev_attr_power'。 這兩個屬性可以按如下方式組織成一個組
static struct attribute *dev_attrs[] = {
&dev_attr_type.attr,
&dev_attr_power.attr,
NULL,
};
static struct attribute_group dev_group = {
.attrs = dev_attrs,
};
static const struct attribute_group *dev_groups[] = {
&dev_group,
NULL,
};
輔助宏可用於單個組的常見情況,因此可以使用以下方法宣告以上兩個結構:
ATTRIBUTE_GROUPS(dev);
然後可以透過在呼叫 struct device 中的組指標之前設定 device_register() 來將此組陣列與裝置關聯
dev->groups = dev_groups;
device_register(dev);
device_register() 函式將使用“groups”指標建立裝置屬性,並且 device_unregister() 函式將使用此指標刪除裝置屬性。
警告:儘管核心允許隨時在裝置上呼叫 device_create_file() 和 device_remove_file(),但使用者空間對何時建立屬性有嚴格的期望。 當新裝置在核心中註冊時,會生成一個 uevent 以通知使用者空間(如 udev)有新裝置可用。 如果在設備註冊後新增屬性,則使用者空間將不會收到通知,並且使用者空間將不會知道新屬性。
這對於需要在驅動程式探測時釋出裝置的其他屬性的裝置驅動程式來說非常重要。 如果裝置驅動程式只是在傳遞給它的裝置結構上呼叫 device_create_file(),那麼使用者空間將永遠不會收到新屬性的通知。