Rev 513 | Rev 521 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
490 | giacomo | 1 | #include <kernel/int_sem.h> |
2 | #include <stdlib.h> |
||
496 | giacomo | 3 | #include <kernel/func.h> |
4 | #include <ll/sys/ll/event.h> |
||
490 | giacomo | 5 | |
513 | giacomo | 6 | PID intr_server = NIL; |
7 | |||
8 | #define MAX_INT_LIST 50 |
||
9 | |||
514 | giacomo | 10 | /* 1-15 for IRQ and 16-63 for timers */ |
513 | giacomo | 11 | |
514 | giacomo | 12 | void *int_arg_table[64]; |
13 | void *int_func_table[64]; |
||
14 | int timer_table[64]; |
||
15 | |||
513 | giacomo | 16 | int int_list[MAX_INT_LIST]; |
17 | int next_free_int = 0; |
||
18 | int next_execute_int = 0; |
||
19 | |||
20 | /* FIFO add job */ |
||
21 | int add_interrupt_job(int no) |
||
22 | { |
||
23 | |||
24 | int_list[next_free_int] = no; |
||
25 | next_free_int++; |
||
26 | |||
27 | if (next_free_int == MAX_INT_LIST) next_free_int = 0; |
||
28 | if (next_free_int == next_execute_int) { |
||
29 | next_free_int--; |
||
30 | return -1; |
||
31 | } |
||
32 | |||
33 | return 0; |
||
34 | |||
35 | } |
||
36 | |||
37 | /* FIFO get job */ |
||
38 | int get_interrupt_job() |
||
39 | { |
||
40 | |||
41 | int res = -1; |
||
42 | |||
43 | if (next_free_int != next_execute_int) { |
||
44 | res = int_list[next_execute_int]; |
||
45 | next_execute_int++; |
||
46 | if (next_execute_int == MAX_INT_LIST) next_execute_int = 0; |
||
47 | } |
||
48 | |||
49 | return res; |
||
50 | |||
51 | } |
||
52 | |||
514 | giacomo | 53 | int get_free_timer_slot() |
54 | { |
||
55 | |||
56 | int i = 16; |
||
57 | |||
58 | while(timer_table[i] != -1) |
||
59 | if (i < 64) i++; else return -1; |
||
60 | |||
61 | return i; |
||
62 | |||
63 | } |
||
64 | |||
513 | giacomo | 65 | extern void linux_intr(int no); |
514 | giacomo | 66 | extern void linux_timer(int no); |
513 | giacomo | 67 | |
514 | giacomo | 68 | |
69 | /* The Interrupt TASK is an aperiodic task designed for |
||
70 | the INTDRIVE module. */ |
||
71 | |||
513 | giacomo | 72 | TASK Interrupt_Server(void *arg) |
73 | { |
||
74 | |||
75 | int no; |
||
76 | |||
77 | while(1) { |
||
78 | |||
79 | no = get_interrupt_job(); |
||
80 | |||
514 | giacomo | 81 | if (no != -1 && no < 16) |
82 | linux_intr(no); |
||
83 | |||
84 | if (no != -1 && no >= 16) { |
||
85 | linux_timer(no); |
||
86 | timer_table[no] = -1; |
||
87 | int_func_table[no] = NULL; |
||
88 | int_arg_table[no] = NULL; |
||
89 | } |
||
90 | |||
513 | giacomo | 91 | task_endcycle(); |
92 | |||
93 | } |
||
94 | |||
95 | } |
||
96 | |||
97 | int shark_interrupt_server() { |
||
98 | |||
99 | HARD_TASK_MODEL ht; |
||
100 | int i; |
||
101 | |||
514 | giacomo | 102 | for(i=0;i<64;i++) { |
513 | giacomo | 103 | int_arg_table[i] = NULL; |
104 | int_func_table[i] = NULL; |
||
514 | giacomo | 105 | timer_table[i] = -1; |
513 | giacomo | 106 | } |
107 | |||
514 | giacomo | 108 | |
513 | giacomo | 109 | hard_task_default_model(ht); |
110 | hard_task_def_wcet(ht,10000); |
||
111 | hard_task_def_interrupt(ht); |
||
112 | |||
113 | intr_server = task_create("Interrupt Server",Interrupt_Server,&ht,NULL); |
||
514 | giacomo | 114 | if (intr_server == NIL) |
513 | giacomo | 115 | return -1; |
116 | |||
514 | giacomo | 117 | return 0; |
118 | |||
513 | giacomo | 119 | } |
120 | |||
490 | giacomo | 121 | void shark_internal_sem_create(void **sem, int init) { |
496 | giacomo | 122 | *sem = (void *)malloc(sizeof(internal_sem_t)); |
123 | internal_sem_init((internal_sem_t *)(*sem),init); |
||
490 | giacomo | 124 | } |
125 | |||
126 | void shark_internal_sem_wait(void *sem) { |
||
496 | giacomo | 127 | internal_sem_wait((internal_sem_t *)(sem)); |
128 | } |
||
490 | giacomo | 129 | |
496 | giacomo | 130 | void shark_internal_sem_post(void *sem) { |
131 | internal_sem_post((internal_sem_t *)(sem)); |
||
132 | } |
||
490 | giacomo | 133 | |
514 | giacomo | 134 | /* Timers */ |
135 | |||
136 | void fast_call_timer(void *arg) |
||
496 | giacomo | 137 | { |
514 | giacomo | 138 | |
139 | int no = (int)arg,res; |
||
140 | |||
141 | res = add_interrupt_job(no); |
||
142 | if (intr_server != NIL && res == 0) |
||
143 | task_activate(intr_server); |
||
144 | |||
490 | giacomo | 145 | } |
146 | |||
514 | giacomo | 147 | int shark_timer_set(const struct timespec *time, void *handler, void *arg) |
496 | giacomo | 148 | { |
514 | giacomo | 149 | SYS_FLAGS f; |
150 | int i; |
||
151 | |||
152 | f = kern_fsave(); |
||
153 | |||
154 | i = get_free_timer_slot(); |
||
155 | |||
156 | if (i == -1) { |
||
157 | kern_frestore(f); |
||
158 | return -1; |
||
159 | } |
||
160 | |||
161 | int_func_table[i] = handler; |
||
162 | int_arg_table[i] = arg; |
||
163 | |||
164 | timer_table[i] = kern_event_post(time,fast_call_timer,(void *)(i)); |
||
165 | |||
166 | if (timer_table[i] == -1) { |
||
167 | kern_frestore(f); |
||
168 | return -1; |
||
169 | } |
||
170 | |||
171 | kern_frestore(f); |
||
172 | |||
173 | return i; |
||
496 | giacomo | 174 | } |
490 | giacomo | 175 | |
514 | giacomo | 176 | int shark_timer_delete(int index) |
513 | giacomo | 177 | { |
178 | |||
514 | giacomo | 179 | SYS_FLAGS f; |
180 | |||
181 | f = kern_fsave(); |
||
182 | |||
183 | if (timer_table[index] != -1) { |
||
184 | |||
185 | int_func_table[index] = NULL; |
||
186 | int_arg_table[index] = NULL; |
||
187 | |||
188 | kern_event_delete(timer_table[index]); |
||
189 | |||
190 | timer_table[index] = -1; |
||
191 | |||
192 | } |
||
193 | |||
194 | kern_frestore(f); |
||
195 | |||
196 | return 0; |
||
197 | |||
198 | } |
||
199 | |||
200 | /* Interrupt */ |
||
201 | |||
202 | void fast_call_intr(int no) |
||
203 | { |
||
204 | |||
513 | giacomo | 205 | int res; |
206 | |||
207 | res = add_interrupt_job(no); |
||
208 | if (intr_server != NIL && res == 0) |
||
209 | task_activate(intr_server); |
||
210 | |||
496 | giacomo | 211 | } |
490 | giacomo | 212 | |
513 | giacomo | 213 | int shark_handler_set(int no, void *fast, void *arg){ |
214 | |||
514 | giacomo | 215 | if (no >= 1 && no < 16 && int_func_table[no] == NULL) { |
513 | giacomo | 216 | int_arg_table[no] = arg; |
217 | int_func_table[no] = fast; |
||
514 | giacomo | 218 | return handler_set(no, fast_call_intr, NIL, TRUE); |
513 | giacomo | 219 | } else { |
220 | return -1; |
||
221 | } |
||
222 | |||
223 | } |
||
224 | |||
496 | giacomo | 225 | int shark_handler_remove(int no){ |
514 | giacomo | 226 | |
227 | int_func_table[no] = NULL; |
||
228 | int_arg_table[no] = NULL; |
||
229 | handler_remove(no); |
||
230 | return 0; |
||
231 | |||
490 | giacomo | 232 | } |
496 | giacomo | 233 |