基于led驅(qū)動(dòng)框架實(shí)現(xiàn)led驅(qū)動(dòng)
驅(qū)動(dòng)共三種形式
1、file_operation形式,在/dev下生成設(shè)備文件,屬于內(nèi)核開放接口,操作設(shè)備文件操作硬件
2、attribute形式,在sys/class下生成屬性文件,通過屬性操作硬件
3、platform形式,在sys/devices/platform下生成文件,屬于平臺類設(shè)備,也是直接操作設(shè)備文件實(shí)現(xiàn)對硬件的操作
led驅(qū)動(dòng)框架屬于attribute方法實(shí)現(xiàn)驅(qū)動(dòng),將整個(gè)驅(qū)動(dòng)分為兩層,第一層是內(nèi)核開發(fā)人員編寫的led驅(qū)動(dòng)抽象層,封裝了led驅(qū)動(dòng)的共同特性,例如字符設(shè)備的注冊與注銷,led框架類的結(jié)構(gòu)體。
第二層則是驅(qū)動(dòng)開發(fā)工程師需要去實(shí)現(xiàn)的,填充led_classdev結(jié)構(gòu)體,由于show和store是需要操作硬件的方法,而其方法本身屬于led驅(qū)動(dòng)抽象層,不能直接操作具體硬件,因此只能通過指針的方式與具體硬件的操作方法進(jìn)行掛接,最終完成對硬件的操作。對于led驅(qū)動(dòng),執(zhí)行對硬件操作的指針是brightness_set,并且show方法并不是真的實(shí)現(xiàn)了對gpio口的值的讀取,而是直接使用輸入的賦值給brightness。
還有值得一說的是,在linux中,gpio也被看做一種資源,內(nèi)核開發(fā)者是用來gpiolib作為資源管理器進(jìn)行管理。因此在驅(qū)動(dòng)程序中應(yīng)當(dāng)盡量避免直接操作相關(guān)資源,避免出現(xiàn)多個(gè)驅(qū)動(dòng)獲得同一資源的bug出現(xiàn)。
使用gpiolib完成gpio設(shè)置的流程如下:
(1)使用gpio_request()/gpio_request_array()申請gpio資源
(2)使用gpio_direction_output()/gpio_direction_input()設(shè)置gpio為輸出或者輸入模式
(3)設(shè)置gpio_set_value()設(shè)置gpio的電平狀態(tài),或者調(diào)用gpio_get_value獲取gpio值
綜上,使用led驅(qū)動(dòng)框架編寫驅(qū)動(dòng)的流程如下:
(1)在模塊的初始化函數(shù)xxx_init中調(diào)用led框架開發(fā)的注冊接口led_classdev_register注冊led驅(qū)動(dòng)模塊,并在此初始化函數(shù)中完成相關(guān)資源的申請。初始化led框架所開發(fā)給驅(qū)動(dòng)開發(fā)者的結(jié)構(gòu)體struct led_classdev(可根據(jù)需要填充相關(guān)項(xiàng))。
(2)編寫相關(guān)的硬件操作函數(shù),調(diào)用gpio_set_value完成gpio值的設(shè)置