嵌入式驅動開發的要點

2021-06-05 11:29:59 字數 3238 閱讀 8854

在linux作業系統下有3類主要的裝置檔案型別:塊裝置、字元裝置和網路裝置。這種分類方法可以將控制輸入/輸出裝置的驅動程式與其他作業系統軟體分離開來。

字元裝置與塊裝置的主要區別是:在對字元裝置發出讀/寫請求時,實際的硬體i/o一般緊接著發生。塊裝置則不然,它利用一塊系統記憶體作為緩衝區,若使用者程序對裝置的請求能滿足使用者的要求,就返回請求的資料;否則,就呼叫請求函式來進行實際的i/o操作。塊裝置主要是針對磁碟等慢速裝置設計的,以免耗費過多的cpu時間用來等待。網路裝置可以通過bsd套介面訪問資料。

每個裝置檔案都有其檔案屬性(c/b),表示是字元裝置還是塊裝置。另外每個檔案都有2個裝置號,第乙個是主裝置號,標識驅動程式;第二個是從裝置號,標識使用同乙個裝置驅動程式的、不同的硬體裝置。裝置檔案的主裝置號必須與裝置驅動程式在登記時申請的主裝置號一致,否則使用者程序將無法訪問驅動程式。

系統呼叫時作業系統核心與應用程式之間的介面,裝置驅動程式是作業系統核心與機器硬體之間的介面。裝置驅動程式是核心的一部分,它完成以下功能:

*對裝置初始化和釋放

*把資料從核心傳送到硬體和從硬體讀取資料

*讀取應用程式傳送給裝置檔案的資料和回送應用程式請求的資料

*檢測和處理裝置出現的錯誤

mtd(memory technology device)裝置是快閃儲存器晶元、小型快閃儲存器卡、記憶棒之類的裝置,它們在嵌入式裝置中的使用正在不斷增加。mtd驅動程式是在linux下專門為嵌入式環境開發的新的一類驅動程式。相對於常規塊裝置驅動程式,使用mtd驅動程式的優點在於他們能更好的支援、管理給予快閃儲存器裝置,有基於扇區的擦除和讀/寫操作的更好的介面。

驅動程式結構

linux的裝置驅動程式可以分為3個主要組成部分:

1. 自動配置和初始化子程式,負責監測所要驅動的硬體裝置是否存在和能否正常工作。如果該裝置正常,則對這個裝置及其相關的裝置驅動程式需要的軟體狀態進行初始化。這部分驅動程式僅在初始化時被呼叫一次。

2. 服務於i/o請求的子程式,又稱為驅動程式的上半部分。呼叫這部分程式是由於系統呼叫的結果。這部分程式在執行時,系統仍認為是與進行呼叫的程序屬於同乙個程序,只是由使用者態變成了核心態,具有進行此系統呼叫的使用者程式的執行環境,因而可以在其中呼叫sleep()等與進行執行環境有關的函式。

3. 中斷服務子程式,又稱為驅動程式的下半部分。在linux系統中,並不是直接從中斷向量表中呼叫裝置驅動程式的中斷服務子程式,而是由linux系統來接收硬體中斷,再由系統呼叫中斷服務子程式。中斷可以在任何乙個程序執行時產生,因而在中斷服務程式被呼叫時,不能依賴於任何程序的狀態,也就不能呼叫任何與程序執行環境有關的函式。因為裝置驅動程式一般支援同一型別的若干裝置,所以一般在系統呼叫中斷服務子程式時,都帶有乙個或多個引數,以唯一標識請求服務的裝置。

在系統內部,i/o裝置的存/取通過一組固定的入口點來進行,這組入口點是由每個裝置的驅動程式提供的。具體到linux系統,裝置驅動程式所提供的這組入口點由乙個檔案操作結構來向系統進行說明。file_operation結構定義於linux/fs.h檔案中。 

struct file_operation;

file_operation結構中的成員幾乎全部是函式指標,所以實質上就是函式跳轉表。每個程序對裝置的操作都會根據major、minor裝置號,轉換成對file_operation結構的訪問。

常用的操作包括以下幾種:

*lseek, 移動檔案指標的位置,只能用於可以隨機訪問的裝置。

*read, 進行讀操作,引數buf為存放讀取結果的緩衝區,count為所要讀取的資料長度。返回值為負表示讀取操作發生錯誤;否則,返回實際讀取的位元組數。對於字元型,要求讀取的位元組數和返回的實際讀取位元組數都必須是inode-i_blksize的倍數。

*write, 進行寫操作,與read類似

*select, 進行選擇操作。如果驅動程式沒有提供select入口,select操作會認為裝置已經準備好進行任何i/o操作。

*ioctl, 進行讀、寫以外的其他操作,引數cmd為自定義的命令

*mmap, 用於把裝置的內容對映到位址空間,一般只有塊裝置驅動程式使用

*open, 開啟裝置準備進行i/o操作。返回0表示開啟成功,返回負數表示失敗。如果驅動程式沒有提供open入口,則只要/dev/driver檔案存在就認為開啟成功。

*release, 即close操作。

在使用者自己的驅動程式中,首先要根據驅動程式的功能,完成file_operation結構中函式實現。不需要的函式介面可以直接在file_operation結構中初始化為null。file_operation變數會在驅動程式初始化時註冊到系統內部。當作業系統對裝置操作時,會呼叫驅動程式註冊的file_operation結構中的函式指標。

linux對中斷的處理

在linux系統裡,對中斷的處理是屬於系統核心部分,因而如果設別與系統之間以中斷方式進行資料交換,就必須把該裝置的驅動程式作為系統核心的一部分。裝置驅動程式通過呼叫request_irq函式來申請中斷,通過free_irq來釋放中斷。它們被定義為: 

#include 

int request_irq(unsigned int irq, 

void (*handler)(int irq, void dev_id, struct pt_regs *regs),

unsigned long flags,

const char *device,

void *dev_id);

void free_irq(unsigned int irq, void *dev_id);

引數irq表示所要申請的硬體中斷號;handler為向系統登記的中斷處理子程式,中斷產生時由系統來呼叫,呼叫時所帶引數irq為中斷號;dev_id為申請時告訴系統的裝置標識;regs為中斷發生時的暫存器內容;device為裝置名,將會出現在/proc/interrupts檔案裡;flag是申請時的選項,它決定中斷處理程式的一些特性,其中最重要的是中斷處理程式是快速處理程式還是慢速處理程式。快速處理程式執行時,所有中斷都被遮蔽,而慢速處理程式執行時,除了正在處理的中斷外,其他中斷都沒有被遮蔽。在linux系統中,中斷可以被不同的中斷處理程式共享。

作為系統核心的一部分,裝置驅動程式在申請和釋放記憶體時不是呼叫malloc和free,而代之以呼叫kmalloc和kfree,它們被定義為: 

#include 

void *kmalloc(unsigned int len, int priority);

void kfree(void *obj);

引數len為希望申請的位元組數;obj為要釋放的記憶體指標;priority為分配記憶體操作的優先順序,即在沒有足夠空閒記憶體時如何操作,一般用gfp_kernel

嵌入式linux IIC驅動

linux驅動和裝置隔離,驅動分層,iic驅動框架分為兩部分 1.1 iic匯流排驅動 platform是虛擬匯流排,針對沒有匯流排的裝置實現,匯流排 裝置 驅動框架,iic不用虛擬,可直接用匯流排bus。iic匯流排驅動有兩個重要資料結構 i2c adapter,i2c algorithm。i2c...

嵌入式Linux SPI驅動

1.1 spi主機驅動 linux使用spi master結構體表示spi主機驅動,定義在 drivers linux spi spi.h transfer 資料傳輸函式 transfer one message spi傳送護具函式,傳送乙個spi message資料 1.2 spi裝置驅動 lin...

開發環境 嵌入式驅動開發環境搭建

2 開發環境 2 1 編譯工具 安裝sudo tar zvxf arm linux gcc 4.3.2.tgz c 配置系統環境變數 sudo vi etc profile 或 bashrc 在檔案最後新增交叉編譯路徑 path path usr local arm 4.3.2 bin export...