Zaprzyjaźnijmy się z RaspberryPi za pomocą TP-Link TL-WN727N

Hej Habra!

Kiedyś postanowiłem podłączyć mojego Raspberry Pi do Internetu bezprzewodowo.

W tym celu w najbliższym sklepie zakupiono gwizdek USB Wi-Fi znanej firmy TP-Link. Powiem od razu, że nie jest to jakiś rodzaj modułu nano USB, ale dość duże urządzenie, wielkością zbliżone do zwykłego dysku flash (lub, jeśli wolisz, wielkości palca wskazującego dorosłego mężczyzny). Przed zakupem trochę poczytałem o producentach obsługiwanych gwizdków dla RPI i na liście znalazł się TP-Link (choć jak się później okazało, nie wziąłem pod uwagę niuansów, bo diabeł, jak wiadomo, tkwi w szczegółach). Zaczyna się więc zimna opowieść o moich perypetiach. Waszą uwagę przyciąga opowieść detektywistyczna w 3 częściach. Zainteresowanych prosimy o zapoznanie się z treścią pod nagłówkiem.

Artykuł Podłączanie adaptera WiFi WN727N do Ubuntu/Mint Pomogło mi to częściowo, ale zacznijmy od początku.

Oświadczenie o problemie

Biorąc pod uwagę:

  1. Komputer jednopłytkowy Raspberry Pi 2 B v1.1 - 1 szt.
  2. gwizdek usb wi-fi WN727N - 1 sztuka
  3. para nie do końca krzywych rąk - 2 sztuki
  4. Najnowszy Raspbian (oparty na Debianie 10 Buster) jest instalowany jako system operacyjny
  5. wersja jądra 4.19.73-v7+

Znajdź: połącz się z Internetem (Wi-Fi jest rozprowadzane z domowego routera)

Po rozpakowaniu adaptera przeczytałem instrukcję znajdującą się w środku:

Zgodność z systemem: Windows 10/8/7/XP (nawet Sky, nawet XP) i MacOS 10.9-10.13

Cóż, jak zwykle, ani słowa o Linuksie. Był to 2k19, ale sterowniki nadal wymagały ręcznej kompilacji...

Mieliśmy ze sobą 2 kompilatory, 75 tysięcy bibliotek, pięć binarnych blobów, połowę tablicy z nagimi kobietami z logo i całe morze nagłówków wszystkich języków i znaczników. Nie żeby był to niezbędny zestaw do tej pracy. Ale gdy już zaczniesz sam tworzyć system, trudno będzie ci przestać. Jedyną rzeczą, która mnie zaniepokoiła, były sterowniki Wi-Fi. Nie ma nic bardziej bezradnego, nieodpowiedzialnego i skorumpowanego niż budowanie sterowników ze źródeł. Ale wiedziałem, że prędzej czy później wpadniemy w ten syf.

Ogólnie rzecz biorąc, jak wiadomo, majstrowanie przy Wi-Fi USB w systemie Linux jest bolesne i trochę bez smaku (jak rosyjskie sushi).

W pudełku znajduje się również płyta CD ze sterownikami. Patrzę na to, co się tam znajduje, bez większej nadziei – na pewno o to nie zadbali. Przeszukanie Internetu doprowadziło mnie na stronę producenta, ale jest tam dostępny sterownik dla systemu Linux tylko dla wersji urządzenia. v4i miałem go w rękach v5.21. A także dla bardzo starych wersji jądra 2.6-3.16. Zniechęcony porażką już na samym początku, pomyślałem, że warto wziąć TL-WN727N (jest nieco droższy i oferuje prędkość 300 Mb/s w porównaniu do 150 w moim przypadku, ale jak się okazało, dla Raspberry Pi nie ma to żadnego znaczenia, o czym napiszę później). Ale najważniejsze jest to, że sterowniki do niego już istnieją i są po prostu instalowane jako pakiet oprogramowanie układowe-ralink. Informację o wersji urządzenia można zazwyczaj znaleźć na naklejce znajdującej się na obudowie urządzenia, obok numeru seryjnego.

Dalsze googlowanie i odwiedzanie różnych forów nie przyniosło niczego szczególnie dobrego. Wygląda na to, że nikt przede mną nie próbował podłączyć tego konkretnego adaptera do Linuksa. No cóż, mam tyle szczęścia co topielec.

Choć nie, kłamię, odwiedziny na forach (głównie anglojęzycznych) także przyniosły efekty, w niektórych tematach pojawiła się wzmianka o pewnym panu lwfinger, który zasłynął z napisania szeregu sterowników do kart Wi-Fi. Jego repozytorium git znajduje się na końcu artykułu, w linkach. Drugą lekcją, jaką wyniosłem, jest to, że trzeba zidentyfikować swoje urządzenie, aby dowiedzieć się, który sterownik będzie dla niego odpowiedni.

Część 1. Tożsamość Bourne’a

Gdy podłączyłem urządzenie do portu, oczywiście żadna dioda LED się nie zaświeciła. I generalnie nie jest wcale jasne, czy coś działa, czy nie.

Pierwszą rzeczą, którą robię, aby dowiedzieć się, czy jądro widzi nasze urządzenie, jest sprawdzenie dmesg:

[  965.606998] usb 1-1.3: new high-speed USB device number 9 using dwc_otg
[  965.738195] usb 1-1.3: New USB device found, idVendor=2357, idProduct=0111, bcdDevice= 0.00
[  965.738219] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  965.738231] usb 1-1.3: Product: 802.11n NIC
[  965.738243] usb 1-1.3: Manufacturer: Realtek
[  965.738255] usb 1-1.3: SerialNumber: 00E04C0001

Okazało się, że go widzi, a nawet widać, że na magistrali USB znajduje się układ Realtek oraz VID/PID urządzenia.

Przejdźmy dalej i rzućmy okiem lsusbi tu czeka nas kolejna porażka

Bus 001 Device 008: ID 2357:0111 
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

System nie wie, jaki to rodzaj urządzenia i nieśmiało wyświetla puste miejsce zamiast nazwy (choć vendor=2357 to zdecydowanie TP-Link).

Dociekliwy czytelnik zapewne już zauważył coś interesującego, ale odłożymy to na później.

Badanie problemu pustych nazw doprowadziło mnie do witryny z identyfikatorami, gdzie wprowadza się informacje o znanych identyfikatorach VID/PID. Naszego 2357:0111 tam nie było. Jak się później okazało, narzędzie lsusb używa pliku /usr/share/misc/usb.ids, która jest tą samą listą identyfikatorów co na tej stronie. Aby wyświetlacz był jeszcze ładniejszy, dodałem do mojego systemu linie dostawcy TP-Link.

2357  TP-Link
        0111  TL-WN727N v5.21

Cóż, naprawiliśmy wyświetlanie na liście urządzeń, ale nie przybliżyło nas to do wyboru sterownika. Aby wybrać driver, musisz wiedzieć, na jakim chipie jest wykonany Twój gwizdek. Dalsze bezskuteczne próby znalezienia odpowiedzi na to pytanie w Internecie nie przyniosły żadnych rezultatów. Uzbrojony w cienki śrubokręt płaski ostrożnie podważam zaślepkę adaptera, a mój wzrok w całej swojej nieskazitelnej nagości ukazuje się okrutnemu dziecku wujka Liao. Pod lupą można zobaczyć nazwę układu - RTL8188EUS. To już jest dobre. Na niektórych forach widziałem posty, że sterownik tego samego pana lwfingera doskonale nadaje się do tego układu (mimo że pisał on tylko o RTL8188EU).

Część 2. Krucjata Bourne’a

Pobieram źródła sterowników z gita.

Czas ponownie zainstalować system Windows i zrobić to, z czym zazwyczaj kojarzą się użytkownicy Linuksa - złożyć coś ze źródeł. Jak się okazało, tworzenie sterowników nie różni się wiele od kompilowania programów:

make
sudo make install

ale żeby skompilować moduły jądra potrzebujemy plików nagłówkowych jądra dla naszej konkretnej wersji.

W repozytorium stockowym znajduje się pakiet raspberrypi-jądro-nagłówki, ale zawiera wersję jądra plików 4.19.66-v7l+, a nam to nie odpowiada. Ale żeby uzyskać nagłówki wymaganej wersji, jak się okazało, istnieje wygodne narzędzie źródło rpi (link na końcu na githubie), z którego można pobrać wymagane nagłówki. Klonujemy repozytorium, czynimy skrypt wykonywalnym i uruchamiamy go. Pierwsze uruchomienie kończy się błędem – brak narzędzia bc. Na szczęście jest on w repozytorium i możemy go po prostu zainstalować.

sudo apt-get install bc

Potem ponowne uruchomienie i pobranie nagłówków (a potem konfiguracja czegoś, teraz nie pamiętam) zajmuje trochę czasu, po czym można się odprężyć w fotelu. Windows stał się lepszy we wszystkich swoich przejawach.

Po pobraniu wszystkich nagłówków sprawdź, czy katalog się pojawił /lib/modules/4.19.73-v7+ a w nim dowiązanie symboliczne wskazuje na miejsce, w którym znajdują się pobrane pliki (u mnie jest to /home/pi/linux):

pi@raspberrypi:/home/pi/rtl8188eu# ls -l /lib/modules/4.19.73-v7+/
lrwxrwxrwx  1 root root     14 Sep 24 22:44 build -> /home/pi/linux

Etap przygotowawczy jest zakończony, można rozpocząć montaż. Montaż modułów zajmuje trochę czasu, a Raspberry Pi nie jest szybkim komputerem (ma 32-bitowy procesor Cortex ARM v900 7Mhz).
Więc wszystko skompilowane. W kroku 2 (make install) instalujemy sterownik, jednocześnie kopiując pliki oprogramowania układowego niezbędne do działania sterownika:

install:
        install -p -m 644 8188eu.ko  $(MODDESTDIR)
        @if [ -a /lib/modules/$(KVER)/kernel/drivers/staging/rtl8188eu/r8188eu.ko ] ; then modprobe -r r8188eu; fi;
        @echo "blacklist r8188eu" > /etc/modprobe.d/50-8188eu.conf
        cp rtl8188eufw.bin /lib/firmware/.
        /sbin/depmod -a ${KVER}
        mkdir -p /lib/firmware/rtlwifi
        cp rtl8188eufw.bin /lib/firmware/rtlwifi/.

Część 3. Ultimatum Bourne’a

Wkładam gwizdek do portu i... nic się nie dzieje. Czy to wszystko poszło na marne?

Zaczynam analizować pliki wewnątrz projektu i w jednym z nich znajduję, gdzie leżał problem: sterownik określa pełną listę identyfikatorów VID/PID, które może obsłużyć. A żeby nasze urządzenie działało z tym sterownikiem, dodałem po prostu swój identyfikator do pliku rtl8188eu/os_dep/usb_intf.c

static struct usb_device_id rtw_usb_id_tbl[] = {
        /*=== Realtek demoboard ===*/
        {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8179)}, /* 8188EUS */
        {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0179)}, /* 8188ETV */
        /*=== Customer ID ===*/
        /****** 8188EUS ********/
        {USB_DEVICE(0x07B8, 0x8179)}, /* Abocom - Abocom */
        {USB_DEVICE(0x0DF6, 0x0076)}, /* Sitecom N150 v2 */
        {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */
        {USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */
        {USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */
        {USB_DEVICE(0x2001, 0x331B)}, /* D-Link DWA-121 rev B1 */
        {USB_DEVICE(0x056E, 0x4008)}, /* Elecom WDC-150SU2M */
        {USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */
        {USB_DEVICE(0x2357, 0x0111)}, /* TP-Link TL-WN727N v5.21 */
        {}      /* Terminating entry */
};

Ponownie skompilowano sterownik i zainstalowano go ponownie w systemie.

I tym razem wszystko zaczęło działać. Zapaliła się kontrolka na karcie sieciowej, a na liście interfejsów sieciowych pojawiło się nowe urządzenie.

Przeglądanie interfejsów bezprzewodowych pokazuje następujące informacje:

pi@raspberrypi:/home/pi/rtl8188eu# iwconfig
eth0      no wireless extensions.

lo        no wireless extensions.

wlan0     unassociated  ESSID:""  Nickname:"<WIFI@REALTEK>"
          Mode:Auto  Frequency=2.412 GHz  Access Point: Not-Associated   
          Sensitivity:0/0  
          Retry:off   RTS thr:off   Fragment thr:off
          Encryption key:off
          Power Management:off
          Link Quality=0/100  Signal level=0 dBm  Noise level=0 dBm
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

Bonus dla tych, którzy doczytali do końca

Pamiętasz, jak mówiłem, że nie ma znaczenia, jaka maksymalna prędkość jest zadeklarowana na Twoim adapterze?
Dlatego na Raspberry Pi (przed premierą modelu 4) wszystkie urządzenia (łącznie z kartą Ethernet) podłączone były do ​​jednej magistrali USB. Całkiem fajne, prawda? Dlatego przepustowość magistrali USB jest dzielona pomiędzy wszystkie urządzenia na niej podłączone. Pomiar prędkości zarówno przez Ethernet, jak i przez USB Wi-Fi (podłączony do 1 routera) oraz przez łącze bezprzewodowe i przewodowe wykazał prędkość około 20 Mbit/s.

PS. Zasadniczo niniejszy przewodnik dotyczący kompilacji sterownika dla tego konkretnego adaptera nie jest ważny tylko w przypadku RPI. Następnie powtórzyłem to na swoim pulpicie z systemem Linux Mint - tam również wszystko zadziałało. Wystarczy pobrać w ten sam sposób wymagane pliki nagłówkowe dla używanej wersji jądra.

AKTUALIZACJA. Osoby dobrze zorientowane w temacie radzą: aby uniezależnić się od wersji jądra, należy skompilować i zainstalować sterowniki za pomocą dkms. Ta opcja jest również dostępna w pliku readme sterownika

pi@raspberrypi:/home/pi# sudo dkms add ./rtl8188eu
pi@raspberrypi:/home/pi# sudo dkms build 8188eu/1.0
pi@raspberrypi:/home/pi# sudo dkms install 8188eu/1.0

AKTUALIZACJA2. Sugerowane łatka dla identyfikatora urządzenia został zaakceptowany do głównej gałęzi repozytorium lwfinger/rtl8188eu.

referencje
- Adaptery Wi-Fi USB RPi
- Gitbub lwfinger/rtl8188eu
- identyfikatory usb
- źródło rpi

Źródło: www.habr.com