Change the run_timers execution frequency
We now use the GCD of all the async timers.
This commit is contained in:
parent
a6f60bbf4e
commit
545e31c6f9
5 changed files with 34 additions and 14 deletions
|
@ -49,6 +49,8 @@ struct
|
|||
|
||||
let fold_lcm l = List.fold_left lcm (List.hd l) (List.tl l)
|
||||
|
||||
let fold_gcd l = List.fold_left gcd (List.hd l) (List.tl l)
|
||||
|
||||
let ms_of_ack = function
|
||||
| Timer_ms ms -> ms
|
||||
|
||||
|
@ -58,34 +60,37 @@ struct
|
|||
let incr = Cbop ("+", Cvar name, one_const) in
|
||||
Caffect (CLvar name, Cbop ("%", incr, modulo_const))
|
||||
|
||||
let call_step_async tick_var (od, ack) =
|
||||
let call_step_async tick_var base (od, ack) =
|
||||
let step = (cname_of_qn od.o_class) ^ "_async_step" in
|
||||
let global = async_global_var_name od in
|
||||
let call = Csexpr (Cfun_call (step, [Caddrof (Cvar global)])) in
|
||||
let zero = Cconst (Ccint 0) in
|
||||
let timer = Cconst (Ccint (ms_of_ack ack)) in
|
||||
let timer = Cconst (Ccint (ms_of_ack ack / base)) in
|
||||
let cond = Cbop ("==", Cbop ("%", tick_var, timer), zero) in
|
||||
Cif (cond, [call], [])
|
||||
|
||||
let decls_and_defs objs =
|
||||
let trans = List.map
|
||||
let translate_objs objs =
|
||||
List.map
|
||||
(fun od ->
|
||||
let ack = Option.get od.o_ack in
|
||||
(od, translate_ack ack))
|
||||
objs
|
||||
in
|
||||
|
||||
let decls_and_defs objs =
|
||||
let trans = translate_objs objs in
|
||||
let timers = List.map
|
||||
(fun (_, ack) -> match ack with Timer_ms ms -> ms)
|
||||
(fun (_, ack) -> ms_of_ack ack)
|
||||
trans
|
||||
in
|
||||
let body = match timers with
|
||||
| [] -> []
|
||||
| _ ->
|
||||
let gcd_timer = fold_gcd timers in
|
||||
let lcm_timer = fold_lcm timers in
|
||||
let steps =
|
||||
List.map (call_step_async (Cvar "tick")) trans
|
||||
List.map (call_step_async (Cvar "tick") gcd_timer) trans
|
||||
in
|
||||
let incr = incr_mod "tick" lcm_timer in
|
||||
let incr = incr_mod "tick" (lcm_timer / gcd_timer) in
|
||||
steps @ [incr]
|
||||
in
|
||||
(* run_timers is declared in avr.h (because of the ISR macro which
|
||||
|
@ -105,6 +110,16 @@ struct
|
|||
] in
|
||||
[], defs
|
||||
|
||||
let main_init = [Csexpr (Cfun_call ("init_timer1", []))]
|
||||
let main_init objs =
|
||||
let trans = translate_objs objs in
|
||||
let timers = List.map
|
||||
(fun (_, ack) -> ms_of_ack ack)
|
||||
trans
|
||||
in
|
||||
match timers with
|
||||
| [] -> []
|
||||
| _ ->
|
||||
let value = fold_gcd timers in
|
||||
[Csexpr (Cfun_call ("init_timer1", [Cconst (Ccint value)]))]
|
||||
|
||||
end
|
||||
|
|
|
@ -7,5 +7,5 @@ sig
|
|||
val gen_copy_func_out : class_def -> cdef
|
||||
val includes : string list
|
||||
val decls_and_defs : obj_dec list -> cdecl list * cdef list
|
||||
val main_init : cstm list
|
||||
val main_init : obj_dec list -> cstm list
|
||||
end
|
||||
|
|
|
@ -418,7 +418,10 @@ let mk_main name p =
|
|||
* could be triggered while the initial reset of the async nodes is
|
||||
* not yet terminated.
|
||||
*)
|
||||
let res_l = res_l @ AvrBackend.main_init in
|
||||
let async_objs = List.flatten
|
||||
(List.map filter_async_objs classes)
|
||||
in
|
||||
let res_l = res_l @ AvrBackend.main_init async_objs in
|
||||
|
||||
[("_main.c", Csource (defs @ [main_skel var_l res_l step_l]));
|
||||
("_main.h", Cheader ([name], []))];
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <util/atomic.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
#include <assert.h>
|
||||
#include "avr.h"
|
||||
|
||||
ISR(TIMER1_COMPA_vect) {
|
||||
|
@ -42,9 +43,10 @@ static inline void set_ocr1a(uint16_t value) {
|
|||
}
|
||||
|
||||
/* Source: https://adnbr.co.uk/articles/counting-milliseconds */
|
||||
void init_timer1() {
|
||||
void init_timer1(unsigned int ms) {
|
||||
assert(ms < 1000);
|
||||
TCCR1B |= _BV(WGM12) | _BV(CS11);
|
||||
set_ocr1a((F_CPU / 1000) / 8);
|
||||
set_ocr1a(((ms * F_CPU) / 1000) / 8);
|
||||
TIMSK1 |= _BV(OCIE1A);
|
||||
sei();
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
void run_timers();
|
||||
|
||||
void init_timer1();
|
||||
void init_timer1(unsigned int ms);
|
||||
|
||||
void atomic_memcpy(void *dest, const void *src, size_t size);
|
||||
|
||||
|
|
Loading…
Reference in a new issue