目前嵌入式系統的工程師有蠻多時候需要撰寫所謂特定device或是chip的driver,這邊先就一些基本的觀念做一點解釋。以linux來說,其程式分成兩個部分,一種運行於kernel,這種程式擁有控制硬體暫存器的權限,因此這邊的程式如果有bug,因為權限太大,很容易造成系統的記憶體空間發生錯誤,而導致整個系統crash。另外一種是運行在user space的程式,這種程式沒有權利直接去存取那些可以直接控制硬體的暫存器,因此其必須利用由linux定義出來,介於user space跟kernel space的介面,將控制的request由這個介面傳給kernel space的driver,用這個driver來將從硬體得到的值再傳回給user space的程式,完成一次對硬體的request。
linux為了統一這個介於中間層的interface,其定義了一些固定的功能,寫driver的時候只要去覆寫這些固定的function,則上層(user-space)可以使用類似的介面來控制許多不同種類的device。
linux將每個device都視為一個檔案,對其做資料上的操作,就很像對檔案做開檔讀檔以及寫入的功能。如果有一些hardware-depedent的一些功能,則可以利用(ioctl+自訂command)的方式來實現。
例如:假設有一個gpio的driver,並且也已經在kernel新增一個gpio(General Purpose I/O)的device,則我們如果要對其操作,我們一樣要先利用open的函數將device打開(f_op=open("/dev/gpio","參數")),然後此時如果成功開啟了device,其會回傳一個file operator,這可以視為要對這個device進行操作的代碼,則我們要對這gpio進行一些特定功能(例如控制值為邏輯0或是邏輯1,或是控制此GPIO為輸入或是輸出)的時候,我們只要使用ioctl的system call,將事先定義好的command以及這個file operator傳進去,我們就可以對device進行這些特定的操作。
基本上在linux撰寫driver,主要就是在kernal層中對一些硬體相關的暫存器做控制,來達到傳輸資料以及控制的目的,不過因為linux有規定好user space跟kernel space的介面規則,因此kernel層的driver還需要根據linux規定的driver框架,進行一些函數的覆寫,大致上這就是linux driver的初步觀念,比較細節的部分,留待以後說明。
沒有留言:
張貼留言