diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/export/timer.h | 5 | ||||
-rw-r--r-- | firmware/target/hosted/kernel-unix.c | 16 | ||||
-rw-r--r-- | firmware/timer.c | 4 |
3 files changed, 21 insertions, 4 deletions
diff --git a/firmware/export/timer.h b/firmware/export/timer.h index b12ec55881..92b26db216 100644 --- a/firmware/export/timer.h +++ b/firmware/export/timer.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #define TIMER_FREQ 1000000 | 30 | #define TIMER_FREQ 1000000 |
31 | #endif | 31 | #endif |
32 | 32 | ||
33 | /* NOTE: if unreg cb is defined you are in charge of calling timer_unregister() */ | ||
33 | bool timer_register(int reg_prio, void (*unregister_callback)(void), | 34 | bool timer_register(int reg_prio, void (*unregister_callback)(void), |
34 | long cycles, void (*timer_callback)(void) | 35 | long cycles, void (*timer_callback)(void) |
35 | IF_COP(,int core)); | 36 | IF_COP(,int core)); |
@@ -37,6 +38,10 @@ bool timer_set_period(long cycles); | |||
37 | #ifdef CPU_COLDFIRE | 38 | #ifdef CPU_COLDFIRE |
38 | void timers_adjust_prescale(int multiplier, bool enable_irq); | 39 | void timers_adjust_prescale(int multiplier, bool enable_irq); |
39 | #endif | 40 | #endif |
41 | |||
42 | /* NOTE: unregister callbacks are not called by timer_unregister() | ||
43 | * the unregister_callback only gets called when your timer gets | ||
44 | * overwritten by a lower priority timer using timer_register() */ | ||
40 | void timer_unregister(void); | 45 | void timer_unregister(void); |
41 | 46 | ||
42 | /* target-specific interface */ | 47 | /* target-specific interface */ |
diff --git a/firmware/target/hosted/kernel-unix.c b/firmware/target/hosted/kernel-unix.c index e3c492a8cc..ed1f83cd8c 100644 --- a/firmware/target/hosted/kernel-unix.c +++ b/firmware/target/hosted/kernel-unix.c | |||
@@ -113,8 +113,8 @@ void (*global_timer_callback)(void); | |||
113 | 113 | ||
114 | static void timer_cb(union sigval arg) | 114 | static void timer_cb(union sigval arg) |
115 | { | 115 | { |
116 | (void)arg; | 116 | /* check for spurious callbacks [arg.sival_ptr] */ |
117 | if (global_timer_callback) | 117 | if (global_timer_callback && global_timer_callback == arg.sival_ptr) |
118 | global_timer_callback(); | 118 | global_timer_callback(); |
119 | } | 119 | } |
120 | 120 | ||
@@ -129,12 +129,18 @@ bool timer_register(int reg_prio, void (*unregister_callback)(void), | |||
129 | if (reg_prio <= timer_prio || in_us <= 0) | 129 | if (reg_prio <= timer_prio || in_us <= 0) |
130 | return false; | 130 | return false; |
131 | 131 | ||
132 | if (timer_prio >= 0 && global_unreg_callback) | 132 | if(timer_prio >= 0) |
133 | global_unreg_callback(); | 133 | { |
134 | if (global_unreg_callback) /* timer has callback user needs to unreg */ | ||
135 | global_unreg_callback(); | ||
136 | else /* no callback -- delete timer */ | ||
137 | timer_delete(timer_tid); | ||
138 | } | ||
134 | 139 | ||
135 | memset(&sigev, 0, sizeof(sigevent_t)); | 140 | memset(&sigev, 0, sizeof(sigevent_t)); |
136 | sigev.sigev_notify = SIGEV_THREAD, | 141 | sigev.sigev_notify = SIGEV_THREAD, |
137 | sigev.sigev_notify_function = timer_cb; | 142 | sigev.sigev_notify_function = timer_cb; |
143 | sigev.sigev_value.sival_ptr = timer_callback; /* store cb to check later */ | ||
138 | 144 | ||
139 | div_t q = div(in_us, 1000000); | 145 | div_t q = div(in_us, 1000000); |
140 | ts.it_value.tv_sec = ts.it_interval.tv_sec = q.quot; | 146 | ts.it_value.tv_sec = ts.it_interval.tv_sec = q.quot; |
@@ -166,4 +172,6 @@ void timer_unregister(void) | |||
166 | { | 172 | { |
167 | timer_delete(timer_tid); | 173 | timer_delete(timer_tid); |
168 | timer_prio = -1; | 174 | timer_prio = -1; |
175 | global_unreg_callback = NULL; | ||
176 | global_timer_callback = NULL; | ||
169 | } | 177 | } |
diff --git a/firmware/timer.c b/firmware/timer.c index a923290a94..c618f72e02 100644 --- a/firmware/timer.c +++ b/firmware/timer.c | |||
@@ -42,6 +42,7 @@ bool timer_register(int reg_prio, void (*unregister_callback)(void), | |||
42 | return false; | 42 | return false; |
43 | 43 | ||
44 | pfn_timer = timer_callback; | 44 | pfn_timer = timer_callback; |
45 | /* NOTE: if unreg cb is defined you are in charge of calling timer_unregister() */ | ||
45 | pfn_unregister = unregister_callback; | 46 | pfn_unregister = unregister_callback; |
46 | timer_prio = reg_prio; | 47 | timer_prio = reg_prio; |
47 | 48 | ||
@@ -53,6 +54,9 @@ bool timer_set_period(long cycles) | |||
53 | return timer_set(cycles, false); | 54 | return timer_set(cycles, false); |
54 | } | 55 | } |
55 | 56 | ||
57 | /* NOTE: unregister callbacks are not called by timer_unregister() | ||
58 | * the unregister_callback only gets called when your timer gets | ||
59 | * overwritten by a lower priority timer using timer_register() */ | ||
56 | void timer_unregister(void) | 60 | void timer_unregister(void) |
57 | { | 61 | { |
58 | timer_stop(); | 62 | timer_stop(); |