Sterowanie portami w mikroprocesorze STM32MP może odbywać się za pośrednictwem rdzenia Cortex-M4 (w przypadku serii STM32MP1) lub Cortex-M33 (w przypadku STM32MP2), o ile rdzeń jest dostępny. Czasami jednak chcemy mieć możliwość kontrolowania pracy portu GPIO bezpośrednio z poziomu systemu operacyjnego Linux. W tym celu możemy oczywiście przekazywać informacje o tym, w jakim stanie ma znajdować się port GPIO, do koprocesora. Niestety wymaga to pisania dodatkowego kodu odpowiedzialnego za komunikację pomiędzy rdzeniami. Takie rozwiązanie wprowadza pewne opóźnienie w wykonywanym kodzie.
W kolejnych odcinkach kursu zostanie zaprezentowana procedura pozwalająca na nawiązanie komunikacji pomiędzy rdzeniami, wraz z jej potencjalnym zastosowaniem w prostych, jak i bardziej złożonych projektach. Już teraz możemy natomiast powiedzieć, że użycie tego rodzaju komunikacji okazuje się przydatne sytuacjach, w których dodatkowy rdzeń odpowiada za komunikację z zewnętrznymi układami za pomocą interfejsu SPI, I²C, etc., a główny procesor dokonuje obróbki danych, wyświetlania wartości na ekranie itp.
Jeżeli stawiamy na szybkość działania kodu bądź z innych względów nie chcemy angażować dodatkowego rdzenia, do sterowania portem GPIO możemy zastosować główny rdzeń, pracujący pod kontrolą systemu Linux.
Sterowanie LED
W omawianym przykładzie skorzystamy z portu GPIO, do którego na płytce STM32MP157C-DK2 podłączona jest niebieska dioda LED o oznaczeniu LD8. Domyślnie dioda sygnalizuje działanie rdzenia z Linuxem i imituje bicie serca.
Sterowanie diodą odbywać może się na dwa sposoby: z poziomu terminala (konsoli systemu Linux) lub bezpośrednio z poziomu kodu. Zaprezentowane zostaną oba podejścia, z uwagi na różnice wynikające ze sposobu ich użycia oraz zakresu potencjalnych zastosowań we własnych projektach.
Sterowanie LED z terminalu Linux
Sterowanie portem GPIO z poziomu terminala jest wygodnym i szybkim sposobem na zmianę aktualnego stanu danego pinu wyjściowego lub odczytanie poziomu logicznego na wejściu, bez konieczności wykonywania złożonego kodu. Może być również przydatne w momencie, gdy chcemy dokonać szybkiej zmiany stanu wyjścia niezależnie od wykonywanego kodu głównego lub w przypadku, gdy w kodzie nie znajduje się funkcja pozwalająca nam na takie działanie.
Nie będziemy ponownie pokazywać procedury nawiązywania komunikacji z naszą płytką za pośrednictwem SSH – wszystkie niezbędne działania zostały już zaprezentowane we wcześniejszych odcinkach tego kursu.
W celu ustawienia stanu wysokiego („1”) na wyjściu sterującym diodą LD8 należy wprowadzić w terminalu następującą komendę:
natomiast ustawienie stanu niskiego, czyli wyłączenie naszej diody, może być wykonane przez podanie analogicznego polecenia:
Użyta w tym przykładzie ścieżka jest zapisana w systemie operacyjnym, więc nie musimy tutaj ingerować w kod źródłowy.
Sterowanie LED z poziomu kodu
Jak wcześniej wspomnieliśmy, sterować diodą LD8 możemy również z poziomu kodu. Taki sposób obsługi GPIO pozwala nam na większą swobodę działania: w kodzie możemy w łatwy sposób wykonywać bardziej złożone operacje, na przykład wprowadzać odpowiednie opóźnienia.
Zaprezentowany na listingu 1 kod został napisany w języku Python i pozwala na sterowanie portem GPIO w pętli nieskończonej. Dodatkowo pozwala użytkownikowi na zmianę interwału błysków. Standardowy interwał został ustawiony na 1, tak więc wywołanie funkcji bez podania argumentu automatycznie uzupełnia go wartością domyślną, natomiast wywołanie tej samej funkcji z argumentem spowoduje nadpisanie domyślnej wartości przez liczbę wprowadzoną przez użytkownika.
def set_led(state):
try:
with open("/sys/class/leds/heartbeat/brightness", "w") as led:
led.write(str(state))
except IOError as e:
print(f"Error accessing LED file: {e}")
def blink_led(interval=1):
while True:
set_led(1) # Turn LED on
time.sleep(interval)
set_led(0) # Turn LED off
time.sleep(interval)
if __name__ == "__main__":
blink_led()
Listing 1. Kod napisany w języku Python, odpowiedzialny za sterowanie portem GPIO w środowisku Linux
W celu uruchomienia kodu – w przypadku, gdy kod powstawał na komputerze – należy przesłać plik do płytki za pośrednictwem polecenia scp. Można też napisać kod bezpośrednio na płytce, z poziomu otwartego połączenia SSH w terminalu. Domyślnie dystrybucja Yocto udostępnia narzędzie pozwalające na pisanie kodu – jest to posty edytor tekstu vi działający w terminalu.
Po wgraniu kodu na płytkę uruchomienie programu odbywa się poprzez wywołanie polecenia:
W przypadku poprawnie uruchomionego skryptu widocznym efektem jego poprawnego funkcjonowania będzie cykliczne mruganie niebieskiej diody LD8.
Podsumowanie
Możliwość sterowania wyjściem z poziomu terminala bądź kodu w języku Python wymaga zastosowania innych mechanizmów dostępu do portu. Wybór odpowiedniej metody sterowania zależy w głównej mierze od docelowego zastosowania, jak i od preferencji użytkownika. W niektórych przypadkach – zwłaszcza gdy zależy nam na szybkiej, jednorazowej zmianie stanu danego pinu – lepiej będzie użyć polecenia wydanego z poziomu terminala linuksowego.
Jeżeli pierwszorzędne znaczenie ma niezawodność działania bądź możliwość implementacji bardziej złożonych mechanizmów kontroli wyjścia/wejścia GPIO, lepszym rozwiązaniem okaże się napisanie kodu.
inż. Wiktor Hubaj