void trtSignal(uint8_t semnbr) { uint8_t i; struct task *t; uint32_t minDeadline = 0xFFFFFFFF; uint8_t taskToReadyQ = 0; cli(); // disable interrupts for (i=1; i <= kernel.nbrOfTasks; i++) { t = &kernel.tasks[i]; if (t->state == (semnbr + WAIT_OFFSET)) { if (t->deadline <= minDeadline) { taskToReadyQ = i; minDeadline = t->deadline; } } } if (taskToReadyQ == 0) { kernel.semaphores[semnbr-1]++; } else { kernel.tasks[taskToReadyQ].state = READYQ; // make task ready // call interrupt handler to schedule TIMER1_COMPA_vect(); } sei(); // reenable interrupts }
void Posixino::timerThread() { while (true) { usleep(1000); for (int n = 0; n < 3; n++) { if (interruptCounter[n] < 0) continue; interruptCounter[n] += 1000; if (interruptCounter[n] < interruptTiming[n]) continue; interruptCounter[n] -= interruptTiming[n]; if (n == 0) { # ifdef TIMER0 TIMER0_COMPA_vect(); # endif } if (n == 1) { # ifdef TIMER1 TIMER1_COMPA_vect(); # endif } if (n == 2) { # ifdef TIMER2 TIMER2_COMPA_vect(); # endif } } // for interrupts } // forever } // timerThread()
void trtTerminate(void) { cli(); kernel.tasks[kernel.running].state = TERMINATED; // call interrupt handler to schedule TIMER1_COMPA_vect(); }
void trtSleepUntil(uint32_t release, uint32_t deadline) { struct task *t; t = &kernel.tasks[kernel.running]; cli(); // turn off interrupts t->state = TIMEQ; t->release = release; t->deadline = deadline; // call interrupt handler to schedule TIMER1_COMPA_vect(); }
static void timer1_isr(void) { const uint8_t tr = timer_reason; if ( ! sim_interrupts) { // Interrupts disabled. Schedule another callback in 10us. schedule_timer(10); return; } timer_reason = 0; cli(); #ifdef SIM_DEBUG uint64_t now = now_ns(); static unsigned int cc_1s = 0, prev_1s = 0; if ( ! clock_counter_1s && prev_1s) ++cc_1s; prev_1s = clock_counter_1s; //uint16_t now = sim_tick_counter(); uint64_t real = (now-begin) / 1000; uint64_t avr = cc_1s * 4 + clock_counter_1s; avr *= 250; avr += clock_counter_250ms * 10; avr += clock_counter_10ms; avr *= 1000 ; printf("test: Real: %us %u.%03ums AVR: %us %u.%03ums Real/AVR: %u\n", real / 1000000 , (real % 1000000)/1000 , real % 1000 , avr / 1000000 , (avr % 1000000)/1000 , avr % 1000 , real / (avr?avr:1) ); printf("test: 10ms=%u 250ms=%u 1s=%u total=%luns actual=%luns\n", clock_counter_10ms, clock_counter_250ms, clock_counter_1s, now - begin, now - then, sim_runtime_ns()); //printf(" timer1_isr tick_time=%04X now=%04X delta=%u total=%u\n", // TICK_TIME , now, now_us() - then, (now_us() - begin)/1000000 ) ; then = now; #endif if (tr & TIMER_OCR1A) TIMER1_COMPA_vect(); if (tr & TIMER_OCR1B) TIMER1_COMPB_vect(); sei(); // Setup next timer sim_timer_set(); }
void trtWait(uint8_t semnbr) { struct task *t; uint8_t *s; t = &kernel.tasks[kernel.running]; cli(); // disable interrupts s = &kernel.semaphores[semnbr-1]; if ((*s) > 0) { (*s)--; } else { t->state = semnbr + WAIT_OFFSET; // waiting for Sem#semnbr // call interrupt handler to schedule TIMER1_COMPA_vect(); } sei(); // reenable interrupts }
void trtCreateTask(void (*fun)(void*), uint16_t stacksize, uint32_t release, uint32_t deadline, void *args) { uint8_t *sp; struct task *t; int i; cli(); // turn off interrupts ++kernel.nbrOfTasks; sp = kernel.memptr; kernel.memptr -= stacksize; // decrease free mem ptr // initialize stack *sp-- = lo8(fun); // store PC(lo) *sp-- = hi8(fun); // store PC(hi) for (i=0; i<25; i++) //WAS -- for (i=0; i<24; i++) *sp-- = 0x00; // store SREG,r0-r1,r3-r23 // Save args in r24-25 (input arguments stored in these registers) *sp-- = lo8(args); *sp-- = hi8(args); for (i=0; i<6; i++) *sp-- = 0x00; // store r26-r31 t = &kernel.tasks[kernel.nbrOfTasks]; t->release = release; t->deadline = deadline; t->state = TIMEQ; t->spl = lo8(sp); // store stack pointer t->sph = hi8(sp); // call interrupt handler to schedule TIMER1_COMPA_vect(); }
void sim_check_interrupts() { unsigned int ticks = SDL_GetTicks(); int tickDiff = ticks - prevTicks; prevTicks = ticks; if (!(SREG & _BV(SREG_I))) return; #ifdef ENABLE_ULTILCD2 if ((TWCR & _BV(TWEN)) && (TWCR & _BV(TWINT)) && (TWCR & _BV(TWIE))) { //Relay the TWI interrupt by 25ms one time till it gets disabled again. This fakes the LCD refresh rate. if (twiIntStart == 0) twiIntStart = SDL_GetTicks(); if (SDL_GetTicks() - twiIntStart > 25) { cli(); TWI_vect(); _sei(); } } if (!(TWCR & _BV(TWEN)) || !(TWCR & _BV(TWIE))) { twiIntStart = 0; } #endif //if (tickDiff > 1) // printf("Ticks slow! %i\n", tickDiff); if (tickDiff > 0) { ms_callback(); cli(); for(int n=0;n<tickDiff;n++) { if (TIMSK0 & _BV(OCIE0B)) TIMER0_COMPB_vect(); if (TIMSK0 & _BV(TOIE0)) TIMER0_OVF_vect(); } //Timer1 runs at 16Mhz / 8 ticks per second. unsigned int waveformMode = ((TCCR1B & (_BV(WGM13) | _BV(WGM12))) >> 1) | (TCCR1A & (_BV(WGM11) | _BV(WGM10))); unsigned int clockSource = TCCR1B & (_BV(CS12) | _BV(CS11) | _BV(CS10)); unsigned int tickCount = F_CPU * tickDiff / 1000; unsigned int ticks = TCNT1; switch(clockSource) { case 0: tickCount = 0; break; case 1: break; case 2: tickCount /= 8; break; case 3: tickCount /= 64; break; case 4: tickCount /= 256; break; case 5: tickCount /= 1024; break; case 6: tickCount = 0; break; case 7: tickCount = 0; break; } tickCount *= 4;//For some reason the stepper speed is to slow, so cheat the timer routine. if (tickCount > 0 && OCR1A > 0) { ticks += tickCount; while(ticks > int(OCR1A)) { ticks -= int(OCR1A); if (TIMSK1 & _BV(OCIE1A)) TIMER1_COMPA_vect(); } TCNT1 = ticks; } _sei(); }