Lekcja 11- Eksportowanie symboli

Wstęp

W tej krótkiej lekcji dowiemy się jak używać symboli zdefiniowanych w jednym module w innym module. Co rozumiem przez symbol? Przez symbol rozumiem zmienną lub funkcję. Umożliwienie użycia symbolu innym modułom nazywamy najczęściej po prostu eksportowaniem symboli.

Implementacja

Jak zwykle użyjemy naszej ulubionej diody LED do testu. W tym przypadku napiszemy dwa moduły- jeden, który będzie eksportować numer pinu do którego jest podłączona dioda LED. Drugi moduł będzie odczytywał ten numer i będzie dokonywał wszystkich niezbędnych ustawień pinu GPIO.

Zacznijmy od modułu, który eksportuje symbol, jego kod wygląda następująco:

#include <linux/init.h>
#include <linux/module.h>

int led_pin = 48;

EXPORT_SYMBOL(led_pin);

static int __init led_init(void)
{
	return 0;
}
static void __exit led_exit(void)
{
}

module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");

Jak widać kod jest niezwykle prosty, jest niemalże tak samo prosty jak nasz pierwszy moduł. Jedyną nowością w tym kodzie jest makro EXPORT_SYMBOL, które to umożliwia użycie danego symbolu innym modułom. Przyjmuje ono jeden parametr- symbol, który ma zostać wyeksportowany.

Teraz zajmijmy się drugim modułem, który również jest prosty:

#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

extern int led_pin;

static int __init led_init(void)
{
	if (!gpio_is_valid(led_pin)){
      pr_err("Invalid GPIO pin!!1\n");
      return -ENODEV;
   }
	gpio_request(led_pin, "gpioLED");
	gpio_direction_output(led_pin, 1);
	gpio_set_value(led_pin, 1);
	gpio_export(led_pin, false);	
	return 0;
}
static void __exit led_exit(void)
{
	gpio_set_value(led_pin, 0);
	gpio_unexport(led_pin);
	gpio_free(led_pin);
}

module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");

Jeśli przerobiłeś poprzednie lekcje to również powinieneś rozumieć ten kod. Jedyną nowością tutaj jest linijka:

extern int led_pin;

Słowo kluczowe extern oznacza, że dany symbol został zdefiniowany poza modułem. Po słowie kluczowym extern umieszczamy deklaracje zmiennej lub funkcji.

Tym razem budujemy dwa pliki za pomocą Makefile’a:

obj-m += 11_symbol_exporter.o 11_symbol_importer.o
all:
	make -C /ścieżka/do/zbudowanego/kernela M=$(PWD) modules
clean:
	make -C /ścieżka/do/zbudowanego/kernela M=$(PWD) clean

Przebuduj moduł dla swojej płytki:

# BBB
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
# RPi4
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- KERNEL=kernel8

Testowanie sterownika

Prześlij zbudowane moduły na swoją płytkę np. za pomocą scp.

Testowanie tego modułu jest bardzo proste:

sudo insmod 11_symbol_exporter.ko
sudo insmod 11_symbol_importer.ko

Po wykonaniu tych komend dioda powinna się zapalić.

Odwrotna sekwencja ładowania modułów nie powiedzie się ponieważ nie może zostać załadowany moduł, który importuje symbol, który nie został wyeksportowany.

Ten wpis został opublikowany w kategorii Kurs pisania sterowników. Dodaj zakładkę do bezpośredniego odnośnika.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *