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