aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2012-05-09 15:39:47 +0000
committerDimitri Sokolyuk <demon@dim13.org>2012-05-09 15:39:47 +0000
commit153920a334bd9dfb6a51f129caee42dde31df508 (patch)
tree1931cf8f91e79aea691700834342dc139704d7e7 /kernel
parentf482011b93210ee4dde3762d8f766bc350e3ab10 (diff)
proper priorities
Diffstat (limited to 'kernel')
-rw-r--r--kernel/dmx.c16
-rw-r--r--kernel/kernel.c34
-rw-r--r--kernel/kernel.h6
3 files changed, 30 insertions, 26 deletions
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);