sched: Don't count milliseconds in the periodic timer
It's not necessary to keep a millisecond counter. Replace the two users of sched_check_periodic() with explicit task wakeup flags. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
88a10fb31c
commit
62f77f6bc5
|
@ -18,6 +18,8 @@ struct analog_in {
|
||||||
uint8_t state, sample_count;
|
uint8_t state, sample_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct task_wake analog_wake;
|
||||||
|
|
||||||
static uint_fast8_t
|
static uint_fast8_t
|
||||||
analog_in_event(struct timer *timer)
|
analog_in_event(struct timer *timer)
|
||||||
{
|
{
|
||||||
|
@ -42,6 +44,7 @@ analog_in_event(struct timer *timer)
|
||||||
}
|
}
|
||||||
if (a->value < a->min_value || a->value > a->max_value)
|
if (a->value < a->min_value || a->value > a->max_value)
|
||||||
shutdown("adc out of range");
|
shutdown("adc out of range");
|
||||||
|
sched_wake_task(&analog_wake);
|
||||||
a->next_begin_time += a->rest_time;
|
a->next_begin_time += a->rest_time;
|
||||||
a->timer.waketime = a->next_begin_time;
|
a->timer.waketime = a->next_begin_time;
|
||||||
return SF_RESCHEDULE;
|
return SF_RESCHEDULE;
|
||||||
|
@ -83,8 +86,7 @@ DECL_COMMAND(command_query_analog_in,
|
||||||
void
|
void
|
||||||
analog_in_task(void)
|
analog_in_task(void)
|
||||||
{
|
{
|
||||||
static uint16_t next;
|
if (!sched_check_wake(&analog_wake))
|
||||||
if (!sched_check_periodic(3, &next))
|
|
||||||
return;
|
return;
|
||||||
uint8_t oid;
|
uint8_t oid;
|
||||||
struct analog_in *a;
|
struct analog_in *a;
|
||||||
|
|
|
@ -21,6 +21,8 @@ struct end_stop {
|
||||||
|
|
||||||
enum { ESF_PIN_HIGH=1<<0, ESF_HOMING=1<<1, ESF_REPORT=1<<2 };
|
enum { ESF_PIN_HIGH=1<<0, ESF_HOMING=1<<1, ESF_REPORT=1<<2 };
|
||||||
|
|
||||||
|
static struct task_wake endstop_wake;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
stop_steppers(struct end_stop *e)
|
stop_steppers(struct end_stop *e)
|
||||||
{
|
{
|
||||||
|
@ -29,6 +31,7 @@ stop_steppers(struct end_stop *e)
|
||||||
while (count--)
|
while (count--)
|
||||||
if (e->steppers[count])
|
if (e->steppers[count])
|
||||||
stepper_stop(e->steppers[count]);
|
stepper_stop(e->steppers[count]);
|
||||||
|
sched_wake_task(&endstop_wake);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timer callback for an end stop
|
// Timer callback for an end stop
|
||||||
|
@ -115,8 +118,7 @@ DECL_COMMAND(command_end_stop_query, "end_stop_query oid=%c");
|
||||||
void
|
void
|
||||||
end_stop_task(void)
|
end_stop_task(void)
|
||||||
{
|
{
|
||||||
static uint16_t next;
|
if (!sched_check_wake(&endstop_wake))
|
||||||
if (!sched_check_periodic(50, &next))
|
|
||||||
return;
|
return;
|
||||||
uint8_t oid;
|
uint8_t oid;
|
||||||
struct end_stop *e;
|
struct end_stop *e;
|
||||||
|
|
70
src/sched.c
70
src/sched.c
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <setjmp.h> // setjmp
|
#include <setjmp.h> // setjmp
|
||||||
#include "autoconf.h" // CONFIG_*
|
#include "autoconf.h" // CONFIG_*
|
||||||
|
#include "board/io.h" // readb
|
||||||
#include "board/irq.h" // irq_save
|
#include "board/irq.h" // irq_save
|
||||||
#include "board/misc.h" // timer_from_us
|
#include "board/misc.h" // timer_from_us
|
||||||
#include "board/pgm.h" // READP
|
#include "board/pgm.h" // READP
|
||||||
|
@ -18,48 +19,31 @@
|
||||||
* Timers
|
* Timers
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
|
|
||||||
static uint16_t millis;
|
static struct timer periodic_timer, *timer_list = &periodic_timer;
|
||||||
|
static struct timer sentinel_timer;
|
||||||
|
|
||||||
// Check if ready for a recurring periodic event
|
// The periodic_timer simplifies the timer code by ensuring there is
|
||||||
uint8_t
|
// always a timer on the timer list and that there is always a timer
|
||||||
sched_check_periodic(uint16_t time, uint16_t *pnext)
|
// not more than 1ms in the future.
|
||||||
{
|
|
||||||
uint16_t next = *pnext, cur;
|
|
||||||
irqstatus_t flag = irq_save();
|
|
||||||
cur = millis;
|
|
||||||
irq_restore(flag);
|
|
||||||
if ((int16_t)(cur - next) < 0)
|
|
||||||
return 0;
|
|
||||||
*pnext = cur + time;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct timer ms_timer, sentinel_timer, *timer_list = &ms_timer;
|
|
||||||
|
|
||||||
// Default millisecond timer. This timer counts milliseconds. It
|
|
||||||
// also simplifies the timer code by ensuring there is always a timer
|
|
||||||
// on the timer list and that there is always a timer not more than
|
|
||||||
// 1ms in the future.
|
|
||||||
static uint_fast8_t
|
static uint_fast8_t
|
||||||
ms_event(struct timer *t)
|
periodic_event(struct timer *t)
|
||||||
{
|
{
|
||||||
millis++;
|
|
||||||
timer_periodic();
|
timer_periodic();
|
||||||
ms_timer.waketime += timer_from_us(1000);
|
periodic_timer.waketime += timer_from_us(1000);
|
||||||
sentinel_timer.waketime = ms_timer.waketime + 0x80000000;
|
sentinel_timer.waketime = periodic_timer.waketime + 0x80000000;
|
||||||
return SF_RESCHEDULE;
|
return SF_RESCHEDULE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct timer ms_timer = {
|
static struct timer periodic_timer = {
|
||||||
.func = ms_event,
|
.func = periodic_event,
|
||||||
.next = &sentinel_timer,
|
.next = &sentinel_timer,
|
||||||
};
|
};
|
||||||
|
|
||||||
// The sentinel timer is always the last timer on timer_list - its
|
// The sentinel timer is always the last timer on timer_list - its
|
||||||
// presence allows the code to avoid checking for NULL while
|
// presence allows the code to avoid checking for NULL while
|
||||||
// traversing timer_list. Since sentinel_timer.waketime is always
|
// traversing timer_list. Since sentinel_timer.waketime is always
|
||||||
// equal to (ms_timer.waketime + 0x80000000) any added timer must
|
// equal to (periodic_timer.waketime + 0x80000000) any added timer
|
||||||
// always have a waketime less than one of these two timers.
|
// must always have a waketime less than one of these two timers.
|
||||||
static uint_fast8_t
|
static uint_fast8_t
|
||||||
sentinel_event(struct timer *t)
|
sentinel_event(struct timer *t)
|
||||||
{
|
{
|
||||||
|
@ -171,13 +155,35 @@ void
|
||||||
sched_timer_shutdown(void)
|
sched_timer_shutdown(void)
|
||||||
{
|
{
|
||||||
timer_list = &deleted_timer;
|
timer_list = &deleted_timer;
|
||||||
deleted_timer.waketime = ms_timer.waketime;
|
deleted_timer.waketime = periodic_timer.waketime;
|
||||||
deleted_timer.next = &ms_timer;
|
deleted_timer.next = &periodic_timer;
|
||||||
ms_timer.next = &sentinel_timer;
|
periodic_timer.next = &sentinel_timer;
|
||||||
}
|
}
|
||||||
DECL_SHUTDOWN(sched_timer_shutdown);
|
DECL_SHUTDOWN(sched_timer_shutdown);
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Task waking
|
||||||
|
****************************************************************/
|
||||||
|
|
||||||
|
// Note that a task is ready to run
|
||||||
|
void
|
||||||
|
sched_wake_task(struct task_wake *w)
|
||||||
|
{
|
||||||
|
writeb(&w->wake, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a task is ready to run (as indicated by sched_wake_task)
|
||||||
|
uint8_t
|
||||||
|
sched_check_wake(struct task_wake *w)
|
||||||
|
{
|
||||||
|
if (!readb(&w->wake))
|
||||||
|
return 0;
|
||||||
|
writeb(&w->wake, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
* Shutdown processing
|
* Shutdown processing
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
|
|
|
@ -20,11 +20,17 @@ struct timer {
|
||||||
|
|
||||||
enum { SF_DONE=0, SF_RESCHEDULE=1 };
|
enum { SF_DONE=0, SF_RESCHEDULE=1 };
|
||||||
|
|
||||||
|
// Task waking struct
|
||||||
|
struct task_wake {
|
||||||
|
uint8_t wake;
|
||||||
|
};
|
||||||
|
|
||||||
// sched.c
|
// sched.c
|
||||||
uint8_t sched_check_periodic(uint16_t time, uint16_t *pnext);
|
|
||||||
void sched_add_timer(struct timer*);
|
void sched_add_timer(struct timer*);
|
||||||
void sched_del_timer(struct timer *del);
|
void sched_del_timer(struct timer *del);
|
||||||
unsigned int sched_timer_dispatch(void);
|
unsigned int sched_timer_dispatch(void);
|
||||||
|
void sched_wake_task(struct task_wake *w);
|
||||||
|
uint8_t sched_check_wake(struct task_wake *w);
|
||||||
uint8_t sched_is_shutdown(void);
|
uint8_t sched_is_shutdown(void);
|
||||||
void sched_clear_shutdown(void);
|
void sched_clear_shutdown(void);
|
||||||
void sched_try_shutdown(uint_fast8_t reason);
|
void sched_try_shutdown(uint_fast8_t reason);
|
||||||
|
|
Loading…
Reference in New Issue