LinkedIn YouTube Facebook
Szukaj

Newsletter

Proszę czekać.

Dziękujemy za zgłoszenie!

Wstecz
SoM / SBC

Pierwsze kroki z Raspberry Pi: obsługa magistrali 1-Wire

Konfiguracja systemu Linux do obsługi magistrali 1-Wire

System wbudowane działające w oparciu o system operacyjny Linux umożliwiają organizację magistrali 1-Wire na kilka sposobów: wykorzystanie konwerterów interfejsów USB na 1-Wire (np. za pomocą scalonego interfejsu DS2490), I2C na 1-Wire (np. układ DS2482) lub podłączenia układów peryferyjnych bezpośrednio do portów GPIO procesora. Dwa pierwsze z wymienionych rozwiązań wymuszają zastosowanie dodatkowych układów zewnętrznych oraz zwiększają powierzchnię zajmowaną przez urządzenie, dlatego też stosowane są głównie w rozwiązaniach, w których użytkownik nie ma bezpośredniego dostępu do portów GPIO. Komputer Raspberry Pi posiada bardzo wygodny dostęp do portów GPIO, które zostały wyprowadzone na złącze szpilkowe 2×13, dlatego też w dalszej części artykułu skupimy się na rozwiązaniu realizującym obsługę magistrali poprzez port wejścia/wyjścia ogólnego przeznaczenia.

Jedną z wielkich zalet systemu Linux jest bardzo wygodny w użyciu dla użytkownika poziom abstrakcji warstwy sprzętowej – wszystko jest plikiem. Nie inaczej jest również w przypadku magistrali 1-Wire. Każdy czujnik podłączony do urządzenia master jest reprezentowany przez zbiór plików umożliwiających konfigurację pracy i odczyt danych z urządzenia. Aby jednak zapewnić w systemie poprawną obsługę magistrali 1-Wire należy załadować do systemu odpowiednie moduły jądra, lub jeśli moduły te nie są dostępne dokonać samodzielnej jego konfiguracji i kompilacji.

 

Załadowanie gotowych modułów jądra

Większość dostarczanych wraz z komputerem jednopłytkowym Raspberry Pi dystrybucji systemu posiada zainstalowane, gotowe moduły do obsługi magistrali 1-Wire. W takim przypadku załadowanie modułów jądra w systemie ogranicza się do dwóch prostych instrukcji:

  sudo modprobe w1-gpio
  sudo modprobe w1-therm

Pierwszy z załadowanych modułów umożliwia obsługę magistrali 1-Wire poprzez porty wejścia/wyjścia ogólnego przeznaczenia, drugi natomiast umożliwia łatwy odczyt danych z cyfrowych czujników temperatury (jak np. DS18B20). Załadowane moduły są dostępne w systemie do czasu ponownego uruchomienia komputera, dlatego też warto wymusić w systemie ich automatyczne ładowanie przy starcie Raspberry Pi . W tym celu w pliku /etc/modules dodajemy wpisy:

  w1-gpio
  w1-therm

System jest już gotowy do podłączenia czujników. Jeśli proces załadowania modułów przebiegł poprawnie możesz Czytelniku przejść do lektury podrozdziału ” Obsługa magistrali 1-Wire w systemie Linux „. W przypadku gdy napotkałeś błędy, które najprawdopodobniej wynikają z braku wyżej wymienionych modułów w systemie, należy dokonać samodzielnej konfiguracji i kompilacji jądra systemu.

 

Kompilacja jądra systemu Linux włączoną obsługą magistrali 1-Wire

W przypadku gdy budujemy własną dystrybucję systemu lub korzystamy z ogólnodostępnych dystrybucji, które nie posiadają włączonej obsługi magistrali 1-Wire, należy dokonać samodzielnej konfiguracji i kompilacji jądra systemu Linux. Na szczęście cały proces, choć jest długotrwały, nie jest skomplikowany. Warto więc również dla celów dydaktycznych przeanalizować poniższe etapy konfiguracji systemu. Kompletny opis przygotowania narzędzi kross-kompilacji dla zestawu Raspberry Pi (nazwanych raspberrypi-tools ) oraz pobrania kodu źródłowego jądra systemu Linux został w sposób szczegółowy przedstawiony na stronie.
W niniejszym opisie skupimy się wyłącznie na konfiguracji wybranej wersji jądra pod kątem obsługi magistrali 1-Wire.

Po poprawnym skonfigurowaniu narzędzi kompilacji oraz pobraniu kodu źródłowego jądra systemu Linux przystępujemy do jego konfiguracji. W tym celu w katalogach z kodem źródłowym jądra wywołujemy polecenie:

  make menuconfig

które uruchomi pseudo-graficzny interfejs użytkownika. Z dostępnych opcji wybieramy kategorię Device drivers , włączamy opcję Dallas’s 1-wire support (poprzez wciśnięcie przycisku 'Y’) i w kategorii 1-wire Slaves wybieramy opcję Thermal family implementation .

Device Drivers --->
	<*> Dallas's 1-wire support --->
		1-wire Slaves --->
			<*> Thermal family implementation


Rys. 7. Konfiguracja jądra systemu Linux – układy slave

Rys. 7. Konfiguracja jądra systemu Linux – układy slave

W następnym kroku konfigurujemy tryb pracy układu master – ponieważ wybieramy opcję sterowania magistralą przez porty GPIO, z gałęzi 1-wire Bus Masters zaznaczamy opcję GPIO 1-wire busmaster .

Device Drivers --->
	<*> Dallas's 1-wire support --->
		1-wire Bus Masters --->
			<*> GPIO 1-wire busmaster


Rys. 8. Konfiguracja jądra systemu Linux – układ master

Rys. 8. Konfiguracja jądra systemu Linux – układ master

Po zapisaniu wprowadzonych zmian i zakończeniu pracy z narzędziem menuconfig ostatnim etapem jest deklaracja odpowiednich struktur i definicji w pliku ../arch/arm/mach-bcm2708/bcm2708.c . W edytowanym pliku dołączamy dyrektywę:

  #include <linux/w1-gpio.h>

oraz definiujemy numer wyprowadzenia GPIO, które będzie pełniło rolę linii danych (np. GPIO 4):

  #define W1_GPIO 4

Następnie deklarujemy poniższe struktury:

#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
static struct w1_gpio_platform_data w1_gpio_pdata = {
	.pin = W1_GPIO,
	.is_open_drain = 0,
};

static struct platform_device w1_device = {
	.name = "w1-gpio",
	.id = -1,
	.dev.platform_data = &w1_gpio_pdata,
};
#endif

Zadeklarowane struktury rejestrujemy w funkcji void __init bcm2708_init(void) poprzez dodanie wpisu:

#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
	platform_device_register(&w1_device);
#endif

Po zapisaniu zmian w pliku bcm2708.c możemy przystąpić do kompilacji jądra według wskazówek zawartych na stronie www.elinux.org .

 

Obsługa magistrali 1-Wire w systemie Linux

W poprzednim podrozdziale zakończyliśmy etap przygotowania jądra systemu do obsługi magistrali 1-Wire. Przed przystąpieniem do obsługi czujników po stronie przestrzeni użytkownika, dołączmy do zestawu Raspberry Pi dowolną liczbę sensorów DS18B20. Sposób podłączenia czujników został przedstawiony na rysunku 9 (numer portu GPIO 4 został zdefiniowany na etapie kompilacji jądra i jest to także domyślny numer portu przy wykorzystaniu gotowego modułu w1-gpio ).

 Rys. 9. Schemat podłączenia czujnika DS18B20 do zestawu Raspberry Pi

Rys. 9. Schemat podłączenia czujnika DS18B20 do zestawu Raspberry Pi

Jak wspomniano we wstępie artykułu, jądro systemu Linux dostarcza wysoki poziom abstrakcji dołączonego do Raspberry Pi sprzętu. Po skonfigurowaniu jądra każdy dołączony do magistrali czujnik reprezentowany jest poprzez katalog w lokalizacji /sys/bus/w1/devices o nazwie będącej połączeniem kodu rodziny układu i jego numeru identyfikacyjnego. Liczba katalogów w lokalizacji /sys/bus/w1/devices informuje nas więc o liczbie podłączonych sensorów:

cd /sys/bus/w1/devices
ls -l

W odpowiedzi:

lrwxrwxrwx 1 root root 0 May 15 15:09 28-000002f1af7c
lrwxrwxrwx 1 root root 0 May 15 15:09 28-000002f203e3
lrwxrwxrwx 1 root root 0 May 15 15:09 28-000002f218f8
lrwxrwxrwx 1 root root 0 May 15 15:09 w1_bus_master1

Każdy folder oznaczony numerem identyfikacyjnym sensora zawiera szereg plików, spośród których z punktu widzenia użytkownika najważniejszy jest w1_slave . Zawartość pliku jest tworzona przez jądro systemu w momencie odczytu i zawiera informację o wartości temperatury oraz sumie kontrolnej CRC. Odczyt temperatury z wybranego czujnika może zostać zrealizowany w następujący sposób:

  cat 28-000002f1af7c/w1_slave

Przykładowa odpowiedź:

a5 01 4b 46 7f ff 0b 10 f7 : crc=f7 YES
a5 01 4b 46 7f ff 0b 10 f7 t=26312

Ponieważ jądro systemu Linux nie operuje na liczbach zmiennoprzecinkowych, wskazywaną wartość temperatury należy podzielić przez 1000, czyli t = 26312/1000 = 26,312°C.

Jądro dostarcza również kilku prostych mechanizmów umożliwiających sterowanie pracą układu mastera. Konfiguracja pracy odbywa się poprzez zapis/odczyt plików umieszczonych w katalogu w1_bus_master1 . Typowe i najważniejsze możliwości konfiguracji przedstawiono poniżej:

  • Sprawdzenie liczby podłączonych czujnikówcat /sys/bus/w1/devices/w1_bus_master1/w1_master_slave_count
  • Odczyt numerów ID podłączonych czujnikówcat /sys/bus/w1/devices/w1_bus_master1/w1_master_slaves
  • Jednokrotne skanowanie magistrali po dołączeniu/odłączeniu nowych czujnikówecho 1 > /sys/bus/w1/devices/w1_bus_master1/w1_master_search
  • Wyrejestrowanie z systemu czujnika o numerze ID 28-000002f1af7cecho 28-000002f1af7c > /sys/bus/w1/devices/w1_bus_master1/w1_master_remove

 

Łukasz Skalski - absolwent Politechniki Gdańskiej, miłośnik FLOSS, autor książki "Linux. Podstawy i aplikacje dla systemów embedded" oraz szeregu artykułów dotyczących programowania systemów wbudowanych. Zawodowo związany z firmą Samsung. Wszystkie wolne chwile poświęca projektowaniu i programowaniu urządzeń wyposażonych w mikroprocesory 8-/16- i 32-bitowe. Szczególnym zainteresowaniem obejmuje tematykę systemu Linux w aplikacjach na urządzenia embedded.