Change the run_timers execution frequency

We now use the GCD of all the async timers.
async
jeltz 3 years ago
parent a6f60bbf4e
commit 545e31c6f9
Signed by: jeltz
GPG Key ID: 800882B66C0C3326

@ -49,6 +49,8 @@ struct
let fold_lcm l = List.fold_left lcm (List.hd l) (List.tl l) 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 let ms_of_ack = function
| Timer_ms ms -> ms | Timer_ms ms -> ms
@ -58,34 +60,37 @@ struct
let incr = Cbop ("+", Cvar name, one_const) in let incr = Cbop ("+", Cvar name, one_const) in
Caffect (CLvar name, Cbop ("%", incr, modulo_const)) 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 step = (cname_of_qn od.o_class) ^ "_async_step" in
let global = async_global_var_name od in let global = async_global_var_name od in
let call = Csexpr (Cfun_call (step, [Caddrof (Cvar global)])) in let call = Csexpr (Cfun_call (step, [Caddrof (Cvar global)])) in
let zero = Cconst (Ccint 0) 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 let cond = Cbop ("==", Cbop ("%", tick_var, timer), zero) in
Cif (cond, [call], []) Cif (cond, [call], [])
let decls_and_defs objs = let translate_objs objs =
let trans = List.map List.map
(fun od -> (fun od ->
let ack = Option.get od.o_ack in let ack = Option.get od.o_ack in
(od, translate_ack ack)) (od, translate_ack ack))
objs objs
in
let decls_and_defs objs =
let trans = translate_objs objs in
let timers = List.map let timers = List.map
(fun (_, ack) -> match ack with Timer_ms ms -> ms) (fun (_, ack) -> ms_of_ack ack)
trans trans
in in
let body = match timers with let body = match timers with
| [] -> [] | [] -> []
| _ -> | _ ->
let gcd_timer = fold_gcd timers in
let lcm_timer = fold_lcm timers in let lcm_timer = fold_lcm timers in
let steps = let steps =
List.map (call_step_async (Cvar "tick")) trans List.map (call_step_async (Cvar "tick") gcd_timer) trans
in in
let incr = incr_mod "tick" lcm_timer in let incr = incr_mod "tick" (lcm_timer / gcd_timer) in
steps @ [incr] steps @ [incr]
in in
(* run_timers is declared in avr.h (because of the ISR macro which (* run_timers is declared in avr.h (because of the ISR macro which
@ -105,6 +110,16 @@ struct
] in ] in
[], defs [], 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 end

@ -7,5 +7,5 @@ sig
val gen_copy_func_out : class_def -> cdef val gen_copy_func_out : class_def -> cdef
val includes : string list val includes : string list
val decls_and_defs : obj_dec list -> cdecl list * cdef 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 end

@ -418,7 +418,10 @@ let mk_main name p =
* could be triggered while the initial reset of the async nodes is * could be triggered while the initial reset of the async nodes is
* not yet terminated. * 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.c", Csource (defs @ [main_skel var_l res_l step_l]));
("_main.h", Cheader ([name], []))]; ("_main.h", Cheader ([name], []))];

@ -30,6 +30,7 @@
#include <util/atomic.h> #include <util/atomic.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <avr/io.h> #include <avr/io.h>
#include <assert.h>
#include "avr.h" #include "avr.h"
ISR(TIMER1_COMPA_vect) { ISR(TIMER1_COMPA_vect) {
@ -42,9 +43,10 @@ static inline void set_ocr1a(uint16_t value) {
} }
/* Source: https://adnbr.co.uk/articles/counting-milliseconds */ /* 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); TCCR1B |= _BV(WGM12) | _BV(CS11);
set_ocr1a((F_CPU / 1000) / 8); set_ocr1a(((ms * F_CPU) / 1000) / 8);
TIMSK1 |= _BV(OCIE1A); TIMSK1 |= _BV(OCIE1A);
sei(); sei();
} }

@ -39,7 +39,7 @@
void run_timers(); void run_timers();
void init_timer1(); void init_timer1(unsigned int ms);
void atomic_memcpy(void *dest, const void *src, size_t size); void atomic_memcpy(void *dest, const void *src, size_t size);

Loading…
Cancel
Save