最大 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: 私の英語に誤りがありましたら申し訳ありません。改善する必要があることは承知しています。