Projekte
workwind
Multitasking optimiert
thread.c
Projekte
Forum
Doku
Öffentliche Projekte
Startseite
Beispielprogramme
Projekte von anderen
Welcome
Username
Passwort
Eingeloggt bleiben
Zugangsdaten vergessen?
Registrieren
Projektverwaltung
⇨ Please choose! ⇦
——————————————————
✎ Create new project...
★ Browse existing projects...
——————————————————
⚬ MotorTest#1
⚬ C Tutorial 8#1
⚬ NIBO2 C Project#1
⚙ C Tutorial 15#1
⚬ 2010_11_18_el_test001#1
Multitask...optimiert
cdll.c
cdll.h
condition.c
condition.h
main.c
mutex.c
mutex.h
scheduler.S
semaphore.c
semaphore.h
thread.c
thread.h
Project details
Compiler settings
Nachrichten
Sie sind nicht eingeloggt.
Neuigkeiten
★
NiboRoboLib 3.6
2017-01-17: Neue Version 3.6
★
NiboRoboLib 3.4.1
2016-04-16: Neue Version 3.4.1
★
Coding Tutorial
2015-11-22: Jetzt auch für den NIBO burger!
Site-Statistic
7426 private projects
385 public projects
16180353 lines compiled
58212 builds
NIBO
@
multitasking_opt/thread.c [read only]
#include <avr/interrupt.h> #include "thread.h" #define IDLE_STACKSIZE 32 #define RETURN_ADDRESS_SIZE 2 #if defined(RAMPZ) #define RAMP_SIZE 1 #else #deine RAMP_SIZE 0 #endif #define IDLE_CONTEXT_SIZE (RETURN_ADDRESS_SIZE + 4) #define CALL_CONTEXT_SIZE (RETURN_ADDRESS_SIZE + 21) #define IRQ_CONTEXT_SIZE (RETURN_ADDRESS_SIZE + RAMP_SIZE + 34) volatile uint8_t scheduler_status; #define SCHEDULER_IS_IDLE 0 #define SCHEDULER_HAS_NEXT 1 #define SCHEDULER_FROM_IRQ 2 #define SCHEDULER_TIMER 3 #define LO(val) ((uint8_t)(((val)>>0)&0xff)) #define HI(val) ((uint8_t)(((val)>>8)&0xff)) thread_t idleThread; thread_t primaryThread; uint8_t idle_stack[IDLE_STACKSIZE]; volatile thread_t * running_thread; volatile thread_t * next_thread; cdll_t ready_list[THREAD_PRIO_MAX]; cdll_t wait_list; cdll_t waittime_list; uint16_t waittime_next; uint16_t waittime_dec; uint32_t ticks; static uint8_t schedule_lock; //#include "thread_asm.h" void scheduler_yield(); void scheduler_irq(); void scheduler_timer(); void scheduler_idle(); uint8_t thread_selectNext(uint8_t status); uint8_t thread_handleTimer(uint8_t status); uint8_t thread_selectNext(uint8_t status) { if (schedule_lock) { return status; } thread_t * thread = 0; for (uint8_t p=0; p<THREAD_PRIO_MAX; ++p) { cdll_t * rlist = &(ready_list[p]); thread = (thread_t*) cdll_peek_front(rlist); if (thread) { cdll_move_back(rlist, (cdll_t *)thread); break; } } if (thread==0) { thread = &idleThread; } if (thread!=running_thread) { next_thread = thread; return status | _BV(SCHEDULER_HAS_NEXT); } return status; } uint8_t thread_handleTimer(uint8_t status) { ticks++; if (waittime_next) { waittime_next--; if (waittime_next==0) { // we have a wait event.... uint16_t waittime = 0xffff; cdll_t * pos = waittime_list.next; while (pos != &waittime_list) { thread_t * thread = (thread_t *) pos; pos = pos->next; uint16_t timeout = thread->wait_timeout - waittime_dec; thread->wait_timeout = timeout; if (timeout==0) { cdll_move_front(&(ready_list[thread->priority]), (cdll_t *)thread); thread->state = THREAD_TIMEOUT_READY; } else if (timeout < waittime) { waittime = timeout; } } if (waittime != 0xffff) { waittime_dec = waittime; waittime_next = waittime; } } } return status; } void thread_startScheduler(uint8_t priority) { //assert (priority < THREAD_PRIO_MAX) cli(); schedule_lock = 0; waittime_next = 0; waittime_dec = 0; for (uint8_t p = 0; p<THREAD_PRIO_MAX; ++p) { cdll_reset(&(ready_list[p])); } cdll_reset(&wait_list); cdll_reset(&waittime_list); // setup idle thread idleThread.priority = THREAD_PRIO_MAX; idleThread.state = THREAD_READY; uint8_t * stack = idle_stack + IDLE_STACKSIZE - 1; stack -= IDLE_CONTEXT_SIZE; stack[IDLE_CONTEXT_SIZE-0] = LO(((uint16_t)scheduler_idle)); stack[IDLE_CONTEXT_SIZE-1] = HI(((uint16_t)scheduler_idle)); stack[3] = 0; // SREG stack[2] = _BV(SE); // MCUCR stack[1] = _BV(SCHEDULER_FROM_IRQ) | _BV(SCHEDULER_IS_IDLE); idleThread.stackpointer = stack; // setup primary thread thread_init(&primaryThread, 0, 0, priority); primaryThread.state = THREAD_READY; cdll_push_front(&(ready_list[priority]), (cdll_t *)&primaryThread); running_thread = &primaryThread; scheduler_yield(); sei(); } void thread_init(thread_t * thread, void * stack, uint16_t stack_size, uint8_t priority) { //assert (priority < THREAD_PRIO_MAX) if (stack) { thread->stackpointer = stack+stack_size-1; } thread->priority = priority; thread->state = 0; thread->signal_cnt = 0; thread->wait_timeout = 0; } void thread_start(thread_t * thread, thread_main_t * mainFunc, void * arg) { uint8_t * stack = thread->stackpointer; stack -= IRQ_CONTEXT_SIZE; stack[IRQ_CONTEXT_SIZE-0] = LO(((uint16_t)mainFunc)); stack[IRQ_CONTEXT_SIZE-1] = HI(((uint16_t)mainFunc)); stack[IRQ_CONTEXT_SIZE-2] = LO((uint16_t)arg); stack[IRQ_CONTEXT_SIZE-3] = 0; // SREG stack[26] = HI((uint16_t)arg); stack[1] = _BV(SCHEDULER_FROM_IRQ); thread->stackpointer = stack; thread->state = THREAD_WAIT; cdll_push_back(&wait_list, (cdll_t *)thread); } void thread_delete(thread_t * thread) { } void thread_yield() { cli(); uint8_t slock = schedule_lock; schedule_lock = 0; scheduler_status = thread_selectNext(scheduler_status); if (scheduler_status & _BV(SCHEDULER_HAS_NEXT)) { scheduler_yield(); } schedule_lock = slock; sei(); } void thread_wait() { cli(); thread_t * thread = (thread_t *) running_thread; if (thread->signal_cnt) { thread->signal_cnt--; } else { thread->state = THREAD_WAIT; cdll_move_back(&wait_list, (cdll_t *)thread); uint8_t slock = schedule_lock; schedule_lock = 0; scheduler_yield(); schedule_lock = slock; } sei(); } uint8_t thread_waitTimeout(uint16_t timeout) { cli(); thread_t * thread = (thread_t *) running_thread; if (thread->signal_cnt) { thread->signal_cnt--; } else { thread->state = THREAD_WAITTIME; cdll_move_back(&waittime_list, (cdll_t *)thread); if (timeout < waittime_next) { // wir sind als erstes reif fuer sie Signalisierung waittime_dec = waittime_dec - waittime_next + timeout; waittime_next = timeout; thread->wait_timeout = waittime_dec; } else if (waittime_next==0) { // wir sind der eizige wartende Task waittime_dec = timeout; waittime_next = timeout; thread->wait_timeout = timeout; } else { // die anderen Tasks sind eher fertig... timeout += waittime_dec - waittime_next; thread->wait_timeout = timeout; } uint8_t slock = schedule_lock; schedule_lock = 0; scheduler_yield(); schedule_lock = slock; } if (thread->state == THREAD_TIMEOUT_READY) { thread->state = THREAD_READY; sei(); return 0; } sei(); return 1; } void thread_signal(thread_t * thread) { cli(); thread_signalISR(thread); scheduler_yield(); sei(); } void thread_signalISR(thread_t * thread) { uint8_t state = thread->state; if (state == THREAD_READY) { thread->signal_cnt++; } else if (state == THREAD_WAIT) { thread->state = THREAD_READY; cdll_move_front(&(ready_list[thread->priority]), (cdll_t *)thread); } else if (state == THREAD_WAITTIME) { thread->state = THREAD_READY; cdll_move_front(&(ready_list[thread->priority]), (cdll_t *)thread); } } void thread_changePriority(thread_t * thread, uint8_t priority) { cli(); thread->priority = priority; if ((thread->state == THREAD_READY) || (thread->state == THREAD_TIMEOUT_READY)) { cdll_move_front(&(ready_list[thread->priority]), (cdll_t *)thread); } sei(); } void thread_suppressScheduling() { cli(); schedule_lock++; sei(); } void thread_allowScheduling() { cli(); if (schedule_lock) { schedule_lock--; } sei(); }
Compiler results:
Werbung
Online
dtsjada1842883129
elidabaylee669745
giahill891542995
janinalomax603906209
jeanniebland8449