本文主要對 應用程式、庫、內核、驅動程式的關係 及 LED驅動的實現原理 進行簡要介紹 ...
應用程式、庫、內核、驅動程式的關係
從上到下,一個軟體系統可以分為:應用程式、庫、操作系統(內核)、驅動程式。開發人員可以專註於自己熟悉的部分,對於相鄰層,只需要瞭解它的介面,無需關註它的實現細節。以點亮LED為例,這4層軟體的協作關係如下:
1、應用程式使用庫提供的open函數打開代表LED的設備文件。
2、庫數據open函數傳入的參數執行“swi”指令,這條指令會引起CPU異常,進入內核。
3、內核的異常處理函數根據這些參數找到相應的驅動程式,返回一個文件句柄給庫,進而返回給應用程式。
4、應用程式得到文件句柄後,使用庫提供的write或ioclt函數發出的控制命令。
5、庫根據write或ioclt函數傳入的參數執行“swi”指令,這條指令會引起異常,進入內核。
6、內核的異常處理函數根據這些參數調用驅動程式的相關函數,點亮LED。
7、庫(比如glibc)給應用程式提供的open、read、write、ioctl、mmap等介面函數被稱為系統調用,它們都是設置好相關寄存器後,執行某條指令引發異常進入內核。對於ARM架構的 CPU,這條指令為swi。除系統調用介面外,庫還提供其他函數,比如字元串處理函數(strepy、strcmp等)、輸入/輸出函數(scanf、printf等)、資料庫,還有應用程式的啟動代碼等。 在異常處理函數中,內核會根據傳入的參數執行各種操作,比如根據設備文件名找到對應的驅動程式,調用驅動程式的相關函數等。
LED驅動的實現原理
儘管Linux驅動直接與硬體打交道,但並不是Linux驅動直接向硬體中的記憶體寫數據,而是與本機的I/O記憶體(I/O Memory,位於內核空間)進行交互。所謂I/O記憶體是通過各種藉口(PCI、USB、藍牙、乙太網口等)連接到主機(PC、手機)的硬體(網卡、音效卡、攝像頭等)
在主機記憶體中的映射。 例如,在Ubuntu Linux上運行的驅動只需要訪問運行Ubuntu Linux的主機中的I/O記憶體即可,然後Linux內核會利用I/O記憶體中的數據硬體交互。
Linux內核提供了多個與I/O記憶體交互的函數,如ioread16,ioread32,iowrite16,iowrite32等。Linux內核的記憶體管理模塊負責同步I/O記憶體與硬體中的數據。原理如圖:
每一個連接Linux的硬體在I/O記憶體中都會有映射首地址。在使用ioread32、iowrite32等函數讀寫I/O記憶體是需要指定這些首地址。開發板上的LED也有其映射首地址。