1. 程式人生 > >深入淺出:Linux裝置驅動之字元裝置驅動

深入淺出:Linux裝置驅動之字元裝置驅動

一、linux系統將裝置分為3類:字元裝置、塊裝置、網路裝置。使用驅動程式:

  • 字元裝置:是指只能一個位元組一個位元組讀寫的裝置,不能隨機讀取裝置記憶體中的某一資料,讀取資料需要按照先後資料。字元裝置是面向流的裝置,常見的字元裝置有滑鼠、鍵盤、串列埠、控制檯和LED裝置等。
  • 塊裝置:是指可以從裝置的任意位置讀取一定長度資料的裝置。塊裝置包括硬碟、磁碟、U盤和SD卡等。

每一個字元裝置或塊裝置都在/dev目錄下對應一個裝置檔案。linux使用者程式通過裝置檔案(或稱裝置節點)來使用驅動程式操作字元裝置和塊裝置。

二、字元裝置、字元裝置驅動與使用者空間訪問該裝置的程式三者之間的關係。

如圖,在Linux核心中使用cdev結構體來描述字元裝置,通過其成員dev_t來定義裝置號(分為主、次裝置號)以確定字元裝置的唯一性。通過其成員file_operations來定義字元裝置驅動提供給VFS的介面函式,如常見的open()、read()、write()等。

在Linux字元裝置驅動中,模組載入函式通過register_chrdev_region( ) 或alloc_chrdev_region( )來靜態或者動態獲取裝置號,通過cdev_init( )建立cdev與file_operations之間的連線,通過cdev_add( )向系統新增一個cdev以完成註冊。模組解除安裝函式通過cdev_del( )來登出cdev,通過unregister_chrdev_region( )來釋放裝置號。

使用者空間訪問該裝置的程式通過Linux系統呼叫,如open( )、read( )、write( ),來“呼叫”file_operations來定義字元裝置驅動提供給VFS的介面函式。

三、字元裝置驅動模型

1. 驅動初始化

1.1. 分配cdev

在2.6的核心中使用cdev結構體來描述字元裝置,在驅動中分配cdev,主要是分配一個cdev結構體與申請裝置號,以按鍵驅動為例:

1 /*……*/ 2 /* 分配cdev*/ 3 struct cdev btn_cdev; 4 /*……*/ 5
/* 1.1 申請裝置號*/ 6 if(major){ 7 //靜態 8 dev_id = MKDEV(major, 0); 9 register_chrdev_region(dev_id, 1, "button"); 10 } else { 11 //動態 12 alloc_chardev_region(&dev_id, 0, 1, "button"); 13 major = MAJOR(dev_id); 14 } 15 /*……*/

從上面的程式碼可以看出,申請裝置號有動靜之分,其實裝置號還有主次之分。

在Linux中以主裝置號用來標識與裝置檔案相連的驅動程式。次編號被驅動程式用來辨別操作的是哪個裝置。cdev 結構體的 dev_t 成員定義了裝置號,為 32 位,其中高 12 位為主裝置號,低20 位為次裝置號。

裝置號的獲得與生成:

獲得:主裝置號:MAJOR(dev_t dev);

次裝置號:MINOR(dev_t dev);

生成:MKDEV(int major,int minor);

裝置號申請的動靜之分:

靜態:

1 2 1 int register_chrdev_region(dev_t from, unsigned count, const char *name); 2 /*功能:申請使用從from開始的count 個裝置號(主裝置號不變,次裝置號增加)*/

靜態申請相對較簡單,但是一旦驅動被廣泛使用,這個隨機選定的主裝置號可能會導致裝置號衝突,而使驅動程式無法註冊。

動態:

1 2 1 int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,const char *name); 2 /*功能:請求核心動態分配count個裝置號,且次裝置號從baseminor開始。*/

動態申請簡單,易於驅動推廣,但是無法在安裝驅動前建立裝置檔案(因為安裝前還沒有分配到主裝置號)。

1.2. 初始化cdev

1 2

相關推薦

深入淺出Linux裝置驅動字元裝置驅動

一、linux系統將裝置分為3類:字元裝置、塊裝置、網路裝置。使用驅動程式: 字元裝置:是指只能一個位元組一個位元組讀寫的裝置,不能隨機讀取裝置記憶體中的某一資料,讀取資料需要按照先後資料。字元裝置是面向流的裝置,常見的字元裝置有滑鼠、鍵盤、串列埠、

Linux驅動字元裝置工作原理(未完)

字元裝置驅動工作原理 系統整體工作原理 應用層->API->裝置驅動->硬體? API:open、read、write、close等? 驅動原始碼中提供真正的open、read、write、close等函式實體? file_

linux驅動字元裝置

第一部分:字元裝置工作過程1、系統呼叫和驅動程式的關聯關鍵結構體:struct file_operation;file_operation結構體的每一個成員的名字都對應著一個系統呼叫。使用者程序利用系統呼叫在對裝置檔案進行諸如read/write操作時,系統呼叫通過裝置檔案的主裝置號找到相應的裝置驅動程式,然

Linux裝置驅動字元裝置驅動---轉

一、linux系統將裝置分為3類:字元裝置、塊裝置、網路裝置。 應用程式呼叫的流程框圖: 三種裝置的定義分別如下, 字元裝置:只能一個位元組一個位元組的讀寫的裝置,不能隨機讀取裝置記憶體中的某一資料,讀取資料需要按照先後順序進行。字元裝置是面向流的裝置,常見的字

Linux裝置驅動字元裝置(一)

Linux中裝置驅動的分類 從上圖可以看到Linux系統將各異的裝置分為三大類:字元裝置,塊裝置和網路裝置。核心針對每一類裝置都提供了對應驅動模型架構,包括基本的核心設施和檔案系統介面。 字元裝置:在傳送過程中以字元為單位,一個位元組一個位元組的讀寫,不

Linux裝置驅動字元裝置驅動

一、linux系統將裝置分為3類:字元裝置、塊裝置、網路裝置。 應用程式呼叫的流程框圖: 三種裝置的定義分別如下, 字元裝置:只能一個位元組一個位元組的讀寫的裝置,不能隨機讀取裝置記憶體中的某一資料,讀取資料需要按照先後順序進行。字元裝置是面向流的裝置,常見的字元裝置如

linux驅動字元裝置驅動

字元裝置驅動框架: cdev結構體: 描述字元裝置; dev_t:定義裝置號(分為主、次裝置號)以確定字元裝置的唯一性; file_operations:定義字元裝置驅動提供給VFS的介面函式,如常見的open()、read()、write()等;

I2C裝置驅動字元裝置簡寫

最近有機會需要寫一個 掛載在I2C匯流排的I2C裝置驅動,外設晶片是MCP23017 IO擴充套件晶片,測試是否可以通訊成功,以下是部分程式碼以及除錯的一些注意項: #include <linux/kernel.h> #include <linux/init.h>

linux driver ------ 字元裝置驅動“ 建立裝置節點流程 ”

在字元裝置驅動開發的入門教程中,最常見的就是用device_create()函式來建立裝置節點了,但是在之後閱讀核心原始碼的過程中卻很少見device_create()的蹤影了,取而代之的是device_register()與device_add(),將device_create()函式展開不難發現:其實de

linux裝置驅動第三篇寫一個簡單的字元裝置驅動

在linux裝置驅動第一篇:裝置驅動程式簡介中簡單介紹了字元驅動,本篇簡單介紹如何寫一個簡單的字元裝置驅動。本篇借鑑LDD中的原始碼,實現一個與硬體裝置無關的字元裝置驅動,僅僅操作從核心中分配的一些記憶體。 下面就開始學習如何寫一個簡單的字元裝置驅動。首先我們來分解一下字元

linux裝置驅動第三篇如何實現簡單的字元裝置驅動

在linux裝置驅動第一篇:裝置驅動程式簡介中簡單介紹了字元驅動,本篇簡單介紹如何寫一個簡單的字元裝置驅動。本篇借鑑LDD中的原始碼,實現一個與硬體裝置無關的字元裝置驅動,僅僅操作從核心中分配的一些記憶體。 下面就開始學習如何寫一個簡單的字元裝置驅動。首先我們來分解一下

Linux裝置驅動mmap裝置操作(memdev.c字元裝置驅動分析)

from:  1.mmap系統呼叫 void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset); 功能:負責把檔案內容對映到程序的虛擬地址空間,通過對這段記憶體的

Linux字元裝置驅動模型--字元裝置的註冊

當我們編寫字元裝置驅動程式的時候,在進行字元裝置物件cdev的分配、初始化,裝置號的註冊這些初始化階段之後,就可以將它加入到系統中,這樣才能使用這個字元裝置。將一個字元裝置加入到系統中呼叫的函式時cdev_add,核心原始碼如下: int cdev_add(struct cdev *

Linux驅動字元設備註冊新介面(未完)

驅動之字元設備註冊新介面 目前尚不是最終版本,還望有心人自己學習的時候,把自己整合的知識點相關的答案也好問題也好,或者實踐過程中的一些操作截圖,再或者其他的一些想要分享材料發給筆者郵箱:[email protected],我們一起完善這篇部落格!筆者寫這篇部

Linux 驅動裝置結構體 (二)

上回最後面介紹了相關資料結構,下面再詳細介紹 塊裝置物件結構 block_device 核心用結構block_device例項代表一個塊裝置物件,如:整個硬碟或特定分割槽。如果該結構代表一個分割槽,則其成員bd_part指向裝置的分割槽結構。如果該結構代表裝置,則其成員

linux powerpc i2c驅動  i2c裝置

pr_debug("bus: '%s': %s: bound device %s to driver %s\n", drv->bus->name, __func__, dev_name(dev), drv->name);  

Linux應用程式訪問字元裝置驅動詳細過程解析

下面先通過一個編寫好的核心驅動模組來體驗以下字元裝置驅動 可以暫時先忽略下面的程式碼實現! memdev.c #include <linux/module.h> #include <linux/fs.h> #include <linux/in

Linux裝置模型tty&&uart驅動架構分析

五: uart_add_one_port()操作 在前面提到.在對uart裝置檔案過程中.會將操作轉換到對應的port上,這個port跟uart_driver是怎麼關聯起來的呢?這就是uart_add_ont_port()的主要工作了. 顧名思義,這個函式是在uart_driver增加一個port.程式碼如

程式碼編寫一個簡單的字元裝置驅動——建立多個同類型裝置

編寫同類型多個裝置字元驅動應注意一下幾個問題: 1、申請裝置號alloc_chrdev_region時須指定次裝置號範圍; 2、動態分配裝置空間時同時分配NUM個裝置的空間; 3、根據次裝置號和統一的主裝置號生成針對單個裝置的devno,然後完成cdev_add註冊; 4、

Linux裝置驅動button按鍵驅動學習與小結

button按鍵驅動,相對於前面的LED驅動來說。增加了中斷處理以及阻塞與非阻塞方式等新知識點。 先上學習的驅動程式碼。 核心:linux3.0 板子:fl2440 /***************************************************