ISIX-RTOS – przykład 3 – obsługa przerwań na przykładzie zegara RTC z magistralą I2C

Opis systemu ISIX-RTOS i jego funkcji opublikowaliśmy w artykule „Mini system operacyjny dla STM32 – wprowadzenie”, który można przeczytać tu.

Wątki mogą komunikować się ze sobą za pomocą semaforów lub kolejek komunikatów. Korzystanie z nich może powodować usypianie procesu (sleep state) w wyniku oczekiwania na pozyskanie zasobu. W przypadku przerwań uśpienie procedury obsługi przerwania nie jest możliwe z uwagi, że przerwania nie są wykonywane w kontekście procesu W związku z tym dla procedur obsługi przerwań należy wywołać tylko metody nieblokujące. W systemie ISIX, w kontekście obsługi przerwań mogą być wywoływane jedynie metody z sufiksem _isr. Sposób obsługi komunikacji pomiędzy zadaniami, a procedurami obsługi przerwań pokażemy na przykładzie obsługi magistrali I2C z podłączonym scalonym zegarem RTC M41T56C64 (na przykład z modułu KAmodRTC). Działanie aplikacji sprowadzać się będzie do odczytania godziny z zegara RTC, przetworzenia go na komunikat, oraz przesłanie go do serwera wyświetlania, zaprezentowanego w poprzednim przykładzie. Kolejny niezależny wątek podobnie jak w poprzednim przykładzie będzie migał diodą LED D1 zamontowaną w zestawie STM32Butterfly.

Uwaga!
W prezentowanym przykładzie można zastosować moduły z serii KAmod: KAmodLCD1 oraz KAmodRTC dostępne na stronie http://www.kamami.pl/

W przykładzie zastosowano także wyświetlacz od Nokii3310 (KAmodLCD1). Sposób dołączenia wyświetlacza i układu RTC do mikrokontrolera pokazano na rys. 1.

Rys. 1. Sposób dołączenia zegara RTC i wyświetlacza LCD

Rys. 1. Sposób dołączenia zegara RTC i wyświetlacza LCD

Układ M41T56C64 firmy ST jest bardzo interesującym opracowaniem, integrującym w jednej obudowie zegar czasu rzeczywistego RTC z wbudowanym rezonatorem kwarcowym 32768 Hz oraz pamięć EEPROM AT24C64. Układ charakteryzuje się poborem prądu rzędu 400 nA, co umożliwia mu pracę z małej baterii litowej nawet 10 lat. Dzięki zintegrowaniu w układzie rezonatora kwarcowego nie musimy dołączać z zewnątrz praktycznie żadnych elementów, dodatkowo rezonator ten jest kalibrowany w procesie produkcji przez firmę ST, która gwarantuje dokładność rzędu +/- 5 ppm. Układ pamięci oraz zegara zostały wewnętrznie dołączone do wspólnej magistrali I2C, a rozróżnienie ich następuje na podstawie adresów sprzętowych I2C (szczegóły w dokumentacji).

Uwaga!
Ustawienie zwór adresowych J1…J3 na rys. 1 ma wpływ tylko na adres pamięci EEPROM zintegrowanej w układzie M41T56C64, adres zegara RTC jest niezmienny.

 
Przykładowy program pokazuje na wyświetlaczu LCD aktualną godzinę oraz miga diodą LED D1 znajdującą się na płytce STM32Butterfly. Sposób działania aplikacji z podziałem na wątki przedstawiono na rys. 2.

 

Rys. 2. Podział aplikacji na wątki

Rys. 2. Podział aplikacji na wątki

Wątek obsługi LED pracuje zupełnie niezależnie od pozostałych wątków, co pozwala pokazać ich wzajemną niezależność. Wątek obsługi LCD, który z punktu widzenia pozostałych wątków jest serwerem wyświetlania, odpowiada za odbiór rozkazów oraz odpowiednie sterowanie wyświetlaczem. Wątek RTC jest odpowiedzialny za odczytanie aktualnej godziny z zegara RTC poprzez interfejs I2C, sformatowanie tekstu, następnie wygenerowanie i przesłanie komunikatu dla serwera wyświetlania. Aplikacja została napisana w sposób obiektowy w języku C++, gdzie hierarchię klas przedstawiono na rys. 3.

 

Rys. 3. Hierarchia klas projektu

Rys. 3. Hierarchia klas projektu

Hierarchia klas jest bardzo podobna do przykładu 2, ponieważ wykorzystano opisaną w nim architekturę serwera wyświetlania. Klasa the_application jest klasą aplikacji, w której zawarto wszystkie pozostałe obiekty. Klasa led_blink jest odpowiedzialna za cykliczne miganie diodą LED i jest dziedziczona z klasy isix::task_base implementującej obsługę wątków. Klasa display_server jest odpowiedzialna za odbiór komunikatów z kolejki FIFO oraz fizyczne sterowanie kontrolerem wyświetlacza za pomocą klasy nokia_display. Klasa i2c_host jest uniwersalną klasą sterownika, implementująca obsługę magistrali I2C z wykorzystaniem sprzętowego kontrolera I2C1 w trybie 7-bitowym. Została ona napisana w taki sposób aby można było ją rozwinąć o obsługę dodatkowych sprzętowych kontrolerów I2C, występujących w mikrokontrolerach rodziny STM32Fxxx. Deklaracja klasy znajduje się w pliku i2c_host.hpp (list. 1).

List. 1. Deklaracja klasy sterownika i2c_host

Klasa została zaprzyjaźniona z funkcją i2c1_ev_isr_vector stanowiącą wektor obsługi przerwania od kontrolera I2C1. Wszystkie procedury obsługi przerwań muszą mieć linkowanie typu C (extern „C”). Funkcje wywoływane są w momencie wystąpienia przerwania bez żadnych dodatkowych parametrów, co wymusza istnienie dostępu do instancji klasy kontrolera I2C poprzez wskaźnik lub referencję globalną. Wskaźnik do obiektu i2c umożliwiający dostęp do obiektu kontrolera I2C przez funkcję obsługi przerwania umieszczono w nienazwanej przestrzeni nazw w pliku implementacji klasy (i2c_host.cpp), przez co dostęp do niej jest możliwy tylko w obrębie tego modułu (list. 2).

List. 2.

Do pobrania

O autorze