目前,Linux軟體工程師大致可分為兩個層次:
(1)Linux應用軟體工程師(Application Software Engineer):
主要利用C庫函數和Linux API進行應用軟體的編寫;
從事這方面的開發工作,主要需要學習:符合linux posix標準的API函數及系統調用,linux的多任務編程技巧:多進程、多線程、處理序間通訊、多任務之間的同步互斥等,嵌入式資料庫的學習,UI編程:QT、miniGUI等。
(2)Linux韌體工程師(Firmware Engineer):
主要進行Bootloader、Linux的移植及Linux裝置驅動程式的設計工作。
一般而言,韌體工程師的要求要高於應用軟體工程師的層次,而其中的Linux裝置驅動編程又是Linux程式設計中比較複雜的部分,究其原因,主要包括如下幾個方面:
1)裝置驅動屬於Linux核心的部分,編寫Linux裝置驅動需要有一定的Linux作業系統核心基礎;需要瞭解部分linux核心的工作機制與系統組成
2)編寫Linux裝置驅動需要對硬體的原理有相當的瞭解,大多數情況下我們是針對一個特定的嵌入式硬體平台編寫驅動的,例如:針對特定的主機平台:可能是三星的2410、2440,也可能是atmel的,或者飛思卡爾的等等
3)Linux裝置驅動中廣泛涉及到多進程並發的同步、互斥等控制,容易出現bug;因為linux本身是一個多任務的工作環境,不可避免的會出現在同一時刻對同一裝置發生並行作業
4)由於屬於核心的一部分,Linux裝置驅動的調試也相當複雜。linux裝置驅動沒有一個很好的IDE環境進行單步、變數查看等調試協助工具輔助;linux驅動跟linux核心工作在同一層次,一旦發生問題,很容易造成核心的整體崩潰。
本系列文章我們將一步步、深入淺出的介紹linux裝置驅動編程中設計的一些問題及學習方法,希望對大家學習linux裝置驅動有所協助。
在任何一個電腦系統中,大至伺服器、PC機、小至手機、mp3/mp4播放器,無論是複雜的大型伺服器系統還是一個簡單的流水燈單片機系統,都離不開驅動程式的身影,沒有硬體的軟體是空中樓閣,沒有軟體的硬體只是一堆廢鐵,硬體是底層的基礎,是所有軟體得以啟動並執行平台,代碼最終會落實到硬體上的邏輯組合。
但是硬體與軟體之間存在一個駁論:為了快速、優質的完成軟體功能設計,應用程式工程師不想也不願關心硬體,而硬體工程師也很難有功夫去處理軟體開發中的一些應用。例如軟體工程師在調用printf的時候,不許也不用關心資訊到底是通過什麼樣的處理,走過哪些通路顯示在該顯示的地方,硬體工程師在寫完了一個4*4鍵盤驅動後,無需也不必管應用程式在獲得索引值後做哪些處理及操作。
也就是說軟體工程師需要看到一個沒有硬體的純軟體世界,硬體必須透明的提供給他,誰來實現這一任務?答案是驅動程式,驅動程式從字面解釋就是:“驅使硬體裝置行動”。驅動程式直接與硬體打交道,按照硬體裝置的具體形式,驅動裝置的寄存器,完成裝置的輪詢、中斷處理、DMA通訊,最終讓通訊裝置可以收發資料,讓顯示裝置能夠顯示文字和畫面,讓音訊裝置可以完成聲音的儲存和播放。
可見,裝置驅動程式充當了硬體和軟體之間的樞紐,因此驅動程式的表現形式可能就是一些標準的、事先協定好的API函數,驅動工程師只需要去完成相應函數的填充,應用工程師只需要調用相應的介面完成相應的功能。無論有沒有作業系統,驅動程式都有其存在價值,只是在裸機情況下,工作環境比較簡單、完成的工作較單一,驅動程式完成的功能也就比較簡單,同時介面只要在小範圍內符合統一的標準即可。但是在有作業系統的情況下,此問題就會被放大:硬體來自不同的公司、千變萬化,全世界每天都會有大量的新晶片被生產,大量的電路板被設計出來,如果沒有一個很好的統一標準去規範這一程式,作業系統就會被設計的非常冗餘,效率會非常低。
所以無論任何作業系統都會制定一套標準的架構去管理這些驅動程式:linux作為嵌入式作業系統的典範,其驅動架構具有很高的規範性與彙總性,不但把不同的硬體裝置分門別類、綜合管理,並且針對不同硬體的共性進行了統一抽象,將其硬體相關性降到最低,大大簡化了驅動程式的編寫,形成了具有其特色的驅動組織架構。
反映了應用程式、linux核心、驅動程式、硬體的關係。
linux核心分為5大部分:多任務管理、記憶體管理、檔案系統管理、裝置管理、網路管理;
每一部分都有承上下的作用,對上提供API介面,提供給應用開發工程師使用;
對下通過驅動程式屏蔽不同的硬體構成,完成硬體的具體操作。