日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > 嵌入式 > 嵌入式教程
[導(dǎo)讀]塊設(shè)備通常指一些需要以塊(如512字節(jié))的方式寫入的設(shè)備,如IDE硬盤、SCSI硬盤、光驅(qū)等。它的驅(qū)動(dòng)程序的編寫過(guò)程與字符型設(shè)備驅(qū)動(dòng)程序的編寫有很大的區(qū)別。

11.4塊設(shè)備驅(qū)動(dòng)編程

塊設(shè)備通常指一些需要以塊(如512字節(jié))的方式寫入的設(shè)備,如IDE硬盤、SCSI硬盤、光驅(qū)等。它的驅(qū)動(dòng)程序的編寫過(guò)程與字符型設(shè)備驅(qū)動(dòng)程序的編寫有很大的區(qū)別。

塊設(shè)備驅(qū)動(dòng)編程接口相對(duì)復(fù)雜,不如字符設(shè)備明晰易用。塊設(shè)備驅(qū)動(dòng)程序?qū)φ麄€(gè)系統(tǒng)的性能影響較大,速度和效率是設(shè)計(jì)塊設(shè)備驅(qū)動(dòng)程要重點(diǎn)考慮的問(wèn)題。系統(tǒng)中使用緩沖區(qū)與訪問(wèn)請(qǐng)求的優(yōu)化管理(合并與重新排序)來(lái)提高系統(tǒng)性能。

1.編程流程說(shuō)明

塊設(shè)備驅(qū)動(dòng)程序的編寫流程同字符設(shè)備驅(qū)動(dòng)程序的編寫流程很類似,也包括了注冊(cè)和使用兩部分。但與字符驅(qū)動(dòng)設(shè)備所不同的是,塊設(shè)備驅(qū)動(dòng)程序包括一個(gè)request請(qǐng)求隊(duì)列。它是當(dāng)內(nèi)核安排一次數(shù)據(jù)傳輸時(shí)在列表中的一個(gè)請(qǐng)求隊(duì)列,以最大化系統(tǒng)性能為原則進(jìn)行排序。在后面的讀寫操作時(shí)會(huì)詳細(xì)講解這個(gè)函數(shù),圖11.5為塊設(shè)備驅(qū)動(dòng)程序的流程圖,請(qǐng)讀者注意與字符設(shè)備驅(qū)動(dòng)程序的區(qū)別。

圖11.5塊設(shè)備驅(qū)動(dòng)程序流程圖

2.重要數(shù)據(jù)結(jié)構(gòu)

每個(gè)塊設(shè)備物理實(shí)體由一個(gè)gendisk結(jié)構(gòu)體來(lái)表示(在</linux/genhd.h>中定義),每個(gè)gendisk可以支持多個(gè)分區(qū)。

每個(gè)gendisk中包含了本物理實(shí)體的全部信息以及操作函數(shù)接口。整個(gè)塊設(shè)備的注冊(cè)過(guò)程是圍繞gendisk來(lái)展開(kāi)的。在驅(qū)動(dòng)程序中需要初始化的gendisk的一些成員如下所示。

structgendisk

{

intmajor;/*主設(shè)備號(hào)*/

intfirst_minor;/*第一個(gè)次設(shè)備號(hào)*/

intminors;/*次設(shè)備號(hào)個(gè)數(shù),一個(gè)塊設(shè)備至少需要使用一個(gè)次設(shè)備號(hào),而且塊設(shè)

備的每個(gè)分區(qū)都需要一個(gè)次設(shè)備號(hào),因此這個(gè)成員等于1,則表明該塊

設(shè)備是不可被分區(qū)的,否則可以包含minors–1個(gè)分區(qū)。*/

chardisk_name[32];/*塊設(shè)備名稱,在/proc/partions中顯示*/

structhd_struct**part;/*分區(qū)表*/

structblock_device_operations*fops;/*塊設(shè)備操作接口,與字符設(shè)備的

file_operations結(jié)構(gòu)對(duì)應(yīng)*/

structrequest_queue*queue;/*I/O請(qǐng)求隊(duì)列*/

void*private_data;/*指向驅(qū)動(dòng)程序私有數(shù)據(jù)*/

sector_tcapacity;/*塊設(shè)備可包含的扇區(qū)數(shù)*/

……/*其他省略*/

};

與字符設(shè)備驅(qū)動(dòng)程序一樣,塊設(shè)備驅(qū)動(dòng)程序也包含一個(gè)在<linux/fs.h>中定義的block_device_operations結(jié)構(gòu),其定義如下所示。

structblock_device_operations

{

int(*open)(structinode*,structfile*);

int(*release)(structinode*,structfile*);

int(*ioctl)(structinode*,structfile*,unsigned,unsignedlong);

long(*unlocked_ioctl)(structfile*,unsigned,unsignedlong);

long(*compat_ioctl)(structfile*,unsigned,unsignedlong);

int(*direct_access)(structblock_device*,sector_t,unsignedlong*);

int(*media_changed)(structgendisk*);

int(*revalidate_disk)(structgendisk*);

int(*getgeo)(structblock_device*,structhd_geometry*);

structmodule*owner;

};

從該結(jié)構(gòu)的定義中,可以看出塊設(shè)備并不提供read()、write()等函數(shù)接口。對(duì)塊設(shè)備的讀寫請(qǐng)求都是以異步方式發(fā)送到設(shè)備相關(guān)的request隊(duì)列之中。

3.塊設(shè)備注冊(cè)和初始化

塊設(shè)備的初始化過(guò)程要比字符設(shè)備復(fù)雜,它既需要像字符設(shè)備一樣在加載內(nèi)核時(shí)完成一定的工作,還需要在內(nèi)核編譯時(shí)增加一些內(nèi)容。塊設(shè)備驅(qū)動(dòng)程序初始化時(shí),由驅(qū)動(dòng)程序的init()完成。

塊設(shè)備的初始化過(guò)程如圖11.6所示。

圖11.6塊設(shè)備驅(qū)動(dòng)程序初始化過(guò)程

(1)向內(nèi)核注冊(cè)。

使用register_blkdev()函數(shù)對(duì)設(shè)備進(jìn)行注冊(cè)。

intregister_blkdev(unsignedintmajor,constchar*name);

其中參數(shù)major為要注冊(cè)的塊設(shè)備的主設(shè)備號(hào),如果其值等于0,則系統(tǒng)動(dòng)態(tài)分配并返回主設(shè)備號(hào)。參數(shù)name為設(shè)備名,在/proc/devices中顯示。如果出錯(cuò),則該函數(shù)返回負(fù)值。

與其對(duì)應(yīng)的塊設(shè)備的注銷函數(shù)為unregister_blkdev(),其格式如下所示。

intunregister_blkdev(unsignedintmajor,constchar*name);

其參數(shù)必須與注冊(cè)函數(shù)中的參數(shù)相同。如果出錯(cuò)則返回負(fù)值。

(2)申請(qǐng)并初始化請(qǐng)求隊(duì)列。

這一步要調(diào)用blk_init_queue()函數(shù)來(lái)申請(qǐng)并初始化請(qǐng)求隊(duì)列,其格式如下所示。

structrequest_queue*blk_init_queue(request_fn_proc*rfn,spinlock_t*lock)

其中參數(shù)rfn是請(qǐng)求隊(duì)列的處理函數(shù)指針,它負(fù)責(zé)執(zhí)行塊設(shè)備的讀、寫請(qǐng)求。參數(shù)lock為自旋鎖,用于控制對(duì)所分配的隊(duì)列的訪問(wèn)。

(3)初始化并注冊(cè)gendisk結(jié)構(gòu)。

內(nèi)核提供的gendisk結(jié)構(gòu)相關(guān)函數(shù)如表11-16所示。

表11-16 gendisk結(jié)構(gòu)相關(guān)函數(shù)

函數(shù)格式

說(shuō)明

structgendisk*alloc_disk(intminors)

動(dòng)態(tài)分配gendisk結(jié)構(gòu),參數(shù)為次設(shè)備號(hào)的個(gè)數(shù)

voidadd_disk(structgendisk*disk)

向系統(tǒng)注冊(cè)gendisk結(jié)構(gòu)

voiddel_gendisk(structgendisk*disk)

從系統(tǒng)注銷gendisk結(jié)構(gòu)

首先使用alloc_disk()函數(shù)動(dòng)態(tài)分配gendisk結(jié)構(gòu),接下來(lái),對(duì)gendisk結(jié)構(gòu)的主設(shè)備號(hào)(major)、次設(shè)備號(hào)相關(guān)成員(first_minor和minors)、塊設(shè)備操作函數(shù)(fops)、請(qǐng)求隊(duì)列(queue)、可包含的扇區(qū)數(shù)(capacity)以及設(shè)備名稱(disk_name)等成員進(jìn)行初始化。

在完成對(duì)gendisk的分配和初始化之后,調(diào)用add_disk()函數(shù)向系統(tǒng)注冊(cè)塊設(shè)備。在卸載gendisk結(jié)構(gòu)的時(shí)候,要調(diào)用del_gendisk()函數(shù)。

4.塊設(shè)備請(qǐng)求處理

塊設(shè)備驅(qū)動(dòng)中一般要實(shí)現(xiàn)一個(gè)請(qǐng)求隊(duì)列處理函數(shù)來(lái)處理隊(duì)列中的請(qǐng)求。從塊設(shè)備的運(yùn)行流程,可知請(qǐng)求處理是塊設(shè)備的基本處理單位,也是最核心的部分。對(duì)塊設(shè)備的讀寫操作被封裝到了每一個(gè)請(qǐng)求中。

已經(jīng)提過(guò)調(diào)用blk_init_queue()函數(shù)來(lái)申請(qǐng)并初始化請(qǐng)求隊(duì)列。表11-17列出了一些與請(qǐng)求處理相關(guān)的函數(shù)。

表11-17 請(qǐng)求處理相關(guān)函數(shù)

函數(shù)格式

說(shuō)明

request_queue_t*blk_alloc_queue(intgfp_mask)

分配請(qǐng)求隊(duì)列

request_queue_t*blk_init_queue
(request_fn_proc*rfn,spinlock_t*lock)

分配并初始化請(qǐng)求隊(duì)列

structrequest*blk_get_request
(request_queue_t*q,intrw,intgfp_mask)

從隊(duì)列中獲取一個(gè)請(qǐng)求

voidblk_requeue_request(request_queue_t*q,structrequest*rq)

將請(qǐng)求再次加入隊(duì)列

voidblk_queue_max_sectors
(request_queue_t*q,unsignedshortmax_sectors)

設(shè)置最大訪問(wèn)扇區(qū)數(shù)

voidblk_queue_max_phys_segments
(request_queue_t*q,unsignedshortmax_segments)

設(shè)置最大物理段數(shù)

voidend_request(structrequest*req,intuptodate)

結(jié)束本次請(qǐng)求處理

voidblk_queue_hardsect_size
(request_queue_t*q,unsignedshortsize)

設(shè)置物理扇區(qū)大小

以上簡(jiǎn)單地介紹了塊設(shè)備驅(qū)動(dòng)編程的最基本的概念和流程。更深入的內(nèi)容不是本書的重點(diǎn),有興趣的讀者可以參考其他書籍。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過(guò)流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問(wèn)題卻十分常見(jiàn),不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問(wèn)題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問(wèn)題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來(lái)解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開(kāi)關(guān)電源具有效率高的特性,而且開(kāi)關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開(kāi)關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉