Linux裝置驅動程式設計例項

2021-04-13 23:00:02 字數 3824 閱讀 5501

linux系統中,裝置驅動程式是作業系統核心的重要組成部分,在 與硬體裝置之間

建立了標準的抽象介面。通過這個介面,使用者可以像處理普通檔案一樣,對硬體設

備進行開啟(open)、關閉(close)、讀寫(read/write)等操作。通過分析和設計設

備驅動程式,可以深入理解linux系統和進行系統開發。本文通過乙個簡單的例子

來說明裝置驅動程式的設計。

1、   程式清單

//      mydev.c      2023年2月7日編寫

#ifndef __kernel__

# define __kernel__  //按核心模組編譯

#endif

#ifndef module

# define module        //裝置驅動程式模組編譯

#endif

#define device_name "mydev"  

#define openspk 1

#define closespk 2

//必要的標頭檔案

#include

//同kernel.h,最基本的核心模組標頭檔案

#include

//同module.h,最基本的核心模組標頭檔案

#include

//這裡包含了進行正確性檢查的巨集

#include

//檔案系統所必需的標頭檔案

#include

//這裡包含了核心空間與使用者空間進行資料交換時的

函式巨集

#include

//i/o訪問

int my_major=0;         //主裝置號

static int device_open=0;

static char message="this is from device driver";

char *message_ptr;

int my_open(struct inode *inode, struct file *file)

static void my_release(struct inode *inode, struct file *file)

ssize_t my_read (struct file *f,char *buf,int size,loff_t off)

return bytes_read;

} ssize_t my_write (struct file *f,const char *buf, int size,loff_t off)

int my_ioctl(struct inode *inod,struct file *f,unsigned int arg1,

unsigned int arg2) }

struct file_operations my_fops = ;

int init_module(void)

void cleanup_module(void)

2、   裝置  驅動程式設計

linux裝置分為字元裝置、塊裝置和網路裝置。字元裝置是不需要緩衝而直接

讀寫的裝置,如串列埠、鍵盤、滑鼠等,本例就是字元裝置驅動程式;塊裝置的訪問

通常需要緩衝來支援,以資料塊為單位來讀寫,如磁碟裝置等;網路裝置是通過套

接字來訪問的特殊裝置。

1) 裝置驅動程式和核心與應用程式的介面

無論哪種型別的裝置,linux都是通過在核心中維護特殊的裝置控制塊來與設

備驅動程式介面的。在字元裝置和塊裝置的控制塊中,有乙個重要的資料結構

file_operations,該結構中包含了驅動程式提供給應用程式訪問硬體裝置的各種

方法,其定義如下(參見fs.h):

struct file_operations ;

多數情況下,只需為上面結構中的少數方法編寫服務函式,其他均設為null即可。

每乙個可裝配的裝置驅動程式都必須有init_module和cleanup_module兩個函式,

裝載和解除安裝裝置時核心自動呼叫這兩個函式。在init_module中,除了可以對硬體

裝置進行檢查和初始化外,還必須呼叫register_* 函式將裝置登記到系統中。本

例中是通過register_chrdev來登記的,如果是塊裝置或網路裝置則應該用

register_blkdev和register_netdev來登記。register_chrdev 的主要功能是將設

備名和結構file_operations登記到系統的裝置控制塊中。

2) 與應用程式的資料交換

由於裝置驅動程式工作在核心儲存空間,不能簡單地用"="、"memcpy"等方法與應

用程式交換資料。在標頭檔案uaccess.h中定義了方法put_user(x, ptr)和

get_user(x, ptr),用於核心空間與使用者空間的資料交換。值x的型別根據指標

ptr的型別確定,請參見源**中的my_read與my_write函式。

3) 與硬體裝置的介面

linux中為裝置驅動程式訪問i/o埠、硬體中斷和dma提供了簡便方法,相應的頭

檔案分別為io.h、irq.h、dma.h。由於篇輻限制,本例中只涉及到i/o埠訪問。

linux提供的i/o埠訪問方法主要有:inb()、inw()、outb()、outw()、inb_p()

、inw_p()、outb_p()、outw_p()等。要注意的是,裝置驅動程式在使用埠前,

應該先用check_region()檢查該埠的占用情況,如果指定的埠可用,則再用

request_region()向系統登記。說明check_region()、request_region()的標頭檔案

是ioport.h。

4) 記憶體分配

裝置驅動程式作為核心的一部分,不能使用虛擬記憶體,必須利用核心提供的

kmalloc()與kfree()來申請和釋放核心儲存空間。kmalloc()帶兩個引數,第乙個

要申請的是記憶體數量,在早期的版本中,這個數量必須是2的整數冪,如128、256

。關於kmalloc()與kfree()的用法,可參考核心源程式中的malloc.h與slab.c程式

。 3、程式的編譯和訪問

本例在linux 2.2.x.x中可以成功編譯和執行。先用下面的命令列進行編譯:

gcc -wall -o2 -c mydev.c

該命令列中引數-wall告訴編譯程式顯示警告資訊;引數-o2是關於**優化的設定

,注意核心模組必須優化;引數-c規定只進行編譯和彙編,不進行連線。

正確編譯後,形成mydev.o檔案。可以輸入命令in**od mydev.o來裝載此程式。如

果裝配成功,則顯示資訊:register ok.major-number=xx。利用命令l**od可以看

到該模組被裝配到系統中。

為了訪問該模組,應該用命令mknode來建立裝置檔案。下面的應用程式可以對建立

的裝置檔案進行訪問。

本文**

Linux裝置驅動程式設計例項

linux系統中,裝置驅動程式是作業系統核心的重要組成部分,在 與硬體裝置之間建立了標準的抽象介面。通過這個介面,使用者可以像處理普通檔案一樣,對硬體裝置進行開啟 open 關閉 close 讀寫 read write 等操作。通過分析和設計裝置驅動程式,可以深入理解linux系統和進行系統開發。本...

Linux裝置驅動程式設計例項

linux系統中,裝置驅動程式是作業系統核心的重要組成部分,在與硬體裝置之間建立了標準的抽象介面。通過 這個介面,使用者可以像處理普通檔案一樣,對硬體裝置進行開啟 open 關閉 close 讀寫 read write 等操作。通過分析和設計裝置 驅動程式,可以深入理解linux系統和進行系統開發。...

裝置驅動例項 字元裝置驅動

在整個linux裝置驅動學習中,字元裝置驅動較為基礎。通過對它的學習,對裝置驅動進一步加深了解 cdev 結構體struct cdev 講下比較重要的成員變數 dev t dev 定義了32位的裝置號,其中12位是主裝置號,20位是從裝置號。獲取主裝置號 major dev t dev 獲取從裝置號...