aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/dmx.c4
-rw-r--r--kernel/kernel.c55
-rw-r--r--kernel/stack.h9
3 files changed, 25 insertions, 43 deletions
diff --git a/kernel/dmx.c b/kernel/dmx.c
index c531a37..d4d7d73 100644
--- a/kernel/dmx.c
+++ b/kernel/dmx.c
@@ -36,11 +36,11 @@ struct pwmarg pwmargs[] = {
int
main()
{
- init(STACK);
+ init(DEFSTACK);
uart_init();
lcd_init();
- exec(heartbeat, NULL, MINSTACK);
+ exec(heartbeat, NULL, DEFSTACK);
exec(rgb, &rgbargs, DEFSTACK);
exec(pwm, &pwmargs[0], DEFSTACK);
exec(pwm, &pwmargs[1], DEFSTACK);
diff --git a/kernel/kernel.c b/kernel/kernel.c
index 983f052..397402a 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -23,6 +23,7 @@
#include <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>
+#include <avr/power.h>
#include <avr/wdt.h>
#include "kernel.h"
#include "stack.h"
@@ -65,48 +66,35 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED)
uint16_t nexthit;
int32_t dist;
- PUSH_ALL();
+ pusha();
now = NOW(kernel.cycles, TCNT1);
+ nexthit = UINT16_MAX;
- /* release waiting tasks */
TAILQ_FOREACH_SAFE(tp, &kernel.timeq, t_link, tmp) {
- if (DISTANCE(tp->release, now) >= 0) {
+ dist = DISTANCE(now, tp->release);
+ if (dist <= 0) {
TAILQ_REMOVE(&kernel.timeq, tp, t_link);
TAILQ_INSERT_TAIL(&kernel.runq, tp, r_link);
- } else
- break;
+ } else if (dist < nexthit)
+ nexthit = dist;
}
- /* drop idle */
- if (kernel.current == kernel.idle)
- TAILQ_REMOVE(&kernel.runq, kernel.current, r_link);
-
- /* runq not changed && not empty -> yield */
if (kernel.current == TAILQ_FIRST(&kernel.runq)) {
TAILQ_REMOVE(&kernel.runq, kernel.current, r_link);
- TAILQ_INSERT_TAIL(&kernel.runq, kernel.current, r_link);
+ if (kernel.current != kernel.idle)
+ TAILQ_INSERT_TAIL(&kernel.runq, kernel.current, r_link);
}
- /* go idle if nothing to do */
if (TAILQ_EMPTY(&kernel.runq))
TAILQ_INSERT_TAIL(&kernel.runq, kernel.idle, r_link);
-
- nexthit = INT16_MAX; /* max time slice */
-
- if ((tp = TAILQ_FIRST(&kernel.timeq))) {
- dist = DISTANCE(now, tp->release);
- if (dist < nexthit)
- nexthit = dist;
- }
-
+
OCR1A = (uint16_t)(now + nexthit);
- /* switch context */
kernel.current->sp = SP;
kernel.current = TAILQ_FIRST(&kernel.runq);
SP = kernel.current->sp;
- POP_ALL();
+ popa();
reti();
}
@@ -116,9 +104,12 @@ init(uint8_t stack)
uint8_t i;
cli();
+
MCUSR = 0;
wdt_disable();
+ clock_prescale_set(clock_div_1);
+
/* Set up timer 1 */
TCNT1 = 0; /* reset timer */
TCCR1A = 0; /* normal operation */
@@ -215,23 +206,11 @@ signal(uint8_t chan)
void
sleep(uint32_t sec, uint32_t usec)
{
- struct task *tp;
-
cli();
- TAILQ_REMOVE(&kernel.runq, kernel.current, r_link);
kernel.current->release += SEC(sec) + USEC(usec);
-
- /* find right position on time queue */
- TAILQ_FOREACH(tp, &kernel.timeq, t_link)
- if (DISTANCE(kernel.current->release, tp->release) > 0)
- break;
-
- if (tp)
- TAILQ_INSERT_BEFORE(tp, kernel.current, t_link);
- else
- TAILQ_INSERT_TAIL(&kernel.timeq, kernel.current, t_link);
-
+ TAILQ_REMOVE(&kernel.runq, kernel.current, r_link);
+ TAILQ_INSERT_TAIL(&kernel.timeq, kernel.current, t_link);
SCHEDULE();
}
@@ -239,7 +218,6 @@ void
yield(void)
{
cli();
-
SCHEDULE();
}
@@ -249,7 +227,6 @@ suspend(void)
cli();
TAILQ_REMOVE(&kernel.runq, kernel.current, r_link);
-
SCHEDULE();
}
diff --git a/kernel/stack.h b/kernel/stack.h
index b53c870..d553076 100644
--- a/kernel/stack.h
+++ b/kernel/stack.h
@@ -18,8 +18,12 @@
#ifndef __STACK_H
#define __STACK_H
+#define NAKED(name, ...) \
+void name (void) __attribute__ ((naked)) __VA_ARGS__; \
+void name (void)
+
/* 68 cycles */
-#define PUSH_ALL() asm volatile ( \
+#define pusha() asm volatile ( \
"push r1 \n" \
"push r0 \n" \
"in r0, __SREG__ \n" \
@@ -57,7 +61,7 @@
"push r31 \n" )
/* 69 cycles */
-#define POP_ALL() asm volatile ( \
+#define popa() asm volatile ( \
"pop r31 \n" \
"pop r30 \n" \
"pop r29 \n" \
@@ -93,4 +97,5 @@
"pop r0 \n" \
"pop r1 \n" )
+#define ret() asm volatile ("ret");
#endif