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