1

この質問が適切に構成されていないと思われる場合は、元のバージョンを参照してください。私は、この質問を最小限の形に縮小するよう求められました。

Linux デバイス ドライバーを作成している場合、実際の G​​PIO ピンにプログラムでアクセスするにはどうすればよいですか? 例えば:

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

繰り返しますが、これが不明確である場合、それは私がコミュニティのルールを単純でばかげたものにする義務を負わせようとしているからです. その場合は、この質問の最初のバージョンを読んでください。

4

1 に答える 1

2

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

于 2012-12-08T21:58:05.933 に答える