Konfiguracja jądra Linux z GPIO

Na ogół w systemach wbudowanych potrzebujemy dostępu do GPIO przynajmniej w jednym celu — do migania diodami, sygnalizującymi stan pracy urządzenia. W gruncie rzeczy błyskanie LED-em jest zresztą pierwszym i podstawowym zadaniem większości urządzeń…

Niestety, opisując proces kompilacji Linuksa dla MMneta1002 zapomniałem o zapewnieniu dostępu do GPIO. Sterowanie pinami na potrzeby migania diodą, załączania przekaźnika czy sprawdzania stanu przełącznika jest jednak bardzo proste — wymaga tylko włączenia odpowiednich opcji w konfiguracji jądra i wykonywania operacji na plikach reprezentujących poszczególne piny. Dodatkowo mamy możliwość automatycznej obsługi LED-ów przez jądro w celu sygnalizacji np. dostępu do nośników danych.

Zaczynamy od tego, że w konfiguracji jądra zaznaczamy opcję /sys/class/gpio/… (sysfs interface) w zakładce GPIO Support (CONFIG_GPIO_SYSFS=y). Warto też włączyć LED Heartbeat Trigger i LED Timer Trigger w LED Support (CONFIG_LEDS_TRIGGER_HEARTBEAT=y i LEDS_TRIGGER_TIMER=y).

Następnie poprawiamy łatkę dla pliku arch/arm/mach-at91/board-sam9260ek.c. W pliku tym definiujemy, które piny będą dostępne dla jądra jako urządzenia LED:

/*
 * LEDs
 */
static struct gpio_led ek_leds[] = {
	{	/* "DISK" LED */
		.name			= "disk",
		.gpio			= AT91_PIN_PC1,
		.active_low		= 1,
		.default_trigger	= "nand-disk",
	},
	{	/* "USR" LED */
		.name			= "usr",
		.gpio			= AT91_PIN_PC15,
		.active_low		= 1,
		.default_trigger	= "heartbeat",
	}
};

Gotową łatkę można pobrać tutaj: linux-2.6.32.9-mmnet1002.patch.

Po rekompilacji jądra dostajemy dostęp do poszczególnych pinów w przestrzeni użytkownika. Przykład: jeżeli chcemy zaświecić diodę podłączoną do pinu PC2 (gpio98), najpierw eksportujemy ten pin:

# echo 98 > /sys/class/gpio/export

a następnie konfigurujemy go jako wyjście w stanie niskim:

# echo "low" > /sys/class/gpio/gpio98/direction

Oczywiście, jeżeli do tego pinu podłączymy przycisk, możemy sprawdzić jego stan za pomocą dwóch prostych poleceń:

# echo "in" > /sys/class/gpio/gpio98/direction
# cat /sys/class/gpio/gpio98/value

Szczegóły implementacji GPIO w Linuksie można znaleźć w dokumentacji jądra.

A teraz przyjrzyjmy się diodom podłączonym do PC1 i PC15. Pierwsza z nich (nie jest ona wlutowana w płytkę — dodałem ją samodzielnie na potrzeby własnego projektu) ma ustawiony wyzwalacz nand-disk, co można łatwo sprawdzić:

# cat /sys/class/leds/disk/trigger
none [nand-disk] timer heartbeat default-on

Oznacza to, że dioda będzie migać, gdy system będzie korzystał z pamięci NANDFlash. Dioda USR (umieszczona obok diody PWR) ma zaś wyzwalacz heartbeat, co oznacza, że imituje bicie serca, a jej „tętno” zależy od obciążenia systemu (przyśpiesza wyraźnie dopiero, gdy system jest bardzo obciążony).

Oczywiście, plik trigger możemy nadpisywać swoją wartością. Poniższe polecenia sprawią, że dioda będzie cieszyć nasze oczy krótkim błyśnięciem raz na sekundę:

# echo "timer" > /sys/class/leds/usr/trigger
# echo 100 > /sys/class/leds/usr/delay_on
# echo 900 > /sys/class/leds/usr/delay_off

Szczegóły implementacji urządzeń LED również można znaleźć w dokumentacji jądra.

Dodawanie komentarzy

XHTML: Możesz używać tagów: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">