3

最大 32 のプログラム可能な I/O ラインを管理する 4 つの PIO コントローラーを備えた AT91SAM9G25 ボードを使用しています。各ピンは、汎用 I/O ラインのみとして、または最大 2 つのペリフェラル I/O を多重化した I/O ラインとして構成可能です。したがって、たとえば、ドキュメント ( SAM9G25、14 ページ) によると、信号 PC0 は、汎用 I/O ラインまたは VIDEO_ATMEL_ISI (イメージ センサー インターフェイスの ISI) の ISI_D0 ラインとして多重化できます。

╔════════════╦════════════╦════════════╦════════════╦════════════╗
║  Primary   ║ Alternates ║   PeripA   ║   PeripB   ║  PeripC    ║
╠════════════╬════════════╬════════════╬════════════╬════════════╣
║ Signal/Dir ║ Signal/Dir ║ Signal/Dir ║ Signal/Dir ║ Signal/Dir ║
║ ---------  ║ ---------  ║ ---------  ║ ---------  ║ ---------  ║
║ PC0 / I/O  ║            ║            ║ ISI_D0 / I ║            ║
╚════════════╩════════════╩════════════╩════════════╩════════════╝

すべての GPIO ラインのリセット状態は、IN 方向とプルアップが有効になっています。sysfs 経由で GPIOLIB を使用すると、プルアップが原因でいくつかの GPIO の INPUT として「1」の値が読み取られます。これは、複数のボードが他のペリフェラルと多重化できる場合、リセット時の GPIO (プルアップ抵抗付きの入力) の通常の安全な状態ですか? GPIOLIB を使用してユーザー空間を介してプルアップを無効にする方法がわかりません。たとえば、カーネルの起動時に、イメージ センサー ペリフェラルがカーネルまたはモジュールとして有効になっているかどうかを確認し、有効な場合は PC0 をペリフェラル B に設定します。これは /arch/arm/mach のカーネル ソースにあります。 -at91/at91sam9x5_devices.c

#if defined(CONFIG_VIDEO_ATMEL_ISI) || defined(CONFIG_VIDEO_ATMEL_ISI_MODULE)
....
         at91_set_B_periph(AT91_PIN_PC0, 0);    /* ISI_D0 */
...
#endif

次に、カーネルで ISI サポートを有効にしない場合、PC0 信号を GPIO ラインとして使用できます。これは /sys/kernel/debug/gpio です。

    # cat /sys/kernel/debug/gpio

    GPIOs 32-63, A:

    GPIOs 64-95, B:
    [atmel_usba_udc] GPIOB16: [gpio] set
    [d1] GPIOB18: [gpio] clear

    GPIOs 96-127, C:

    GPIOs 128-159, D:
    [ohci_vbus] GPIOD19: [gpio] clear
    [ohci_vbus] GPIOD20: [gpio] clear
    [d2] GPIOD21: [gpio] set

これは /sys/kernel/debug/at91_gpio です

    # cat /sys/kernel/debug/at91_gpio

    Pin     PIOA            PIOB            PIOC            PIOD

    0:      A               A               GPIO:1          A
    1:      A               A               GPIO:1          A
    2:      GPIO:1          A               GPIO:1          A
    3:      GPIO:1          A               GPIO:1          A
    4:      GPIO:1          A               GPIO:1          GPIO:1
    5:      GPIO:1          A               GPIO:1          GPIO:1
    6:      GPIO:1          A               GPIO:1          A
    7:      B               A               GPIO:1          A
    8:      GPIO:1          GPIO:1          GPIO:1          A
    9:      A               A               GPIO:1          A
    10:     A               A               GPIO:1          A
    11:     A               GPIO:1          GPIO:1          A
    12:     A               GPIO:1          GPIO:1          A
    13:     A               GPIO:1          GPIO:1          A
    14:     A               GPIO:1          GPIO:1          GPIO:1
    15:     GPIO:1          GPIO:1          GPIO:1          A
    16:     GPIO:1          GPIO:1          GPIO:0          A
    17:     GPIO:1          GPIO:1          GPIO:1          A
    18:     GPIO:1          GPIO:1          GPIO:1          A
    19:     GPIO:1          A               GPIO:1          GPIO:0
    20:     GPIO:1          A               GPIO:0          GPIO:0
    21:     GPIO:1          A               GPIO:0          GPIO:1
    22:     GPIO:1          A               GPIO:1          A
    23:     GPIO:1          A               GPIO:1          A
    24:     GPIO:1          A               GPIO:1          A
    25:     GPIO:1          A               GPIO:1          A
    26:     GPIO:1          A               GPIO:1          A
    27:     GPIO:0          A               GPIO:1          A
    28:     GPIO:1          A               GPIO:0          A
    29:     GPIO:1          A               GPIO:0          A
    30:     GPIO:1          A               GPIO:1          A
    31:     GPIO:1          A               GPIO:1          A

上記の出力は、PIOA0 がペリフェラル A (TXD0 UART ライン) に多重化されており、たとえば PIOC20 がクリアされていることを示していますが、ドキュメントによると、リセット状態のすべての GPIO ラインはプルアップ付きの入力であり、カーネルまたは u-boot が無効になっている場所が見つかりません。この GPIO のプルアップ (おそらく GPIO は、誰も彼のレジスターに触れない場合、その状態を維持しますか?)

しかし、彼の主な質問は、GPIO ラインのプルアップ レジスタをクリアするにはどうすればよいかということです。カーネル ソースで、 /arch/arm/mach-at91/at91sam9x5_devices.c が linux-2.6.39/arch/arm/mach-at91/gpio.c に実装されているこの関数を使用していることがわかりました。

    /*
    * enable/disable the pull-down.
    * If pull-up already enabled while calling the function, we disable it.
    */
    int __init_or_module at91_set_pulldown(unsigned pin, int is_on)
    {
        void __iomem    *pio = pin_to_controller(pin);
        unsigned    mask = pin_to_mask(pin);

        if (!pio || !cpu_has_pio3())
            return -EINVAL;

        /* Disable pull-up anyway */
        __raw_writel(mask, pio + PIO_PUDR);
        __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR));
        return 0;
    }
    EXPORT_SYMBOL(at91_set_pulldown);

ヘッダー arch/arm/mach-at91/include/mach/gpio.h

    #ifndef __ASSEMBLY__
    /* setup setup routines, called from board init or driver probe() */
    .....
    extern int __init_or_module at91_set_pulldown(unsigned pin, int is_on);
    .....
    #endif  /* __ASSEMBLY__ */

ツールチェーンでこの関数を使用するにはどうすればよいですか? またはカーネル モジュールを作成する必要がありますか?

ありがとう

PD: 私の英語に誤りがありましたら申し訳ありません。改善する必要があることは承知しています。

4

2 に答える 2

2

たぶん、プルアップをそのままにしておくことができます。私は OMAP SoC で GPIO を使用しました。最低レベルには同様のピン マルチプレクサ オプションがありますが、プルアップについて心配する必要はありませんでした。通常、駆動しているものは何でも十分な電流をシンクできます (これは EE/回路の観点であり、慣れていなくても心配する必要はありません)。フローティング入力はランダムで厄介な場合があります。ハイに引き上げればOKです。

カーネル モジュールを作成する必要はないと思います。既存のユーザー モード インターフェイスを使用して実験することをお勧めします。sysfs を介したアクセスを提供するために、カーネルにはすでに低レベルのドライバーがフックされているはずです。sysfsomap gpioを参照してください。sysfs でプルアップ オプションを見たことはないと思います。何かが機能し、それを C コードから呼び出す必要がある場合は、API を探すか、単に system() を使用できます。

于 2013-03-16T03:27:01.297 に答える
0

デバイス ツリーを使用する新しいカーネルでは、デバイス ツリーの "blob" を再コンパイルすることで制御でき、カーネルを変更したり、カーネル ドライバーを作成したりする必要はありません。

http://lxr.free-electrons.com/source/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt

しかし、pinctrl に gpio のようなユーザー空間インターフェースがあれば、それは本当に素晴らしいことです。したがって、ピンを制御する完全なソリューションは、ユーザー空間制御でした。

于 2014-04-26T09:05:33.310 に答える