void __attribute__ ((naked, noinline)) ki_task_shift (void) { PUSHREGS (); // push task regs on stak so we are rdy to task shift K_CHG_STAK (); POPREGS (); // restore regs RETI (); // and do a reti NB this also enables interrupt !!! }
ISR (TIMER2_OVF_vect, ISR_NAKED) { // no local vars ! I think PUSHREGS (); TCNT2 = tcnt2; // Reload the timer if (!k_running) // obvious goto exitt; fakecnt--; if (0 < fakecnt) // how often shall we run KeRNeL timer code ? goto exitt; fakecnt = fakecnt_preset; // now it's time for doing RT stuff // It looks maybe crazy to go through all semaphores and tasks // but // you may have 3-4 tasks and 3-6 semaphores in your code // so... // and - it's a good idea not to init krnl with more items (tasks/Sem/msg descriptors than needed) pE = sem_pool; // Semaphore timer - check timers on semaphores - they may be cyclic for (tmr_indx = 0; tmr_indx < nr_sem; tmr_indx++) { if (0 < pE->cnt2) { // timer on semaphore ? pE->cnt2--; // yep decrement it if (pE->cnt2 <= 0) { // timeout ? pE->cnt2 = pE->cnt3; // preset again - if cnt3 == 0 and >= 0 the rep timer ki_signal (pE); //issue a signal to the semaphore } } pE++; } pE = task_pool; // Chk timers on tasks - they may be one shoot waiting for (tmr_indx = 0; tmr_indx < nr_task; tmr_indx++) { if (0 < pE->cnt2) { // timer active on task ? pE->cnt2--; // yep so let us do one down count if (pE->cnt2 <= 0) { // timeout ? ( == 0 ) pE->cnt2 = -1; // indicate timeout inis semQ prio_enQ (pAQ, deQ (pE)); // to AQ } } pE++; } prio_enQ (pAQ, deQ (pRun)); // round robbin K_CHG_STAK (); exitt: POPREGS (); RETI (); }
ISR (KRNLTMRVECTOR, ISR_NAKED) // naked so we have to supply with prolog and epilog (push pop stack of regs) { PUSHREGS (); // no local vars ! I think // JDN NASTY FOR TIMING ANALYSIS ONLY // PORTB |=0x10; wdt_reset (); #if (KRNLTMR == 0) // we have overtaken the millis timer so we do it by hand timer0_millis += MILLIS_INC; timer0_fractt += FRACT_INC; if (timer0_fractt >= FRACT_MAX) { timer0_fractt -= FRACT_MAX; timer0_millis += 1; } timer0_overflow_count++; #else TCNTx = tcntValue; // Reload the timer #endif if (!k_running) { goto exitt; } if (1 < k_tick_size) { fakecnt--; if (fakecnt <= 0) { fakecnt = k_tick_size; } else { goto exitt; // no service } } k_millis_counter += k_tick_size; // my own millis counter // the following may look crazy: to go through all semaphores and tasks // but you may have 3-4 tasks and 3-6 semaphores in your code // so - seems to be efficient :-) // so - it's a good idea not to init krnl with more items // (tasks/Sem/msg descriptors than needed) pE = sem_pool; // Semaphore timer - check timers on semaphores for (tmr_indx = 0; tmr_indx < nr_sem; tmr_indx++) { if (0 < pE->cnt2) // timer on semaphore ? { pE->cnt2--; // yep decrement it if (pE->cnt2 <= 0) // timeout ? { pE->cnt2 = pE->cnt3; // preset again - if cnt3 == 0 and >= 0 the rep timer ki_signal (pE); //issue a signal to the semaphore } } pE++; } pE = task_pool; // Chk timers on tasks - they may be one shoot waiting for (tmr_indx = 0; tmr_indx < nr_task; tmr_indx++) { if (0 < pE->cnt2) // timer active on task ? { pE->cnt2--; // yep so let us do one down count if (pE->cnt2 <= 0) // timeout ? ( == 0 ) { ((struct k_t *) (pE->cnt3))->cnt1++; // leaving sem so adjust semcount on sem prio_enQ (pAQ, deQ (pE)); // and rip task of semQ and insert in activeQ pE->cnt2 = -1; // indicate timeout in this semQ } } pE++; } prio_enQ (pAQ, deQ (pRun)); K_CHG_STAK (); exitt: //JDN NASTY FOR MEA ONLY onn UNO pin8 //PORTB &=0xef; POPREGS (); RETI (); }
ISR (KRNLTMRVECTOR, ISR_NAKED) { // no local vars ! I think PUSHREGS (); TCNTx = tcntValue; // Reload the timer if (!k_running) { // obvious goto exitt; } fakecnt--; // for very slow k_start values //bq timer cant run so slow (8 bit timers at least) if (0 < fakecnt) { // how often shall we run KeRNeL timer code ? goto exitt; } fakecnt = fakecnt_preset; // now it's time for doing RT stuff k_millis_counter += k_tick_size; // my own millis counter // the following may look crazy: to go through all semaphores and tasks // but you may have 3-4 tasks and 3-6 semaphores in your code // so - seesm to be efficient :-) // so - it's a good idea not to init krnl with more items // (tasks/Sem/msg descriptors than needed) pE = sem_pool; // Semaphore timer - check timers on semaphores - they may be cyclic for (tmr_indx = 0; tmr_indx < nr_sem; tmr_indx++) { if (0 < pE->cnt2) { // timer on semaphore ? pE->cnt2--; // yep decrement it if (pE->cnt2 <= 0) { // timeout ? pE->cnt2 = pE->cnt3; // preset again - if cnt3 == 0 and >= 0 the rep timer ki_signal (pE); //issue a signal to the semaphore } } pE++; } pE = task_pool; // Chk timers on tasks - they may be one shoot waiting for (tmr_indx = 0; tmr_indx < nr_task; tmr_indx++) { if (0 < pE->cnt2) { // timer active on task ? pE->cnt2--; // yep so let us do one down count if (pE->cnt2 <= 0) { // timeout ? ( == 0 ) ki_signal ((struct k_t *) (pE->cnt3)); pE->cnt2 = -1; // indicate timeout in this semQ } } pE++; } if (krnl_preempt_flag) { prio_enQ (pAQ, deQ (pRun)); // round robbin K_CHG_STAK (); } exitt: POPREGS (); RETI (); }