ISIX-RTOS – przykład 2 – kolejki FIFO i obsługa graficznego wyświetlacza LCD
Ustawienie wybranej pozycji kursora w pamięci obrazu sprowadza się do wysłania do wyświetlacza komendy Set Row Position oraz Set Col Position.
Działanie klasy display_server (wątku serwera) , sprowadza się do odczytywania komunikatów (wskaźników do klas komunikatów) z kolejki FIFO, a następnie odpowiednie wykorzystanie metod klasy nokia_display do sterowania wyświetlaczem. Zadanie to realizowane jest przez metodę wirtualną main() klasy display_server (list. 7).
List. 7. Metoda wirtualna main() klasy display_server
//Main thread
void display_server::main()
{
const display_msg *msg = NULL;
for(;;)
{
//Try read message from the fifo
if(io_fifo.pop(msg) == isix::ISIX_EOK)
{
//Validate message
if( msg )
{
//Clear display
display.clear();
//If text message
if(msg->get_type() == display_msg::MSG_TEXT)
{
//Cast to the text message class
const text_msg *t = static_cast(msg);
if(t->get_text())
{
//Write text on the display
display.put_string( t->get_text(), t->get_x(), t->get_y());
}
}
//If graphics message
else if( msg->get_type() == display_msg::MSG_GRAPHICS)
{
//Get image
const images::img_def *img = static_cast(msg)->get_image();
if(img)
{
//Display bitmap
display.put_bitmap(*img);
}
}
}
}
}
}
W pętli głównej wątku wywoływana jest metoda pop() obiektu kolejki FIFO (io_fifo). Metoda ta blokuje wykonywanie wątku do momentu odebrania od innego zadania komunikatu przekazanego za pomocą metody push(). W przypadku, gdy kolejka FIFO zawiera jakiś komunikat, wówczas metoda pop(), wybudza wątek i zwraca kod błędu isix::ISIX_EOK. W przypadku odebrania prawidłowego komunikatu, zawartość wyświetlacza LCD jest czyszczona za pomocą metody clear() obiektu wyświetlacza display, a następnie sprawdzany jest typ przekazanego komunikatu (obiektu) za pomocą metody get_type() klasy bazowej display_msg. Wykrywanie typów klas również można zrealizować za pomocą mechanizmu RTTI (Run Time Type Information) i operatora typeid(), jednak z uwagi na dużą zajętość pamięci Flash mechanizm RTTI został wyłączony za pomocą flagi kompilatora -fno-rtti) Jeżeli przekazany obiekt jest typu tekstowego (text_msg), wówczas jest on rzutowany na wskaźnik do klasy text_msg, i następnie wywoływane są metody pobierające wskaźnik do napisu oraz pozycję tekstu na ekranie. Następnie wywoływana jest metoda obiektu wyświetlacza (display), wypisująca tekst na wyświetlaczu LCD na zadanej pozycji. W przypadku, gdy mamy do czynienia z obiektem typu graficznego (graph_msg), wówczas jest on rzutowany na wskaźnik do tego obiektu, a następnie wywoływana jest metoda pobierająca wskaźnik na strukturę opisującą obrazek (img_def). Następnie wskaźnik ten jest przekazywany do metody put_bitmap() obiektu wyświetlacza, który jest odpowiedzialny za wyświetlenie bitmapy. Obiekt keys, klasy graph_key jest odpowiedzialny za odczyt stanu joysticka oraz wysyłanie komend dla serwera wyświetlania w zależności od kierunku przechylenia josyticka.
List. 8. Klasa graph_key jest odpowiedzialna za odczyt stanu joysticka oraz wysyłanie komend dla serwera wyświetlania w zależności od kierunku przechylenia joysticka
//Constructor
graph_key::graph_key(display_server &_srv) :
task_base( STACK_SIZE, TASK_PRIO), disp_srv(_srv)
{
//Enable PE in APB2
RCC->APB2ENR |= RCC_APB2Periph_GPIOE;
//Set GPIO as inputs
io_config( KEY_PORT, KEY_OK_BIT, GPIO_MODE_INPUT, GPIO_CNF_IN_FLOAT);
io_config( KEY_PORT, KEY_UP_BIT, GPIO_MODE_INPUT, GPIO_CNF_IN_FLOAT);
io_config( KEY_PORT, KEY_DOWN_BIT, GPIO_MODE_INPUT, GPIO_CNF_IN_FLOAT);
io_config( KEY_PORT, KEY_LEFT_BIT, GPIO_MODE_INPUT, GPIO_CNF_IN_FLOAT);
io_config( KEY_PORT, KEY_RIGHT_BIT, GPIO_MODE_INPUT, GPIO_CNF_IN_FLOAT);
}
Obiekt inicjalizowany jest za pomocą konstruktora, który jako argument przyjmuje referencję do klasy display_server. W konstruktorze inicjalizowane są porty GPIO do których podłączone są poszczególne styki joysticka. Odczyt stanu joysticka oraz wysyłanie komunikatów realizowane jest przez metodę główną wątku main() – list. 9.
List. 9. Metoda główna wątku main() odpowiada za odczyt stanu joysticka oraz wysyłanie komunikatów
//Task/thread method
void graph_key::main()
{
//Previous key variable
static short p_key = -1;
//Graphics message class
static graph_msg gmsg;
//Text message class
static text_msg tmsg("Wcisnales OK");
for(;;)
{
//Get key
short key = get_key();
//Check if any key is pressed
if(key!=0 && p_key==0)
{
switch(key)
{
case KEY_OK:
disp_srv.send_message(tmsg);
break;
case KEY_LEFT:
gmsg.set_image( images::isixlogo_bmp);
disp_srv.send_message(gmsg);
break;
case KEY_RIGHT:
gmsg.set_image( images::disk_bmp);
disp_srv.send_message(gmsg);
break;
case KEY_UP:
gmsg.set_image( images::printer_bmp);
disp_srv.send_message(gmsg);
break;
case KEY_DOWN:
gmsg.set_image( images::scriba_bmp);
disp_srv.send_message(gmsg);
break;
}
}
//Previous key assignement
p_key = key;
//Wait short time
isix::isix_wait( isix::isix_ms2tick(DELAY_TIME) );
}
}
Wykrywanie kierunku przechylenia joysticka jest realizowane w pętli głównej wątku, na zasadzie wykrywania zbocza na linii GPIO, do której dołączono styki joysticka. W przypadku wykrycia zbocza opadającego na którymś z wejść program ustala jaki kierunek wskazuje josytick, następnie do kolejki FIFO serwera wyświetlania jest przekazywany obiekt komunikatu za pomocą metody send_message(). Dodatkowe krótkie opóźnienie o długości DELAY_TIME (25 ms) eliminuje wpływ drgań styków na działanie aplikacji.

AAEON BOXER-6751-ADP – przemysłowy komputer typu Box PC przygotowany na wymagania współczesnej automatyki
Wzrost, Certyfikacja, Stabilność: PB Training Podsumowuje Pomyślny Rok 2025
Generator Peltza – eksperyment z użyciem zestawu ADALM2000 



