資源描述:
《Linux設(shè)備驅(qū)動(dòng)的分層設(shè)計(jì)思想》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫。
1、Linux設(shè)備驅(qū)動(dòng)的分層設(shè)計(jì)思想1.1設(shè)備驅(qū)動(dòng)核心層和例化在面向?qū)ο蟮某绦蛟O(shè)計(jì)中,可以為某一類相似的事物定義一個(gè)基類,而具體的事物可以繼承這個(gè)基類中的函數(shù)。如果對(duì)于繼承的這個(gè)事物而言,其某函數(shù)的實(shí)現(xiàn)與基類一致,那它就可以直接繼承基類的函數(shù);相反,它可以重載之。這種面向?qū)ο蟮脑O(shè)計(jì)思想極大地提高了代碼的可重用能力,是對(duì)現(xiàn)實(shí)世界事物間關(guān)系的一種良好呈現(xiàn)。Linux內(nèi)核完全由C語言和匯編語言寫成,但是卻頻繁用到了面向?qū)ο蟮脑O(shè)計(jì)思想。在設(shè)備驅(qū)動(dòng)方面,往往為同類的設(shè)備設(shè)計(jì)了一個(gè)框架,而框架中的核心層則實(shí)現(xiàn)了該設(shè)備通用的一些功能。同樣的
2、,如果具體的設(shè)備不想使用核心層的函數(shù),它可以重載之。舉個(gè)例子:return_typecore_funca(xxx_device*bottom_dev,param1_typeparam1,param1_typeparam2){if(bottom_dev->funca)returnbottom_dev->funca(param1,param2);/*核心層通用的funca代碼*/...}上述core_funca的實(shí)現(xiàn)中,會(huì)檢查底層設(shè)備是否重載了funca(),如果重載了,就調(diào)用底層的代碼,否則,直接使用通用層的。這樣做的好處是
3、,核心層的代碼可以處理絕大多數(shù)該類設(shè)備的funca()對(duì)應(yīng)的功能,只有少數(shù)特殊設(shè)備需要重新實(shí)現(xiàn)funca()。再看一個(gè)例子:return_typecore_funca(xxx_device*bottom_dev,param1_typeparam1,param1_typeparam2){/*通用的步驟代碼A*/...bottom_dev->funca_ops1();/*通用的步驟代碼B*/...bottom_dev->funca_ops2();/*通用的步驟代碼C*/...bottom_dev->funca_ops3();}
4、上述代碼假定為了實(shí)現(xiàn)funca(),對(duì)于同類設(shè)備而言,操作流程一致,都要經(jīng)過“通用代碼A、底層ops1、通用代碼B、底層ops2、通用代碼C、底層ops3”這幾步,分層設(shè)計(jì)明顯帶來的好處是,對(duì)于通用代碼A、B、C,具體的底層驅(qū)動(dòng)不需要再實(shí)現(xiàn),而僅僅只關(guān)心其底層的操作ops1、ops2、ops3。圖1明確反映了設(shè)備驅(qū)動(dòng)的核心層與具體設(shè)備驅(qū)動(dòng)的關(guān)系,實(shí)際上,這種分層可能只有2層(圖1的a),也可能是多層的(圖1的b)。圖1Linux設(shè)備驅(qū)動(dòng)的分層這樣的分層化設(shè)計(jì)在Linux的input、RTC、MTD、I2C、SPI、TTY、
5、USB等諸多設(shè)備驅(qū)動(dòng)類型中屢見不鮮。下面的2節(jié)以input和RTC為例先行進(jìn)行一番說明,當(dāng)然,后續(xù)的章節(jié)會(huì)對(duì)幾個(gè)大的設(shè)備類型對(duì)應(yīng)驅(qū)動(dòng)的層次進(jìn)行更詳細(xì)的分析1.2輸入設(shè)備驅(qū)動(dòng)輸入設(shè)備(如按鍵、鍵盤、觸摸屏、鼠標(biāo)等)是典型的字符設(shè)備,其一般的工作機(jī)理是底層在按鍵、觸摸等動(dòng)作發(fā)送時(shí)產(chǎn)生一個(gè)中斷(或驅(qū)動(dòng)通過timer定時(shí)查詢),然后CPU通過SPI、I2C或外部存儲(chǔ)器總線讀取鍵值、坐標(biāo)等數(shù)據(jù),放入1個(gè)緩沖區(qū),字符設(shè)備驅(qū)動(dòng)管理該緩沖區(qū),而驅(qū)動(dòng)的read()接口讓用戶可以讀取鍵值、坐標(biāo)等數(shù)據(jù)。顯然,在這些工作中,只是中斷、讀值是設(shè)備相
6、關(guān)的,而輸入事件的緩沖區(qū)管理以及字符設(shè)備驅(qū)動(dòng)的file_operations接口則對(duì)輸入設(shè)備是通用的?;诖?,內(nèi)核設(shè)計(jì)了輸入子系統(tǒng),由核心層處理公共的工作。Linux內(nèi)核輸入子系統(tǒng)的框架如圖2所示。圖2Linux輸入設(shè)備驅(qū)動(dòng)的分層輸入核心提供了底層輸入設(shè)備驅(qū)動(dòng)程序所需的API,如分配/釋放一個(gè)輸入設(shè)備:structinput_dev*input_allocate_device(void);voidinput_free_device(structinput_dev*dev);input_allocate_device()返回
7、的是1個(gè)input_dev的結(jié)構(gòu)體,此結(jié)構(gòu)體用于表征1個(gè)輸入設(shè)備。注冊(cè)/注銷輸入設(shè)備用的如下接口:int__must_checkinput_register_device(structinput_dev*);voidinput_unregister_device(structinput_dev*);報(bào)告輸入事件用的如下接口:/*報(bào)告指定type、code的輸入事件*/voidinput_event(structinput_dev*dev,unsignedinttype,unsignedintcode,intvalue);/
8、*報(bào)告鍵值*/voidinput_report_key(structinput_dev*dev,unsignedintcode,intvalue);/*報(bào)告相對(duì)坐標(biāo)*/voidinput_report_rel(structinput_dev*dev,unsignedintcode,intvalue);/