From 153920a334bd9dfb6a51f129caee42dde31df508 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Wed, 9 May 2012 15:39:47 +0000 Subject: proper priorities --- kernel/dmx.c | 16 ++++++++-------- kernel/kernel.c | 34 +++++++++++++++++++--------------- kernel/kernel.h | 6 +++--- 3 files changed, 30 insertions(+), 26 deletions(-) (limited to 'kernel') diff --git a/kernel/dmx.c b/kernel/dmx.c index 73ee9a3..97f3731 100644 --- a/kernel/dmx.c +++ b/kernel/dmx.c @@ -34,17 +34,17 @@ struct pwmarg pwmargs[] = { int main() { - init(nPrio, nSema, BIGSTACK); + init(nSema, BIGSTACK); uart_init(); lcd_init(); - exec(heartbeat, NULL, DEFSTACK); - exec(rgb, &rgbargs, BIGSTACK); - exec(pwm, &pwmargs[0], DEFSTACK); - exec(pwm, &pwmargs[1], DEFSTACK); - exec(pwm, &pwmargs[2], DEFSTACK); - exec(adc, &adcarg, BIGSTACK); - exec(clock, NULL, BIGSTACK); + exec(heartbeat, NULL, DEFSTACK, Low); + exec(rgb, &rgbargs, BIGSTACK, High); + exec(pwm, &pwmargs[0], DEFSTACK, RT); + exec(pwm, &pwmargs[1], DEFSTACK, RT); + exec(pwm, &pwmargs[2], DEFSTACK, RT); + exec(adc, &adcarg, BIGSTACK, Low); + exec(clock, NULL, BIGSTACK, Low); #if 0 exec(ctrl, NULL, BIGSTACK); exec(cmd, &rgbargs, DEFSTACK); diff --git a/kernel/kernel.c b/kernel/kernel.c index ab7d466..e5c2a15 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -36,12 +36,15 @@ #define NOW(hi, lo) (((uint32_t)(hi) << 0x10) | (lo)) #define DISTANCE(from, to) ((int32_t)((to) - (from))) #define SCHEDULE TIMER1_COMPA_vect +#define MAXROUND 0x10 struct task { uint32_t release; /* release time */ uint16_t sp; /* stack pointer */ uint8_t *stack; /* stack area */ uint8_t id; /* task id */ + uint8_t prio; + uint8_t defprio; struct queue *rq; TAILQ_ENTRY(task) r_link; TAILQ_ENTRY(task) t_link; @@ -89,7 +92,8 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED) dist = DISTANCE(now, tp->release); if (dist <= 0) { TAILQ_REMOVE(&kern.tq, tp, t_link); - tp->rq = &kern.rq[High]; + tp->prio = tp->defprio; + tp->rq = &kern.rq[tp->prio]; TAILQ_INSERT_TAIL(tp->rq, tp, r_link); } else if (dist < nexthit) nexthit = dist; @@ -98,10 +102,10 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED) /* reschedule current task if it's still at head of runq */ if (kern.cur == TAILQ_FIRST(kern.cur->rq)) { TAILQ_REMOVE(kern.cur->rq, kern.cur, r_link); - kern.cur->rq = &kern.rq[Low]; - /* skipping idle task */ - if (kern.cur != kern.idle) - TAILQ_INSERT_TAIL(kern.cur->rq, kern.cur, r_link); + if (kern.cur->prio < RR) + kern.cur->prio++; + kern.cur->rq = &kern.rq[kern.cur->prio]; + TAILQ_INSERT_TAIL(kern.cur->rq, kern.cur, r_link); } /* pick hightes rq */ @@ -111,10 +115,6 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED) break; } - /* if none is ready, go idle */ - if (TAILQ_EMPTY(rq)) - TAILQ_INSERT_TAIL(kern.idle->rq, kern.idle, r_link); - /* switch context */ kern.cur->sp = SP; kern.cur = TAILQ_FIRST(rq); @@ -128,7 +128,7 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED) } void -init(uint8_t prio, uint8_t sema, uint8_t stack) +init(uint8_t sema, uint8_t stack) { uint8_t i; @@ -150,8 +150,8 @@ init(uint8_t prio, uint8_t sema, uint8_t stack) /* init queues */ - kern.rq = calloc(prio, sizeof(struct queue)); - for (i = 0; i < prio; i++) + kern.rq = calloc(nPrio, sizeof(struct queue)); + for (i = 0; i < nPrio; i++) TAILQ_INIT(&kern.rq[i]); kern.wq = calloc(sema, sizeof(struct queue)); @@ -162,11 +162,13 @@ init(uint8_t prio, uint8_t sema, uint8_t stack) /* init idle task */ kern.idle = calloc(1, sizeof(struct task)); + kern.idle->prio = Idle; + kern.idle->defprio = Idle; kern.idle->id = 0; kern.idle->release = 0; kern.idle->sp = SP; /* not really needed */ kern.idle->stack = (uint8_t *)(RAMEND - stack + 1); - kern.idle->rq = &kern.rq[Low]; + kern.idle->rq = &kern.rq[kern.idle->prio]; TAILQ_INSERT_TAIL(kern.idle->rq, kern.idle, r_link); kern.cur = TAILQ_FIRST(kern.idle->rq); @@ -181,7 +183,7 @@ init(uint8_t prio, uint8_t sema, uint8_t stack) } void -exec(void (*fun)(void *), void *args, uint8_t stack) +exec(void (*fun)(void *), void *args, uint8_t stack, uint8_t prio) { struct task *tp; uint8_t *sp; @@ -206,10 +208,12 @@ exec(void (*fun)(void *), void *args, uint8_t stack) sp -= 6; memset(sp, 0, 6); /* r26-r31 */ + tp->prio = prio; + tp->defprio = prio; tp->id = ++kern.maxid; tp->release = 0; tp->sp = (uint16_t)sp; /* SP */ - tp->rq = &kern.rq[Low]; + tp->rq = &kern.rq[tp->prio]; TAILQ_INSERT_TAIL(tp->rq, tp, r_link); SCHEDULE(); diff --git a/kernel/kernel.h b/kernel/kernel.h index 4f2b748..83e44ae 100644 --- a/kernel/kernel.h +++ b/kernel/kernel.h @@ -69,12 +69,12 @@ #define MSEC(T) ((uint32_t)(T) * kHz) #define SEC(T) ((uint32_t)(T) * Hz) -enum Prio { High, Low, nPrio }; +enum Prio { RT, High, Low, RR, Idle, nPrio }; /* __BEGIN_DECLS */ -void init(uint8_t prio, uint8_t sema, uint8_t stack); -void exec(void (*fun)(void *), void *args, uint8_t stack); +void init(uint8_t sema, uint8_t stack); +void exec(void (*fun)(void *), void *args, uint8_t stack, uint8_t prio); void wait(uint8_t chan); void signal(uint8_t chan); -- cgit v1.2.3