- FST Detektor i Decoder:
- Dekoder - zamienia sygnały itd na wydarzenia
- Detektor - zwraca najważniejsze wyderzenia.
Tablica FSM ma M wierszy. Każdy wierszy przechowuje informacje jak "zhandlować" dane wyderzenie w zależności od stanu. Musimy stworzyć dodatkowy wektor/tablice zaistniałych wydarzeń.
Boolean events[M]
void detektor() {
if(czyZdarzenie1Zaszlo()) events[0] = true;
else if(czyZdarzenie2Zaszlo()) events[1] = true;
/*
Dużo zdarzeń tutaj!
*/
else if(czyZdarzenieMZaszo()) events[M-1] = true;
}
unsigned int dekoder(){
for(int i = M - 1; i >= 0; i--) {
if(events[M]) return i;
}
return -1 //Nie znaleziono
}
- Mapy do dyspozycji jedną 32 lub 64 bitową liczbę, więc max tyle zdarzeń!
/*
Musimy mieć zdefiniowane stałe, które są potęgami dwójki
*/
const int ZDARZENIE1 = 1
const int ZDARZENIE2 = 2
const int ZDARZENIE3 = 4
const int ZDARZENIE4 = 8
int events = 0; // Same 0000000000
void detektor(){
if(zdarzenie1){
events |= ZDARZENIE1
zdarzenie1 = false
} else if(zdarzenie2){
events |= ZDARZENIE2
zdarzenie2 = false
} .... else if(zdarzenie4){
events |= ZDARZENIE4
zdarzenie4 = false
}
}
interrupt {
if(! zdarzenieI) zdarzenieI = true
}
//Takie cuś zdefiniować dla każdego przerwania obsługiwanego
- Trzeba było przepisać to:
typedef data struct
{
// Pointer to the task (must be a 'void (void)' function)
void (code * pTask)(void);
// Delay (ticks) until the function will (next) be run
// - see SCH_Add_Task() for further details
tWord Delay;
// Interval (ticks) between subsequent runs.
// - see SCH_Add_Task() for further details
tWord Period;
// Incremented (by time interrupt service routine) when task is due to execute
tByte RunMe;
} sTask;
void SCH_Update(void) interrupt INTERRUPT_Timer_2_Overflow
{
tByte Index;
TF2 = 0; // Have to manually clear interrupt for some architectures
// NOTE: calculations are in *TICKS* (not milliseconds)
for (Index = 0; Index < SCH_MAX_TASKS; Index++)
{
// Check if there is a task at this location
if (SCH_tasks_G[Index].pTask)
{
if (SCH_tasks_G[Index].Delay == 0)
{
// The task is due to run
SCH_tasks_G[Index].RunMe += 1; // Inc. the 'RunMe' flag
if (SCH_tasks_G[Index].Period)
{
// Schedule periodic tasks to run again
SCH_tasks_G[Index].Delay = SCH_tasks_G[Index].Period;
}
}
else
{
// Not yet ready to run: just decrement the delay
SCH_tasks_G[Index].Delay -= 1;
}
}
}
}
-
Takie coś nabazgrać trzeba: http://elf2.pk.edu.pl/mod/book/view.php?id=41144&chapterid=2791 Rys 5!
-
Przekopiowane z notek:
struct tcb //struktura danych związana z zadaniem
{
char name[MAXLEN+1]; //identyfikator zadania
proc (*addr)(); //funkcja skojarzona z zadaniem
int type; //typ zadania - ważne w aplikacjach real time
int state; //aktualny stan zadania - zgodny z przyjetymi typami zadań
long dline; //termin zadania - ważne w aplikacjach real time
int period; //okres zadania periodycznego
int prt; //priorytet
int wcet; //worst case execution time
float util; //współczynnik wykorzystania procesora = wcet/period
int *context; //wskaźnik do adresu w pamięci pod ktorym przechowywany jest kontekst zadania
proc next; //zmienna wskazująca na następne zadanie na liście zadań
proc prev; //zmienna wskazująca na poprzednie zadanie na liście zadań
};
void instert(proc i, queue *que) //Wstawienie zadania do kolejki que
//Ponieważ używamy EDF, wszystkie zadania są uporządkowane
//według terminów i dlatego w funkcji zaimplementowano
//przeszukiwanie kolejki
{
long dl; /*deadline*/
int p; /*pointer to the previous TCB */
int q; /*pointer to the next TCB */
p=NIL;
q=*que; /*a list is identifird by its first element */
dl=vdes[i].dline;
while((q!=NIL) && dl>=vdes[q].dline))
{
p=q;
q=vdes[q].next;
}
if (p!=NIL) vdes[p].next=i;
else *que=i;
if (q!=NIL) vdes.prev=i;
vdes[i].next=q;
vdes[i].prev=p;
}