Linux デバイス ドライバーは、arch のgpioモジュールによって提供される一連の関数にアクセスできる必要があります。私は Atmel ARM コードに精通しており、RPI で使用される Broadcom SoC についてはよく知らないので、ここに実際のgpioコードをいくつか示します。
ARM SoC の I/O デバイスは通常、メモリ マップされます (つまり、個別の I/O アドレス空間はありません)。これらの物理アドレスは、カーネルの仮想アドレス空間にマップできます。(周辺機器のレジスタのアドレスは、多くの場合、個々のデバイス ドライバによって専用にマップされます。)
仮想メモリにマップされると、GPIO ピンの状態を格納または制御するレジスタは、通常の読み取りまたは書き込みメモリ操作によって簡単にアクセスできます。 (C 言語の要件に準拠しながら)。これらのデバイス レジスタの各ビットの正確な割り当てと機能については、Broadcom SoC ハードウェア ドキュメントを参照してください。
GPIO を入力ピンまたは出力ピンとして使用する前に、GPIO ピンを構成する必要があります。多くの場合、ピンには複数の用途があります (「多重化」されている) ため、これらの特定の機能の 1 つを早期のボード初期化中に選択する必要があります。これらの割り当ては、デバイス構成レジスタ (メモリ位置にマップされている) に書き込むことによって実行されます。
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);
使用しているカーネルで同様のコードを見つけることができれば幸いです (たとえば、"gpio"のシンボル ファイルをgrepします)。System.map