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 fb9c5e2..70b3e03 100644
--- a/firmware/kernel.c
+++ b/firmware/kernel.c
@@ -54,7 +54,9 @@
volatile long current_tick SHAREDDATA_ATTR = 0;
#endif
-void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
+/* List of tick tasks - final element always NULL for termination */
+void (*tick_funcs[MAX_NUM_TICK_TASKS+1])(void);
+static int num_tick_funcs = 0;
extern struct core_entry cores[NUM_CORES];
@@ -128,18 +130,8 @@ void tick_start(unsigned int interval_in_ms)
void IMIA0(void) __attribute__ ((interrupt_handler));
void IMIA0(void)
{
- int i;
-
/* Run through the list of tick tasks */
- for(i = 0;i < MAX_NUM_TICK_TASKS;i++)
- {
- if(tick_funcs[i])
- {
- tick_funcs[i]();
- }
- }
-
- current_tick++;
+ call_tick_tasks();
TSR0 &= ~0x01;
}
@@ -178,18 +170,8 @@ void tick_start(unsigned int interval_in_ms)
void TIMER0(void) __attribute__ ((interrupt_handler));
void TIMER0(void)
{
- int i;
-
/* Run through the list of tick tasks */
- for(i = 0;i < MAX_NUM_TICK_TASKS;i++)
- {
- if(tick_funcs[i])
- {
- tick_funcs[i]();
- }
- }
-
- current_tick++;
+ call_tick_tasks();
TER0 = 0xff; /* Clear all events */
}
@@ -199,27 +181,17 @@ void TIMER0(void)
#ifndef BOOTLOADER
void TIMER1(void)
{
- int i;
-
/* Run through the list of tick tasks (using main core) */
TIMER1_VAL; /* Read value to ack IRQ */
/* Run through the list of tick tasks using main CPU core -
wake up the COP through its control interface to provide pulse */
- for (i = 0;i < MAX_NUM_TICK_TASKS;i++)
- {
- if (tick_funcs[i])
- {
- tick_funcs[i]();
- }
- }
+ call_tick_tasks();
#if NUM_CORES > 1
/* Pulse the COP */
core_wake(COP);
#endif /* NUM_CORES */
-
- current_tick++;
}
#endif
@@ -243,16 +215,8 @@ void tick_start(unsigned int interval_in_ms)
void timer_handler(void)
{
- int i;
-
/* Run through the list of tick tasks */
- for(i = 0;i < MAX_NUM_TICK_TASKS;i++)
- {
- if(tick_funcs[i])
- tick_funcs[i]();
- }
-
- current_tick++;
+ call_tick_tasks();
TIMER0.clr = 0;
}
@@ -274,19 +238,16 @@ void tick_start(unsigned int interval_in_ms)
int tick_add_task(void (*f)(void))
{
- int i;
int oldlevel = disable_irq_save();
/* Add a task if there is room */
- for(i = 0;i < MAX_NUM_TICK_TASKS;i++)
+ if(num_tick_funcs < MAX_NUM_TICK_TASKS)
{
- if(tick_funcs[i] == NULL)
- {
- tick_funcs[i] = f;
- restore_irq(oldlevel);
- return 0;
- }
+ tick_funcs[num_tick_funcs++] = f;
+ restore_irq(oldlevel);
+ return 0;
}
+
restore_irq(oldlevel);
panicf("Error! tick_add_task(): out of tasks");
return -1;
@@ -298,11 +259,16 @@ int tick_remove_task(void (*f)(void))
int oldlevel = disable_irq_save();
/* Remove a task if it is there */
- for(i = 0;i < MAX_NUM_TICK_TASKS;i++)
+ for(i = 0;i < num_tick_funcs;i++)
{
if(tick_funcs[i] == f)
{
- tick_funcs[i] = NULL;
+ /* Compact function list - propagates NULL-terminator as well */
+ for(; i < num_tick_funcs; i++)
+ tick_funcs[i] = tick_funcs[i+1];
+
+ num_tick_funcs--;
+
restore_irq(oldlevel);
return 0;
}