前面的博文循規蹈矩按照無驅動框架的步驟分析了乙個簡單的字元裝置驅動,但是現如今更多是使用核心開發者提供的驅動框架來完成驅動的註冊,這樣的做法即可減少**的錯誤率,也能避免錯誤例如記憶體申請忘記釋放的問題,更能簡化驅動的開發難度,這裡就以乙個簡答的led類裝置驅動架構為例,分析字元裝置驅動框架:
驅動框架實際也是乙個驅動**,他把很多的,一類裝置都會進行的錯誤放在乙個較早的時間,在核心模組載入的初期,就將其作為乙個模組載入進去了,並未驅動開發者提供了很多便利的註冊介面函式。
1.驅動框架自身完成的部分:
subsys_initcall(leds_init);
subsys_initcall()的等級高於module_init()函式,所以在真正的驅動載入之前他已經作為乙個模組載入進了核心之中。
static int __init leds_init(void)
(1)led裝置類的建立:
leds_class = class_create(this_module, "leds");
此後在/sys/class目錄下就會有乙個leds目錄,此後使用此框架註冊的led裝置都可以在leds目錄下找到;
(2)將建立的類less進行一些固定內容的填充:
leds_class->suspend = led_suspend;
leds_class->resume = led_resume;
leds_class->dev_attrs = led_class_attrs;
2.框架提供的led類裝置註冊函式:
int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
export_symbol_gpl(led_classdev_register);
(1)進行裝置的註冊:
led_cdev->dev = device_create(leds_class, parent, 0, led_cdev,"%s", led_cdev->name);
這裡規定了註冊的裝置屬於leds類裝置,系統動態的為其分配裝置號,
(2)將註冊的裝置放進leds類裝置維護的鍊錶內:
down_write(&leds_list_lock);
list_add_tail(&led_cdev->node, &leds_list);
up_write(&leds_list_lock);
if (!led_cdev->max_brightness)
led_cdev->max_brightness = led_full;
led_update_brightness(led_cdev);
(3)最後匯出這個介面函式給驅動開發者使用:
export_symbol_gpl(led_classdev_register);
3.登出驅動函式:
void led_classdev_unregister(struct led_classdev *led_cdev)
export_symbol_gpl(led_classdev_unregister);
(1)呼叫最原始的介面進行登出:
device_unregister(led_cdev->dev);
down_write(&leds_list_lock);
list_del(&led_cdev->node);
up_write(&leds_list_lock);
可見驅動框架幫我們完成了很多的基礎工作,而將與裝置直接相關的一些特異性的東西留給開發者自己去填充,這樣驅動架構和驅動一起工作,完成完整的驅動工作。
end。。。。。。
2 6字元裝置驅動
chardev.c include include for file f op include include for copy to user include for cdev cdev init,cdev add module license gpl module author helight ...
裝置驅動例項 字元裝置驅動
在整個linux裝置驅動學習中,字元裝置驅動較為基礎。通過對它的學習,對裝置驅動進一步加深了解 cdev 結構體struct cdev 講下比較重要的成員變數 dev t dev 定義了32位的裝置號,其中12位是主裝置號,20位是從裝置號。獲取主裝置號 major dev t dev 獲取從裝置號...
驅動實驗(1)字元裝置驅動實驗
練習字元裝置驅動的兩種模板之後,編寫乙個字元驅動程式 chartest虛擬裝置 由驅動程式4管理,所指向的裝置是64號裝置,類似於串列埠終端或者字元裝置終端 include include include include include include define chrdevbase major...