ISIX-RTOS – trzy wątki, przykłady w języku C: termometr z wyświetlaczem LED-RGB
Sposób działania przykładowej aplikacji z uwzględnieniem podziału na wątki przedstawiono na rys. 2. Zasada działania aplikacji jest w zasadzie identyczna jak w przykładzie, różnica polega jedynie na zmianie funkcji wątku wyświetlania. Program rozpoczyna działanie od funkcji main() (list. 1).
List. 1. Funkcja main
/** Main func */ int main(void) { //Create ISIX blinking task isix_task_create( blinking_task, NULL, ISIX_PORT_SCHED_MIN_STACK_DEPTH, TASK_PRIO_LED); //Create fifo msgs fifo_t *temp_fifo = isix_fifo_create( 10, sizeof(struct msg) ); //Initialize i2c bus i2cm_init(I2C_SPEED); if(temp_fifo) { //Create isix tasks (temp and disp) isix_task_create(temp_read_task, temp_fifo,TASK_STK_SIZE, TASK_PRIO_TEMP); isix_task_create(display_srv_task, temp_fifo,TASK_STK_SIZE, TASK_PRIO_TEMP); } //Start the scheduler isix_start_scheduler(); }
Najpierw tworzony jest niezależny wątek migania diodą D1 (zamontowana na pytce „motyla”), następnie tworzona jest kolejka FIFO, której maksymalną pojemność ustawiono na 10 elementów zdefiniowanych jako struktura msg. Następnie inicjalizowana jest biblioteka obsługi magistrali I2C, a następnie w przypadku pomyślnego utworzenia kolejki FIFO, tworzone jest zadanie odczytu temperatury temp_read_task oraz wątek wyświetlania temperatury display_srv_task . Po utworzeniu wszystkich wątków, uruchamiany jest planista zadań systemu ISIX. Strukturę wiadomości nieco odmienną niż w poprzednim przypadku zdefiniowano w sposób pokazany na list. 2.
List. 2. Struktura wiadomości przekazywanej pomiędzy wątkami
//Message structure struct msg { float t; //Current temperature int errno; //Error code };
W tym przypadku celowo, aby pokazać że operacje zmienno-przecinkowe wykonywane są przez rdzeń Cortex-M3 bardzo sprawnie, zdecydowano się na zdefiniowanie temperatury w postaci liczby zmiennoprzecinkowej typu float . Ten typ zostanie również użyty w przypadku obliczenia nasycenia barw w zależności od temperatury, o czym napiszemy w dalszej części.
Za odczytywanie temperatury z czujnika MCP9801 odpowiada wątek temp_read task , który działa identycznie jak w poprzednim przykładzie, jedyna różnica występuje w funkcji tempsensor_get() (list. 3), w której wartość temperatury jest przeliczana na liczbę zmiennoprzecinkową.