2012-12-08 91 views
1

如果您認爲此問題沒有正確構建,請參閱其原始版本。我被要求將這個問題簡化爲最小形式。設備驅動程序:如何獲得編程訪問實際引腳/硬件?

如果我正在編寫Linux設備驅動程序,如何獲得編程訪問實際的GPIO引腳?例如:

// Turn a green LED on by sending the GPIO pins 0x11223344 
int cmd = encode(Commands.TURN_GREEN_ON); 
send_to_gpio_pins(cmd); 

再一次,如果這不清楚,這是因爲我試圖強制社區規則保持簡單,愚蠢。在這種情況下,請閱讀我的第一個問題。

+0

我控制了我的衝動,編輯出除了主要問題以外的所有內容。相反,你應該考慮自己這樣做。另外,考慮將標題改爲問題。 – Nocturno

+0

Nocturno,希望編輯能讀得更好,儘管我擔心現在我會回答很多「需要更多信息」類型的後續問題/評論。這是權衡... – IAmYourFaja

+0

IMO使用GPIO在兩個計算機系統之間進行通信是一個壞主意。您正試圖在不評估協議要求的情況下立即執行某些操作這應該是主從連接?你需要定義這樣的基本假設。您構建的任何接口都將是處理器到處理器;您無法遠程控制其他設備的GPIO。爲了控制用戶對本地GPIO的訪問,有些人使用* sysfs *而不是使用設備驅動程序。 – sawdust

回答

1

Linux設備驅動程序應該可以訪問由arch的gpio模塊提供的一組功能。由於我熟悉Atmel ARM代碼,並且不確定RPI使用的Broadcom SoC,因此下面列出了一些真正的代碼。

ARM SoC上的I/O設備通常是內存映射(即沒有單獨的I/O地址空間)。這些物理地址可以映射到內核虛擬地址空間。 (外設寄存器的地址通常由單獨的設備驅動程序映射以供其專用)
一旦映射到虛擬內存,包含或控制GPIO引腳狀態的寄存器可以簡單地通過普通的讀或寫操作內存操作(同時符合C語言要求)。請查閱Broadcom SoC hardware document瞭解這些器件寄存器中每個位的確切分配/功能。

在使用GPIO作爲輸入引腳或輸出引腳之前,必須配置GPIO引腳。通常這個引腳會有多種用途(它是「多路複用的」),所以在早期的板啓動期間必須選擇這些特定功能之一。這些分配是通過寫入設備配置寄存器(映射到內存位置)來執行的。

的愛特梅爾功能的GPIO引腳的值(從arch/arm/mach-at91/gpio.c)寫:

/* 
* assuming the pin is muxed as a gpio output, set its value. 
*/ 
int at91_set_gpio_value(unsigned pin, int value) 
{ 
     void __iomem *pio = pin_to_controller(pin); 
     unsigned  mask = pin_to_mask(pin); 

     if (!pio) 
       return -EINVAL; 
     __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR)); 
     return 0; 
} 
EXPORT_SYMBOL(at91_set_gpio_value); 

的愛特梅爾函數讀取一個GPIO引腳的值:

/* 
* read the pin's value (works even if it's not muxed as a gpio). 
*/ 
int at91_get_gpio_value(unsigned pin) 
{ 
     void __iomem *pio = pin_to_controller(pin); 
     unsigned  mask = pin_to_mask(pin); 
     u32    pdsr; 

     if (!pio) 
       return -EINVAL; 
     pdsr = __raw_readl(pio + PIO_PDSR); 
     return (pdsr & mask) != 0; 
} 
EXPORT_SYMBOL(at91_get_gpio_value); 

希望你能找到您使用的內核中的類似代碼(例如grepSystem.map「gpio」的符號文件)。