-
Notifications
You must be signed in to change notification settings - Fork 0
/
yakc.c
151 lines (125 loc) · 3.1 KB
/
yakc.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include "clib.h"
#include "yaku.h"
#include "yakk.h"
//Defines
#define LOWEST_PRIORITY 100
#define INITIAL_FLAGS 0x0020
//Local prototypes
void make_ready_task(tcb_t* tcb);
void YKScheduler(void);
void YKDispatcher(struct tcb* tcb);
void YKIdleTask(void);
tcb_t* active_task = 0;
tcb_t* ready_task = 0;
tcb_t* blocked_list = 0;
tcb_t tcb_memory[MAX_TCB_COUNT];
tcb_t* next_tcb_ptr = tcb_memory;
int task_id_count = 0;
int idle_stack[STACK_SIZE];
int kernel_running = 0;
int YKIdleCount = 0;
int YKCallDepth = 0;
int YKCtxSwCount = 0;
void YKInitialize(void){
tcb_t* idle = next_tcb_ptr++;
idle->id = task_id_count++;
idle->state = 1;
idle->priority = LOWEST_PRIORITY;
idle->next = 0;
idle->sp = &idle_stack[STACK_SIZE];
idle->ss = 0;
// *(idle->sp - 1) = INITIAL_FLAGS;
*(idle->sp - 2) = 0;//bx
*(idle->sp - 1) = (int) YKIdleTask;//start point
idle->sp -= 1*sizeof(int);
ready_task = idle;
//create idle task tcb and put it in the ready queue
//??
//profit
}
void YKIdleTask(void){
while(1){
YKIdleCount++; //Make sure this loop is 4 instructions
}
}
void YKNewTask(void (* task)(void), void *taskStack, unsigned char priority){
tcb_t* tcb;
YKEnterMutex();
tcb = next_tcb_ptr++;
tcb->id = task_id_count++;
tcb->state = 1;
tcb->priority = priority;
tcb->next = 0;
tcb->sp = (int*)((char*)taskStack);
tcb->ss = 0;
// *(tcb->sp - 1) = INITIAL_FLAGS;
// *(tcb->sp - 2) = 0;
*(tcb->sp - 2) = (int) 0;//bx
*(tcb->sp - 1) = (int) task;//start point
tcb->sp -= 1 * sizeof(int);
make_ready_task(tcb);
YKExitMutex();
YKScheduler();
//Create and initialize TCB
//Store initial flags and IP to stack
//
}
void YKRun(void){
//Calls the scheduler, sets global variable to activate user tasks
kernel_running = 1;
YKScheduler();
}
void YKDelayTask(unsigned count){
//If count == 0; return
//Remove TCB from ready queue
//Add TCB to blocking queue with wait count
}
void YKEnterISR(void){
//Increment call depth counter
YKCallDepth++;
}
void YKExitISR(void){
//Decrement call depth counter
//If the call depth is 0, call scheduler
//Return
if((--YKCallDepth) == 0){
YKScheduler();
}
}
void YKScheduler(void){
if(!kernel_running || active_task == ready_task){
return;
}
//YKEnterMutex();//TODO necessary?
YKDispatcher(ready_task);
//YKExitMutex();
return;
//Disable interrupts
//Check ready queue for highest priority task
//Update active TCB pointer
//if it differs from current, call dispatcher
//else, enable interrupts and return
}
/*void YKDispatcher(struct tcb* tcb){
//Restore registers from tcb
//
//
//iret
}*/
void make_ready_task(tcb_t* tcb){
tcb_t* current;
if(tcb->priority < ready_task->priority){
tcb->next = ready_task;
ready_task = tcb;
return;
}
current = ready_task;
// YKEnterMutex();//Necessary?
while(current->next && (current->next->priority < tcb->priority)){
current = current->next;
}
tcb->next = current->next;
current->next = tcb;
// YKExitMutex();//Necessary?
return;
}