Kurs BeagleBone Black – #2- interfejs UART

Kurs BeagleBone Black – #2- interfejs UART

W drugiej części kursu przedstawię konfigurację oraz obsługę interfejsu UART. Oprócz obsługi z konsoli, omówię także przykładowy program napisany w języku C, który umożliwi komunikację między BBB, a komputerem PC.

Na wstępie zaprezentuję kilka podstawowych informacji dotyczących interfejsu UART- jednego z podstawowych protokołów używanych w robotyce.

« Poprzedni artykuł z serii

UART (Universal Asynchronous Receiver and Transmitter) - protokół transmisji szeregowej, służący do przesyłania informacji między urządzeniami, np. uC a komputerem czy też dwoma uC. Wiele układów i czujników korzysta z transmisji szeregowej UART (bądź USART) w celu przesyłania danych pomiarowych do urządzenia nadrzędnego.

Ramka danych protokołu

Ramka danych protokołu

W skład ramki wchodzi:

  • bit startu
  • bity danych (zazwyczaj 8)
  • bit parzystości
  • bity stopu (1 lub 2)

Najpopularniejszą ramką wysyłaną przez moduł UART jest ramka 8n1 (8 bitów danych, brak kontroli parzystości, 1 bit stopu). Więcej o UART w artykule "Port szeregowy i interfejs USART, czyli komunikacja mikrokontrolera z komputerem".

Zgodnie z dokumentacją BeagleBone Black udostępnia 4,5 x UART. Dlaczego 4,5? UART 1,2,4 i 5 są to pełne UART-y, które umożliwiają komunikację w obu kierunkach. Natomiast UART3 posiada jedynie linię TX do nadawania danych. 

Po uruchomieniu konsoli i wpisaniu komendy:

uname -r

Ukazuje się nam informacja dotycząca jądra systemu. Dla BBB rev. C jest to jądro 3.8.13. W nowych wersjach jądra (np. dla 3.8) nie mamy dostępu do multipleksacji pin-ów poprzez wpisy do pliku. Można natomiast uruchamiać dane urządzenie poprzez załadowanie nakładki do Device Tree (ładujemy pliki z rozszerzeniem .dtbo). W katalogu /lib/firmware znajdują się podstawowe nakładki do obsługi peryferiów BeagleBone Black. Po wpisaniu komendy:

ls /lib/firmware

Wyświetlą się następujące pliki odpowiedzialne za uruchomienie interfejsu UART:

BBB_02_

BB-UART1-00A0.dtbo, BB-UART2-00A0.dtbo, BB-UART4-00A0.dtbo, BB-UART5-00A0.dtbo.

Jak widać, producent oprogramowania przygotował nakładki na 4 pełne UART-y. Warto nadmienić, że istnieje możliwość napisania i skompilowania własnej nakładki dla UART3, ale o tym może przy innej okazji. Aktualny stan nakładek, które są uruchomione, można znaleźć w pliku:

cat /sys/devices/bone_capemgr.*/slots

BBB_02_02

Aby załadować moduł UART, należy wpisać w linię komend:

echo BB-UART1 > /sys/devices/bone_capemgr.*/slots

Po wywołaniu cat /sys/devices/bone_capemgr.*/slots widać, że UART1 został załadowany:

BBB_02_03

Teraz zajmijmy się wysyłaniem i odbiorem danych. Test komunikacji można przeprowadzić, podłączając BeagleBone-a np. do PC poprzez konwerter USB-UART przy użyciu terminala.

Ja używam prostego konwertera opartego na układzie FT232RL firmy FTDI. Po podłączeniu urządzenia do USB, należy znaleźć piny na urządzeniu, które odpowiadają UART1 TX (nadawanie) oraz RX (odbieranie). Standardowo trzeba połączyć Tx konwertera z Rx BBB i Rx konwertera z Tx BBB. Oto tabelka przedstawiająca numery wyprowadzeń:

BBB_02_04

Pin GND na BBB znajdziemy na konektorze P9_01 lub P9_02. Domyślnie UART1 jest skonfigurowany na prędkość przesyłu 9600 bps, dlatego tak samo należy skonfigurować terminal (ramka 8n1). Aby wysłać napis "komunikacja" z BBB do komputera, należy wywołać komendę:

echo komunikacja > /dev/ttyO1

W wyniku tego działania ukazują się dane w terminalu:

BBB_02_05

Aby odebrać dane, trzeba wprowadzić małą modyfikację w ustawieniach UART-u. Więcej o modyfikacji ustawień napiszę przy okazji programu w C. Teraz wystarczy wprowadzić w linię poleceń:

stty -F /dev/ttyO1 -icanon

Jest to wyłączenie canonical input (włączenie raw input). Pozwoli to na odczytanie danych w konsoli. Teraz komenda:

cat /dev/ttyO1

i wysyłamy przez terminal. Oto co pojawia się w konsoli BBB:

BBB_02_06

W taki sposób można przetestować działanie interfejsu UART.

Obsługa komunikacji w C

Teraz pora na krótką obsługę komunikacji w C. Dla osób, które nie pracowały w Linuksie, trzeba zaznaczyć, że w systemach Unix-owych każde urządzenie jest udostępnione dla użytkownika-programisty w postaci pliku. W związku z tym wysyłanie danych czy ich odbieranie będzie wiązało się z zapisem/odczytem do/z pliku. Najpierw omówię jednak konfigurację interfejsu szeregowego. Konfiguracja odbywa się przy pomocy struktury termios. W strukturze termios znajdziemy takie pola jak:

  • c_cflag - opcje sterowania
  • c_lflag - opcje lokalne
  • c_iflag - opcje wejścia
  • c_oflag - opcje wyjścia
  • c_cc - tablica znaków specjalnych
  • c_ispeed i c_ospeed odpowiedzialne za prędkość transmisji.

Nie jest moim celem opisywanie wszystkich elementów konfiguracji. Wpisując w wyszukiwarkę "linux termios" znajdziemy opis całej struktury. Skupię się na najważniejszych zmiennych, które są nam niezbędne do uruchomienia komunikacji.

Oto program obsługujący wysyłanie i odbieranie danych:

Zmienna fd to deskryptor portu, który służy jako jego identyfikator. Należy podać go za każdym razem, gdy chce się coś wysłać (odebrać).

Option to struktura typu termios, która zawiera zmienne konfiguracyjne portu.

Buf jest natomiast tablicą, do której będę zapisywał odebrane znaki.

Na początku używam wywołania systemowego, aby załadować urządzenie (aby nie robić tego "ręcznie" z konsoli). Następnie otwieram plik funkcją open(). Jako pierwszy argument podaję ścieżkę do pliku, jako drugi opcje dla funkcji. Opcja O_RDWR otwiera plik do odczytu i zapisu, O_NOCTTY powoduje, że inne urządzenia nie mają wpływu na działanie otwieranego portu.

Jeśli funkcja open() zwróci wartość < 0 oznacza, że plik został otwarty niepoprawnie. Dalej następuje konfiguracja struktury termios. Do pola c_cflag przypisuję prędkość transmisji z przedrostkiem "B", ramkę 8 bitową (CS8), stałą CLOCAL, która powoduje utworzenie linii lokalnej oraz CREAD - włączenie odbiornika. Do pola c_iflag przypisuję stałą IGNPAR (ignorowanie błędów parzystości) oraz IGNBRK (ignorowanie znaku przerwania).

Na koniec w polu c_cc umieszczam dla stałych VTIME wartość 0 (brak oczekiwania przy odbieraniu znaków w postaci opóźnienia czasowego) oraz dla VMIN wartość 19 (na tyle znaków będzie oczekiwała funkcja read(), zanim zwróci dane). Do VMIN wpisałem wartość 19, ponieważ napis "komunikacja_zwrotna" ma właśnie tyle znaków. Na koniec używam funkcji tcflush(), która odpowiada za "przepłukanie" bufora wejściowego oraz tcsetattr(), która wraz z opcją TCSANOW wprowadza nowe ustawienia natychmiast.

Aby wysłać dane należ wywołać funkcję write(). Jako argumenty podajemy identyfikator pliku, ciąg znaków do wysłania oraz ich liczbę. Do odbioru danych służy funkcja read(), która przyjmuje analogiczne argumenty jak funkcja write().

Na końcu programu zamykamy plik /dev/ttyO1 funkcją close(), podając identyfikator. Aby uruchomić program, musimy go utworzyć i skompilować. W celu utworzenia pliku uruchamiamy edytor "nano" poleceniem:

nano uart.c

Otworzy nam się okno edycji utworzonego pliku o nazwie uart.c. (plik tworzy się automatycznie):

BBB_02_07

Teraz kopiując program wklejamy go do edytora klikając prawym przyciskiem myszy na okno putty:

BBB_02_08

Zapisujemy plik wciskając CTRL+O i zamykamy edytor przy użyciu CTRL+X. W celu kompilacji programu wywołujemy wbudowany kompilator gcc poleceniem:

gcc -o test_uart uart.c

Jeżeli nie zostanie wypisany żaden komunikat, oznacza to, że kompilacja przebiegła poprawnie. Teraz uruchamiamy program poleceniem:

./test_uart

Program wysłał dane do terminala i oczekuje na odebranie 19 znaków.

BBB_02_09

Po wysłaniu danych z terminala do BBB program wypisuje otrzymany napis i kończy działanie:

BBB_02_10

Podsumowanie

Obsługa UART dla BeagleBone Black została przedstawiona w artykule w uproszczony sposób, który nie zawsze sprawdzi się w naszych aplikacjach. Mam jednak nadzieję, że pozwoli na szybki start osobom, które dopiero zaczynają swoją przygodę z tego typu urządzeniami i będzie podstawą do dalszej nauki.

« Poprzedni artykuł z serii

Artykuł zgłoszony do VII edycji konkursu (po)wakacyjnego!
Nagrody ufundował sponsor główny:

satland

 oraz sponsorzy:

and-techavthelion

ebookpointstrefakursów

BBB, beaglebone, uart