進入驅動的hpi相關部分後,就要好好研究pci2040的datasheet了。說實話,乙個驅動程式的大部分內容,就是把datasheet裡的內容翻譯成**,所以每乙個驅動工程師都應該深入的閱讀硬體文件。
首先看pci2040的配置空間,如下所示
有兩個最重要的基位址,乙個是hpi csr記憶體基位址,可以通過它把pci2040的hpi csr暫存器群對映到主機的記憶體;還有乙個是控制空間基位址,可以把pci2040的32kb的控制空間對映到主機記憶體。
hpi csr暫存器如上所示,根據ioremap返回的基址加上相應的偏移,就可以順序訪問這些hpi csr暫存器。可以看出這些暫存器都是用來控制dsp的工作狀態的,比如中斷的開關,重啟dsp等等。那我們怎麼把資料傳遞給dsp並獲得dsp的運算結果?pci2040的datasheet也提供了hpi dsp的資料,從中可以知道,與dsp的通訊需要三個暫存器:位址暫存器hpia,控制暫存器hpic,資料暫存器hpid。這三個暫存器都可以通過對映pci2040的控制空間來訪問。對映成功後,每次與dsp的通訊步驟如下:
(1)通過hpic設定dsp訪問模式
(2)通過hpia設定訪問的dsp記憶體位址
(3)通過hpid寫入或者讀取dsp的記憶體資料。
如果可以順利訪問dsp的記憶體了,那pci2040驅動到這裡就基本算完成了,可是使用者態的應用程式怎麼呼叫這個驅動呢?一般的裝置驅動,都是需要先open,然後再ioctl來呼叫驅動的,不過這次我們的開發環境是rtai+linux,可以利用rtai的共享記憶體機制,來實現使用者態程式與核心態驅動的通訊。
在probe函式的最後,我們呼叫hpi_open()函式,該函式主要功能如下所示:
static int hpi_open (struct hpi_private_data *tp)
使用者態應用程式通過g_shm=(lmcc_shm *)rtai_malloc(nam2num(lmcc_shm_name), sizeof(lmcc_shm))就可以得到這片共享記憶體的基位址,從而讀寫共享記憶體。實時任務每0.5ms查詢一次共享記憶體,並對共享記憶體的改變做出反應。這樣就實現了使用者程式與驅動的通訊。
至此,使用者態的應用程式就可以讀寫dsp記憶體了,實現了驅動的基本功能,再根據使用者需求,對讀寫操作做一層封裝,方便使用者使用,驅動就真正完成了。通過這個程式,可以對linux下的驅動到底是什麼有個初步的認識,也可以對rtai下的實時linux有一些了解。
Linux下的PCI驅動程式設計
pci裝置上有三種位址空間 pci的i o空間 pci的儲存空間和pci的配置空間。cpu可以訪問pci裝置上的所有位址空間,其中i o空間和儲存空間提供給裝置驅動程式使用,而配置空間則由linux核心中的pci初始化 使用。核心在啟動時負責對所有pci裝置進行初始化,配置好所有的pci裝置,包括中...
linux下的 pci 驅動程式設計模型
一 概述 我這裡pci 裝置是powerpc2020 和fpga 通過pci 匯流排進行相連通訊。二 驅動模型 include include include include include include include define send buf size 8192 define recv ...
Linux的PCI驅動分析
1.關鍵資料結構 pci裝置上有三種位址空間 pci的i o空間 pci的儲存空間和pci的配置空間。cpu可以訪問pci裝置上的所有位址空間,其中i o空間和儲存空間提供給裝置驅動程式使用,而配置空間則由linux核心中的pci初始化 使用。核心在啟動時負責對所有pci裝置進行初始化,配置好所有的...