summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/export/kernel.h12
-rw-r--r--firmware/kernel.c72
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c12
-rw-r--r--firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c14
-rw-r--r--firmware/target/arm/tcc77x/timer-tcc77x.c14
-rw-r--r--firmware/target/arm/tcc780x/timer-tcc780x.c15
-rw-r--r--firmware/target/arm/tms320dm320/kernel-dm320.c13
-rw-r--r--firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c11
8 files changed, 37 insertions, 126 deletions
diff --git a/firmware/export/kernel.h b/firmware/export/kernel.h
index 51eb635..9438f6d 100644
--- a/firmware/export/kernel.h
+++ b/firmware/export/kernel.h
@@ -207,6 +207,18 @@ int tick_add_task(void (*f)(void));
int tick_remove_task(void (*f)(void));
extern void tick_start(unsigned int interval_in_ms);
+/* inline helper for implementing target interrupt handler */
+static inline void call_tick_tasks(void)
+{
+ extern void (*tick_funcs[MAX_NUM_TICK_TASKS+1])(void);
+ int i;
+
+ current_tick++;
+
+ for (i = 0; tick_funcs[i] != NULL; i++)
+ tick_funcs[i]();
+}
+
struct timeout;
/* timeout callback type
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;
}
diff --git a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c
index e7bce8d..3d7c577 100644
--- a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c
@@ -27,22 +27,12 @@
#include "kernel.h"
#include "thread.h"
-extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
-
static __attribute__((interrupt("IRQ"))) void EPIT1_HANDLER(void)
{
- int i;
-
EPITSR1 = EPITSR_OCIF; /* Clear the pending status */
/* 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();
}
void tick_start(unsigned int interval_in_ms)
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c
index 4f878d4..76917c8 100644
--- a/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c
+++ b/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c
@@ -24,8 +24,6 @@
#include "timer.h"
#include "thread.h"
-extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
-
void tick_start(unsigned int interval_in_ms)
{
/*
@@ -62,18 +60,8 @@ void tick_start(unsigned int interval_in_ms)
void TIMER4(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();
SRCPND = TIMER4_MASK;
INTPND = TIMER4_MASK;
diff --git a/firmware/target/arm/tcc77x/timer-tcc77x.c b/firmware/target/arm/tcc77x/timer-tcc77x.c
index 4645e38..924ddda 100644
--- a/firmware/target/arm/tcc77x/timer-tcc77x.c
+++ b/firmware/target/arm/tcc77x/timer-tcc77x.c
@@ -51,24 +51,12 @@ void __timer_unregister(void)
/* Timer interrupt processing - all timers (inc. tick) have a single IRQ */
-
-extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
-
void TIMER(void)
{
if (TIREQ & TF0) /* Timer0 reached ref value */
{
- 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();
/* reset Timer 0 IRQ & ref flags */
TIREQ |= TI0 | TF0;
diff --git a/firmware/target/arm/tcc780x/timer-tcc780x.c b/firmware/target/arm/tcc780x/timer-tcc780x.c
index c085201..1795613 100644
--- a/firmware/target/arm/tcc780x/timer-tcc780x.c
+++ b/firmware/target/arm/tcc780x/timer-tcc780x.c
@@ -46,25 +46,12 @@ void __timer_unregister(void)
/* Timer interrupt processing - all timers (inc. tick) have a single IRQ */
-
-extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
-
void TIMER0(void)
{
if (TIREQ & TF0) /* Timer0 reached ref value */
{
- 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();
/* reset Timer 0 IRQ & ref flags */
TIREQ |= TI0 | TF0;
diff --git a/firmware/target/arm/tms320dm320/kernel-dm320.c b/firmware/target/arm/tms320dm320/kernel-dm320.c
index 42f9773..b5eb423 100644
--- a/firmware/target/arm/tms320dm320/kernel-dm320.c
+++ b/firmware/target/arm/tms320dm320/kernel-dm320.c
@@ -25,8 +25,6 @@
#include "timer.h"
#include "thread.h"
-extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
-
void tick_start(unsigned int interval_in_ms)
{
/* TODO: set up TIMER1 clock settings
@@ -53,16 +51,7 @@ void tick_start(unsigned int interval_in_ms)
void TIMER1(void)
{
IO_INTC_IRQ0 = INTR_IRQ0_TMR1;
-
- 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();
}
diff --git a/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c b/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c
index 62176ce..dcfdfd6 100644
--- a/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c
@@ -24,8 +24,6 @@
#include "kernel.h"
#include "jz4740.h"
-extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
-
#define USE_RTC_CLOCK 0
void tick_start(unsigned int interval_in_ms)
{
@@ -70,13 +68,6 @@ void TCU0(void)
{
__tcu_clear_full_match_flag(0);
- 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();
}