c-设备驱动程序:我如何获得对实际引脚/硬件的编程访问



如果您认为这个问题构造不正确,请查看其原始版本。我被要求将这个问题简化为最简单的形式

如果我正在编写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);

同样,如果这一点不清楚,那是因为我试图遵守社区规则,让它保持简单、愚蠢。在这种情况下,请阅读我对这个问题的第一个版本。

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"gpio"的System.map符号文件)。

最新更新