LinkedIn YouTube Facebook
Szukaj

Wstecz
Artykuły

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.

Tagi: GPIO, ISIX, LED, RTOS, STM32