Mini system operacyjny dla STM32 – wprowadzenie

Funkcje API systemu ISIX-RTOS

Funkcje związane z schedulerem (plik nagłówkowy scheduler.h):
 void isix_init(prio_t num_priorities);
Funkcja ta inicjalizuje system ISIX-RTOS. Jako argument przyjmuje maksymalną liczbę priorytetów zadań używanych przez scheduler. Zadanie o najwyższym priorytecie posiada priorytet 0 zadanie o najniższym priorytecie posiada priorytet num_priorities1. Każdy dodatkowy priorytet używany przez system zmniejsza ilość wolnego RAM-u na stercie o 16 bajtów. W systemie może być dowolna ilość zadań o takim samym priorytecie, które są szeregowane według algorytmu karuzelowego Round-Robin.

prio_t isix_get_min_priority(void);
Funkcja pobiera minimalny dopuszczany numer priorytetu w systemie (zadanie o najniższym priorytecie)

void isix_start_scheduler(void) __attribute__((noreturn));
Funkcja uruchamia system i rozpoczyna szeregowanie zadań, jest to ostatnia funkcja wywoływana z funkcji głównej main().

void isix_bug(void);
Wywołanie tej funkcji powoduje zatrzymanie systemu operacyjnego. Powinna być ona wywoływana w wyniku wystąpienia krytycznego błędu. W przypadku, gdy aplikacja skompilowana jest w trybie debug powoduje to wypisanie na terminalu dodatkowych informacji diagnostycznych.

tick_t isix_get_jiffies(void);
Funkcja zwraca liczbę cykli zegarowych od momentu włączenia systemu. Długość cyklu zależy od częstotliwości przerwania zegarowego, którą określa stała ISIX_HZ.

static inline void isix_yield() { port_yield(); }
Funkcja powoduje oddanie sterowania oraz przeprowadzenie ponownego zaszeregowanie zadań.

Funkcje związane z zarządzaniem zadaniami/wątkami (plik nagłówkowy task.h):
task_t* isix_task_create(task_func_ptr_t task_func, void *func_param, unsigned long stack_depth, prio_t priority);
Funkcja tworzy nowe zadanie (wątek). Jako pierwszy argument task_func przyjmuje wskaźnik do funkcji tworzącej zadanie (wątek), o następującej sygnaturze:
void task_func(void *arg) __attribute__((noreturn));
Drugi argument func_param określa argument przekazany do funkcji zadania/wątku, który można odczytać z tej funkcji za pomocą argumentu arg. Argument stack_depth określa wielkości stosu dla danego zadania (wątku). Minimalną dopuszczalną wielkość pamięci określa stała ISIX_MIN_STACK_DEPTH. Argument priority określa priorytet przydzielony dla tworzonego zadania. Funkcja zwraca wskaźnik na strukturę kontrolną zadania task_t* lub NULL w przypadku wystąpienia błędu.

static inline int isix_task_change_prio( task_t* task, prio_t new_prio );
Funkcja pozwala zmienić bieżący priorytet przydzielonego zadania na inny z dopuszczalnego zakresu. Jako argument przyjmuje wskaźnik do struktury kontrolnej zadania, oraz nowy priorytet zadania. Funkcja ta zwraca kod błędu lub ISIX_EOK (0). Pozostałe kody błędów znajdują się w pliku nagłówkowym error.h.

int isix_task_delete(task_t *task);
Funkcja powoduje zatrzymanie zadania (wątku) przekazanego jako argument task oraz jego usunięcie. Funkcja ta zwraca kod błędu.

Do komunikacji międzyprocesowej służą semafory, których API zawarto w pliku nagłówkowym semaphore.h:
sem_t* isix_sem_create(sem_t *sem,int val);
Funkcja tworzy (gdy argument sem ma wartość NULL) lub inicjalizuje semafor *sem i przypisuje mu wartość początkową val. Funkcja zwraca wskaźnik do struktury kontrolnej semafora lub NULL w przypadku niepowodzenia.

int isix_sem_wait(sem_t *sem, tick_t timeout);
Funkcja zmniejsza wartość semafora o 1 gdy jego wartość jest większa od 0, w przypadku gdy wartość semafora jest równa 0 powoduje uśpienie bieżącego wątku (zadania) do momentu podniesienia semafora lub do upłynięcia czasu timeout. W przypadku, gdy argumentowi timeout, przypisano wartość ISIX_TIME_INFINITE, wątek ten czeka bezwarunkowo do chwili podniesienia semafora. Kod błędu ISIX_EOK oznacza, że funkcja powróciła w wyniku podniesienia semafora. Kod błędu ISIX_ETIMEOUT oznacza wystąpienia przeterminowania.

int isix_sem_get_isr(sem_t *sem);
Funkcja jest odpowiednikiem sem_wait, która może być wywoływana z kontekstu procedury obsługi przerwania, co wynika z niemożności odroczenia procedury obsługi przerwania.

static inline int isix_sem_signal(sem_t *sem);
static inline int isix_sem_signal_isr(sem_t *sem);

Te funkcje powodują podniesienie semafora poprzez zwiększenie jego zawartości o 1 oraz ewentualne wybudzenie oczekującego zadania (procesu). Wersja funkcji z sufiksem _isr może być wywoływania z kontekstu procedury obsługi przerwania. W przypadku powodzenia zwraca wartość ISIX_EOK (0).

int isix_sem_destroy(sem_t *sem);
Funkcja powoduje usunięcie semafora przekazanego jako argument sem, oraz zwolnienia zasobów zajmowanych przez ten semafor. W przypadku powodzenia zwraca wartość ISIX_EOK.

tick_t isix_ms2tick(unsigned long ms);
Funkcja powoduje przeliczenie liczby milisekund przekazanych jako argument ms na liczbę cykli systemu operacyjnego

static inline int isix_wait(tick_t timeout);
Funkcja usypia zadanie (wątek) na określoną liczbę cykli systemu. W przypadku powodzenia po zakończeniu oczekiwania zwraca wartość ISIX_EOK.

O autorze