Linux 设备驱动程序应该可以访问 arch 的gpio模块提供的一组功能。由于我熟悉 Atmel ARM 代码并且不确定 RPI 使用的 Broadcom SoC,这里有一些真正的gpio代码。
ARM SoC 上的 I/O 设备通常是内存映射的(即没有单独的 I/O 地址空间)。这些物理地址可以映射到内核虚拟地址空间。(外设寄存器的地址通常由单独的设备驱动程序映射以供其专用。)
一旦映射到虚拟内存中,包含或控制 GPIO 引脚状态的寄存器可以通过普通的读取或写入内存操作简单地访问(同时符合 C 语言要求)。有关这些设备寄存器中每个位的确切分配/功能,请参阅Broadcom SoC 硬件文档。
在将 GPIO 用作输入引脚或输出引脚之前,必须配置 GPIO 引脚。引脚通常有多种用途(它是“多路复用的”),因此必须在早期电路板初始化期间选择其中一种特定功能。这些分配是通过写入设备配置寄存器(映射到内存位置)来执行的。
用于写入 GPIO 引脚值的 Atmel 函数(来自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 引脚值的 Atmel 函数:
/*
* 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);
希望您可以在您使用的内核中找到类似的代码(例如,grep符号System.map
文件以获得“gpio”)。