驱动框架之LED
一、什么是驅(qū)動框架?
1、驅(qū)動是誰寫的?
(1)驅(qū)動開發(fā)工程師;
(2)內(nèi)核維護(hù)者;
2、驅(qū)動編程協(xié)作要求
(1)接口標(biāo)準(zhǔn)化;
(2)內(nèi)核開發(fā)者應(yīng)該盡量降低驅(qū)動開發(fā)者難度;
3、到底什么是驅(qū)動框架?
(1)驅(qū)動框架
- 內(nèi)核中驅(qū)動部分維護(hù)者,針對每個種類(比如LED、LCD、蜂鳴器等等)的設(shè)備,都設(shè)計有一套成熟的、標(biāo)準(zhǔn)的、典型的驅(qū)動實現(xiàn);
- 它是把不同廠家的同類硬件驅(qū)動中相同的部分抽出來自己實現(xiàn)好,再把不同部分留出接口給具體的驅(qū)動開發(fā)工程師來實現(xiàn)。
- 降低了難度,也標(biāo)準(zhǔn)化。
(2)內(nèi)核維護(hù)者在內(nèi)核中設(shè)計了一些(統(tǒng)一管控系統(tǒng)資源的)體系
- 這些體系讓內(nèi)核能夠(對資源在各個驅(qū)動之間的使用)統(tǒng)一協(xié)調(diào)和分配,保證整個內(nèi)核的穩(wěn)定健康運行。
- 譬如系統(tǒng)中所有的GPIO就屬于系統(tǒng)資源,每個驅(qū)動模塊如果要使用某個GPIO就要先調(diào)用特殊的接口先申請,申請到后使用,使用完后要釋放。
- 又譬如中斷號也是一種資源,驅(qū)動在使用前也必須去申請。
- 這體系也是驅(qū)動框架的組成部分。
(3)一些特定的接口函數(shù)、一些特定的數(shù)據(jù)結(jié)構(gòu),這些是驅(qū)動框架的直接表現(xiàn)。
?
二、內(nèi)核驅(qū)動框架中LED的基本情況
1、相關(guān)文件
(1)drivers/leds目錄
- 這個目錄就是驅(qū)動框架規(guī)定的LED這種硬件的驅(qū)動應(yīng)該待的地方。
(2)drivers/leds目錄下有l(wèi)ed-class.c和led-core.c
- 這兩個文件加起來屬于LED驅(qū)動框架的第一部分,這兩個文件是內(nèi)核開發(fā)者提供的,他們描述的是內(nèi)核中所有廠家的不同LED硬件的相同部分的邏輯。
(3)此目錄下有l(wèi)eds-xxxx.c
- 這個文件是LED驅(qū)動框架的第2部分,是由不同廠商的驅(qū)動工程師編寫添加的;
- 廠商驅(qū)動工程師結(jié)合自己公司的硬件的不同情況來對LED進(jìn)行操作,使用第一部分提供的接口來和驅(qū)動框架進(jìn)行交互,最終實現(xiàn)驅(qū)動的功能。
2、典型的驅(qū)動開發(fā)行業(yè)現(xiàn)狀
(1)內(nèi)核開發(fā)者對驅(qū)動框架進(jìn)行開發(fā)和維護(hù)、升級,對應(yīng)led-class.c和led-core.c;
(2)SoC廠商的驅(qū)動工程師對設(shè)備驅(qū)動源碼進(jìn)行編寫、調(diào)試,提供參考版本,對應(yīng)leds-s3c24xx.c;
(3)做產(chǎn)品的廠商的驅(qū)動工程師以SoC廠商提供的驅(qū)動源碼為基礎(chǔ),來做移植和調(diào)試;
?
二、內(nèi)核添加led驅(qū)動框架支持
當(dāng)前內(nèi)核中沒有LED驅(qū)動框架,要去添加它。(/sys/class目錄下沒有此類,因此要去添加此類)
配置內(nèi)核,make menuconfig
Device Drivers ?--->
?? ?[*] LED Support ?--->
?? ??? ?<*> ??LED Class Support
?
三、內(nèi)核驅(qū)動框架中LED的接口
1、led_classdev_register設(shè)備注冊函數(shù)
?
int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)- led_classdev_register函數(shù)創(chuàng)建一個屬于leds這個類的一個設(shè)備,其實就是去注冊一個設(shè)備。
- 這個函數(shù)是led驅(qū)動框架中,內(nèi)核開發(fā)者提供給SoC廠家驅(qū)動開發(fā)者的一個注冊驅(qū)動的接口。
- 當(dāng)使用led驅(qū)動框架去編寫驅(qū)動的時候,這個led_classdev_register函數(shù)的作用類似于之前使用file_operations方式去注冊字符設(shè)備驅(qū)動時的register_chrdev函數(shù)。
- 之前使用file_operations方式時,在sys/class目錄下創(chuàng)建一個類,然后再創(chuàng)建屬于這個類的一個設(shè)備。
2、led_classdev結(jié)構(gòu)體
看一下led_classdev中的主要成員 struct led_classdev {const char *name; //設(shè)備名字int brightness; //當(dāng)前亮度值int max_brightness; //最大亮度值...void (*brightness_set)(struct led_classdev *led_cdev, enum led_brightness brightness); /* 設(shè)置led亮度值 */... };?
四、基于驅(qū)動框架寫led驅(qū)動
完整的led驅(qū)動
#include <linux/module.h> #include <linux/init.h> #include <linux/leds.h>static struct led_classdev mydev;/* led設(shè)置接口 */ static void s5pv210_led_set(struct led_classdev *led_cdev, enum led_brightness value) {printk(KERN_INFO "s5pv210_led_set\n"); }static int __init s5pv210_led_init(void) {int ret = -1;mydev.name = "led";mydev.brightness = 0; mydev.brightness_set = s5pv210_led_set;/* 注冊led設(shè)備 */ret = led_classdev_register(NULL, &mydev);if (ret < 0) {printk(KERN_ERR "led_classdev_register failed\n");return ret;}return 0; }static void __exit s5pv210_led_exit(void) {/* 注銷led設(shè)備 */led_classdev_unregister(&mydev); }module_init(s5pv210_led_init); module_exit(s5pv210_led_exit);// MODULE_xxx這種宏作用是用來添加模塊描述信息 MODULE_LICENSE("GPL"); // 描述模塊的許可證 MODULE_AUTHOR("lsm"); // 描述模塊的作者 MODULE_DESCRIPTION("s5pv210 led driver"); // 描述模塊的介紹信息 MODULE_ALIAS("s5pv210_led"); // 描述模塊的別名信息?
五、查看led設(shè)備
安裝好led驅(qū)動之后,進(jìn)入/sys/class/leds/led
打印出s5pv210_led_set,表示使用led框架成功。
總結(jié)
- 上一篇: 抱歉!我不太会修电脑 | 2018年中国
- 下一篇: 正弦稳态电路的分析