summaryrefslogtreecommitdiff
path: root/firmware/kernel.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/kernel.c')
-rw-r--r--firmware/kernel.c72
1 files changed, 19 insertions, 53 deletions
diff --git a/firmware/kernel.c b/firmware/kernel.c
index fb9c5e2449..70b3e03615 100644
--- a/firmware/kernel.c
+++ b/firmware/kernel.c
@@ -54,7 +54,9 @@
54volatile long current_tick SHAREDDATA_ATTR = 0; 54volatile long current_tick SHAREDDATA_ATTR = 0;
55#endif 55#endif
56 56
57void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); 57/* List of tick tasks - final element always NULL for termination */
58void (*tick_funcs[MAX_NUM_TICK_TASKS+1])(void);
59static int num_tick_funcs = 0;
58 60
59extern struct core_entry cores[NUM_CORES]; 61extern struct core_entry cores[NUM_CORES];
60 62
@@ -128,18 +130,8 @@ void tick_start(unsigned int interval_in_ms)
128void IMIA0(void) __attribute__ ((interrupt_handler)); 130void IMIA0(void) __attribute__ ((interrupt_handler));
129void IMIA0(void) 131void IMIA0(void)
130{ 132{
131 int i;
132
133 /* Run through the list of tick tasks */ 133 /* Run through the list of tick tasks */
134 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 134 call_tick_tasks();
135 {
136 if(tick_funcs[i])
137 {
138 tick_funcs[i]();
139 }
140 }
141
142 current_tick++;
143 135
144 TSR0 &= ~0x01; 136 TSR0 &= ~0x01;
145} 137}
@@ -178,18 +170,8 @@ void tick_start(unsigned int interval_in_ms)
178void TIMER0(void) __attribute__ ((interrupt_handler)); 170void TIMER0(void) __attribute__ ((interrupt_handler));
179void TIMER0(void) 171void TIMER0(void)
180{ 172{
181 int i;
182
183 /* Run through the list of tick tasks */ 173 /* Run through the list of tick tasks */
184 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 174 call_tick_tasks();
185 {
186 if(tick_funcs[i])
187 {
188 tick_funcs[i]();
189 }
190 }
191
192 current_tick++;
193 175
194 TER0 = 0xff; /* Clear all events */ 176 TER0 = 0xff; /* Clear all events */
195} 177}
@@ -199,27 +181,17 @@ void TIMER0(void)
199#ifndef BOOTLOADER 181#ifndef BOOTLOADER
200void TIMER1(void) 182void TIMER1(void)
201{ 183{
202 int i;
203
204 /* Run through the list of tick tasks (using main core) */ 184 /* Run through the list of tick tasks (using main core) */
205 TIMER1_VAL; /* Read value to ack IRQ */ 185 TIMER1_VAL; /* Read value to ack IRQ */
206 186
207 /* Run through the list of tick tasks using main CPU core - 187 /* Run through the list of tick tasks using main CPU core -
208 wake up the COP through its control interface to provide pulse */ 188 wake up the COP through its control interface to provide pulse */
209 for (i = 0;i < MAX_NUM_TICK_TASKS;i++) 189 call_tick_tasks();
210 {
211 if (tick_funcs[i])
212 {
213 tick_funcs[i]();
214 }
215 }
216 190
217#if NUM_CORES > 1 191#if NUM_CORES > 1
218 /* Pulse the COP */ 192 /* Pulse the COP */
219 core_wake(COP); 193 core_wake(COP);
220#endif /* NUM_CORES */ 194#endif /* NUM_CORES */
221
222 current_tick++;
223} 195}
224#endif 196#endif
225 197
@@ -243,16 +215,8 @@ void tick_start(unsigned int interval_in_ms)
243 215
244void timer_handler(void) 216void timer_handler(void)
245{ 217{
246 int i;
247
248 /* Run through the list of tick tasks */ 218 /* Run through the list of tick tasks */
249 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 219 call_tick_tasks();
250 {
251 if(tick_funcs[i])
252 tick_funcs[i]();
253 }
254
255 current_tick++;
256 220
257 TIMER0.clr = 0; 221 TIMER0.clr = 0;
258} 222}
@@ -274,19 +238,16 @@ void tick_start(unsigned int interval_in_ms)
274 238
275int tick_add_task(void (*f)(void)) 239int tick_add_task(void (*f)(void))
276{ 240{
277 int i;
278 int oldlevel = disable_irq_save(); 241 int oldlevel = disable_irq_save();
279 242
280 /* Add a task if there is room */ 243 /* Add a task if there is room */
281 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 244 if(num_tick_funcs < MAX_NUM_TICK_TASKS)
282 { 245 {
283 if(tick_funcs[i] == NULL) 246 tick_funcs[num_tick_funcs++] = f;
284 { 247 restore_irq(oldlevel);
285 tick_funcs[i] = f; 248 return 0;
286 restore_irq(oldlevel);
287 return 0;
288 }
289 } 249 }
250
290 restore_irq(oldlevel); 251 restore_irq(oldlevel);
291 panicf("Error! tick_add_task(): out of tasks"); 252 panicf("Error! tick_add_task(): out of tasks");
292 return -1; 253 return -1;
@@ -298,11 +259,16 @@ int tick_remove_task(void (*f)(void))
298 int oldlevel = disable_irq_save(); 259 int oldlevel = disable_irq_save();
299 260
300 /* Remove a task if it is there */ 261 /* Remove a task if it is there */
301 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 262 for(i = 0;i < num_tick_funcs;i++)
302 { 263 {
303 if(tick_funcs[i] == f) 264 if(tick_funcs[i] == f)
304 { 265 {
305 tick_funcs[i] = NULL; 266 /* Compact function list - propagates NULL-terminator as well */
267 for(; i < num_tick_funcs; i++)
268 tick_funcs[i] = tick_funcs[i+1];
269
270 num_tick_funcs--;
271
306 restore_irq(oldlevel); 272 restore_irq(oldlevel);
307 return 0; 273 return 0;
308 } 274 }