色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 嵌入式Linux設(shè)備驅(qū)動開發(fā)之:塊設(shè)備驅(qū)動編程

          嵌入式Linux設(shè)備驅(qū)動開發(fā)之:塊設(shè)備驅(qū)動編程

          作者: 時間:2013-09-13 來源:網(wǎng)絡(luò) 收藏

          本文引用地址:http://cafeforensic.com/article/257109.htm

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

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

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

          圖11.6塊程序初始化過程

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

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

          intregister_blkdev(unsignedintmajor,constchar*name);

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

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

          intunregister_blkdev(unsignedintmajor,constchar*name);

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

          (2)申請并初始化請求隊列。

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

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

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

          (3)初始化并注冊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ù)格式

          說明

          structgendisk*alloc_disk(intminors)

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

          voidadd_disk(structgendisk*disk)

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

          voiddel_gendisk(structgendisk*disk)

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

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

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

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

          中一般要實現(xiàn)一個請求隊列處理函數(shù)來處理隊列中的請求。從塊設(shè)備的運行流程,可知請求處理是塊設(shè)備的基本處理單位,也是最核心的部分。對塊設(shè)備的讀寫操作被封裝到了每一個請求中。

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

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

          函數(shù)格式

          說明

          request_queue_t*blk_alloc_queue(intgfp_mask)

          分配請求隊列

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

          分配并初始化請求隊列

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

          從隊列中獲取一個請求

          voidblk_requeue_request(request_queue_t*q,structrequest*rq)

          將請求再次加入隊列

          voidblk_queue_max_sectors
          (request_queue_t*q,unsignedshortmax_sectors)

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

          voidblk_queue_max_phys_segments
          (request_queue_t*q,unsignedshortmax_segments)

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

          voidend_request(structrequest*req,intuptodate)

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

          voidblk_queue_hardsect_size
          (request_queue_t*q,unsignedshortsize)

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

          以上簡單地介紹了的最基本的概念和流程。更深入的內(nèi)容不是本書的重點,有興趣的讀者可以參考其他書籍。

          linux相關(guān)文章:linux教程



          上一頁 1 2 下一頁

          評論


          相關(guān)推薦

          推薦視頻

          更多>>

          技術(shù)專區(qū)

          關(guān)閉