1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge branch 'master' of ssh://ukleos.org/home/git/ukleos

This commit is contained in:
Kaspar Schleiser 2010-11-04 16:48:14 +01:00
commit 67f72d43ee
6 changed files with 54 additions and 30 deletions

View File

@ -23,7 +23,7 @@
#include <bitarithm.h> #include <bitarithm.h>
#include <kernel.h> #include <kernel.h>
#include <mutex.h> #include <thread.h>
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -33,8 +33,14 @@ typedef struct hwtimer_t {
uint8_t checksum; uint8_t checksum;
} hwtimer_t; } hwtimer_t;
typedef struct hwtimer_wait_t {
unsigned int pid; /**< pid of waiting thread */
uint8_t state; /**<state of waiting thread */
} hwtimer_wait_t;
#define HWTIMER_QUEUESIZE ARCH_MAXTIMERS #define HWTIMER_QUEUESIZE ARCH_MAXTIMERS
#define Q_FULL HWTIMER_QUEUESIZE + 1 #define Q_FULL HWTIMER_QUEUESIZE + 1
#define HWTIMER_WAIT_BACKOFF (10)
static hwtimer_t timer[HWTIMER_QUEUESIZE]; static hwtimer_t timer[HWTIMER_QUEUESIZE];
static int queue[HWTIMER_QUEUESIZE]; static int queue[HWTIMER_QUEUESIZE];
@ -48,8 +54,8 @@ static volatile long available_timers = 0;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int enqueue(int item) { static int enqueue(int item) {
// Test if timer is already cleared: /* Test if timer is already cleared:
// (hack to prevent race-condition with proccing timer (ISR) and manual hwtimer_remove) * (hack to prevent race-condition with proccing timer (ISR) and manual hwtimer_remove) */
if (available_timers & (1 << item)) { if (available_timers & (1 << item)) {
return 1; return 1;
} }
@ -58,7 +64,8 @@ static int enqueue(int item) {
queue_tail = (queue_tail + 1) % HWTIMER_QUEUESIZE; queue_tail = (queue_tail + 1) % HWTIMER_QUEUESIZE;
queue_items++; queue_items++;
if (queue_items == HWTIMER_QUEUESIZE) { if (queue_items == HWTIMER_QUEUESIZE) {
lpm_prevent_sleep &= ~LPM_PREVENT_SLEEP_HWTIMER; // Allow power down /* Allow power down */
lpm_prevent_sleep &= ~LPM_PREVENT_SLEEP_HWTIMER;
} }
return 1; return 1;
} }
@ -67,10 +74,12 @@ static int dequeue(void) {
register int ret; register int ret;
if (!queue_items) if (!queue_items)
return Q_FULL; return Q_FULL;
lpm_prevent_sleep |= LPM_PREVENT_SLEEP_HWTIMER; // No power down while a timer is active /* No power down while a timer is active */
lpm_prevent_sleep |= LPM_PREVENT_SLEEP_HWTIMER;
queue_items--; queue_items--;
ret = queue[queue_head]; ret = queue[queue_head];
queue[queue_head] = 0xff; // Mark as empty /* Mark as empty */
queue[queue_head] = 0xff;
available_timers &= ~(1 << ret); available_timers &= ~(1 << ret);
queue_head = (queue_head + 1) % HWTIMER_QUEUESIZE; queue_head = (queue_head + 1) % HWTIMER_QUEUESIZE;
return ret; return ret;
@ -81,8 +90,11 @@ static void multiplexer(int source) {
timer[source].callback(timer[source].data); timer[source].callback(timer[source].data);
} }
static void hwtimer_releasemutex(void* mutex) { static void hwtimer_wakeup(void* hwt) {
mutex_unlock((mutex_t*)mutex, true); ((hwtimer_wait_t*)hwt)->state = 0;
while (!(thread_wakeup((*((hwtimer_wait_t*)hwt)).pid))) {
hwtimer_set(HWTIMER_WAIT_BACKOFF, hwtimer_wakeup, (void*) &hwt);
}
} }
void hwtimer_spin(unsigned long ticks) void hwtimer_spin(unsigned long ticks)
@ -109,7 +121,8 @@ void hwtimer_init_comp(uint32_t fcpu) {
available_timers = 0; available_timers = 0;
hwtimer_arch_init(multiplexer, fcpu); hwtimer_arch_init(multiplexer, fcpu);
for (i = 0; i < HWTIMER_QUEUESIZE; i++) { for (i = 0; i < HWTIMER_QUEUESIZE; i++) {
queue[i] = 0xff; // init queue as empty /* init queue as empty */
queue[i] = 0xff;
} }
for (i = 0; i < HWTIMER_QUEUESIZE; i++) { for (i = 0; i < HWTIMER_QUEUESIZE; i++) {
enqueue(i); enqueue(i);
@ -119,7 +132,7 @@ void hwtimer_init_comp(uint32_t fcpu) {
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int hwtimer_active(void) { int hwtimer_active(void) {
return queue_items != HWTIMER_QUEUESIZE; return (queue_items != HWTIMER_QUEUESIZE);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -133,34 +146,37 @@ unsigned long hwtimer_now(void)
void hwtimer_wait(unsigned long ticks) void hwtimer_wait(unsigned long ticks)
{ {
mutex_t mutex; if (ticks <= 6 || inISR()) {
if (ticks <= 4 || inISR()) {
hwtimer_spin(ticks); hwtimer_spin(ticks);
return; return;
} }
mutex_init(&mutex); hwtimer_wait_t hwt;
mutex_lock(&mutex); hwt.pid = active_thread->pid;
// -2 is to adjust the real value hwt.state = 1;
int res = hwtimer_set(ticks-2, hwtimer_releasemutex, &mutex); /* -2 is to adjust the real value */
int res = hwtimer_set(ticks-2, hwtimer_wakeup, (void*) &hwt);
if (res == -1) { if (res == -1) {
mutex_unlock(&mutex, true);
hwtimer_spin(ticks); hwtimer_spin(ticks);
return; return;
} }
mutex_lock(&mutex); while (hwt.state) {
thread_sleep();
}
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int _hwtimer_set(unsigned long offset, void (*callback)(void*), void *ptr, bool absolute) static int _hwtimer_set(unsigned long offset, void (*callback)(void*), void *ptr, bool absolute)
{ {
if (! inISR() ) dINT(); if (!inISR()) {
// hwtimer_arch_disable_interrupt(); dINT();
}
int x = dequeue(); int x = dequeue();
if (x == Q_FULL) { if (x == Q_FULL) {
if (! inISR()) {
eINT();
}
printf("[KT] no timers left\n"); printf("[KT] no timers left\n");
// hwtimer_arch_enable_interrupt();
if (! inISR()) eINT();
return -1; return -1;
} }
@ -168,13 +184,16 @@ static int _hwtimer_set(unsigned long offset, void (*callback)(void*), void *ptr
timer[x].data = ptr; timer[x].data = ptr;
timer[x].checksum = ++timer_id; timer[x].checksum = ++timer_id;
if (absolute) if (absolute) {
hwtimer_arch_set_absolute(offset, x); hwtimer_arch_set_absolute(offset, x);
else }
else {
hwtimer_arch_set(offset, x); hwtimer_arch_set(offset, x);
}
//hwtimer_arch_enable_interrupt(); if (!inISR()) {
if (! inISR()) eINT(); eINT();
}
return (timer[x].checksum << 8) + x; return (timer[x].checksum << 8) + x;
} }

View File

@ -30,7 +30,7 @@
#define __HWTIMER_H #define __HWTIMER_H
#include <stdint.h> #include <stdint.h>
#include "hwtimer_cpu.h" #include <hwtimer_cpu.h>
/** /**
* @def HWTIMER_SPEED * @def HWTIMER_SPEED

View File

@ -34,7 +34,7 @@
typedef struct tcb { typedef struct tcb {
char* sp; char* sp;
unsigned int status; uint8_t status;
uint16_t pid; uint16_t pid;
uint16_t priority; uint16_t priority;

View File

@ -62,7 +62,7 @@ int thread_wakeup(int pid) {
} else { } else {
sched_context_switch_request = 1; sched_context_switch_request = 1;
} }
return 0; return 1;
} else { } else {
DEBUG("thread_wakeup: Thread is not sleeping!\n"); DEBUG("thread_wakeup: Thread is not sleeping!\n");
if (!isr) eINT(); if (!isr) eINT();

View File

@ -51,7 +51,7 @@ and the mailinglist (subscription via web site)
#define SHT11_RESET (0x1E) //000 1111 0 #define SHT11_RESET (0x1E) //000 1111 0
/* time to wait after toggling the data line */ /* time to wait after toggling the data line */
#define SHT11_DATA_WAIT (HWTIMER_TICKS(5)) #define SHT11_DATA_WAIT (HWTIMER_TICKS(1))
/* time to wait after toggling the clock line */ /* time to wait after toggling the clock line */
#define SHT11_CLK_WAIT (HWTIMER_TICKS(1)) #define SHT11_CLK_WAIT (HWTIMER_TICKS(1))

View File

@ -1,5 +1,6 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <board_uart0.h>
#include <auto_init.h> #include <auto_init.h>
#define ENABLE_DEBUG #define ENABLE_DEBUG
@ -16,6 +17,10 @@ void auto_init(void) {
DEBUG("Auto init swtimer module.\n"); DEBUG("Auto init swtimer module.\n");
swtimer_init(); swtimer_init();
#endif #endif
#ifdef MODULE_UART0
DEBUG("Auto init uart0 module.\n");
board_uart0_init();
#endif
#ifdef MODULE_SHT11 #ifdef MODULE_SHT11
DEBUG("Auto init SHT11 module.\n"); DEBUG("Auto init SHT11 module.\n");
sht11_init(); sht11_init();