Beispiel #1
0
/**
\brief The program starts executing here.
*/
int mote_main(void) {
   
   board_init();
   leds_error_on();
   
   debugpins_frame_set();    some_delay();
   debugpins_frame_toggle(); some_delay();
   debugpins_frame_toggle(); some_delay();
   debugpins_frame_clr();    some_delay();
   
   debugpins_slot_set();     some_delay();
   debugpins_slot_toggle();  some_delay();
   debugpins_slot_toggle();  some_delay();
   debugpins_slot_clr();     some_delay();
   
   debugpins_fsm_set();      some_delay();
   debugpins_fsm_toggle();   some_delay();
   debugpins_fsm_toggle();   some_delay();
   debugpins_fsm_clr();      some_delay();
   
   debugpins_task_set();     some_delay();
   debugpins_task_toggle();  some_delay();
   debugpins_task_toggle();  some_delay();
   debugpins_task_clr();     some_delay();
   
   debugpins_isr_set();      some_delay();
   debugpins_isr_toggle();   some_delay();
   debugpins_isr_toggle();   some_delay();
   debugpins_isr_clr();      some_delay();
   
   debugpins_radio_set();    some_delay();
   debugpins_radio_toggle(); some_delay();
   debugpins_radio_toggle(); some_delay();
   debugpins_radio_clr();    some_delay();
   
   board_reset();
   
   return 0;
}
Beispiel #2
0
kick_scheduler_t radiotimer_isr() {
    uint8_t         i;                       // iterator
    uint16_t        now,timeSpent;
    uint16_t        calc;
    uint16_t        min;
    uint16_t        tempcompare;

    // update the current theoretical time -- nextCurrentTime MUST be NOW
    abstimer_vars.currentTime = abstimer_vars.nextCurrentTime;

    //debug -- to detect nested behaviours in case of reentrant interrupt.. should never happen
    abstimer_dbg.nested_isr++;

    //===== step 1. Find out which interrupts just fired

    // Note: we store the list of interrupts which fired in an 8-bit bitmap
    abstimer_vars.bitmapInterruptsFired = 0;

    for (i=0; i<ABSTIMER_SRC_MAX; i++) {
        if (
            (abstimer_vars.isArmed[i]==TRUE) &&
            (abstimer_vars.compareVal[i]==abstimer_vars.currentTime)
        ) {
            abstimer_vars.bitmapInterruptsFired |= (1<<i);
        }
    }
    if ((abstimer_vars.bitmapInterruptsFired & (1<<ABSTIMER_SRC_RADIOTIMER_OVERFLOW)) &&
            (abstimer_vars.bitmapInterruptsFired & (1<<ABSTIMER_SRC_RADIOTIMER_COMPARE))) {
        abstimer_vars.bitmapInterruptsFired &= ~(1<<ABSTIMER_SRC_RADIOTIMER_COMPARE);
    }

    // make sure at least one timer fired
    if (abstimer_vars.bitmapInterruptsFired==0) {
        while(1);
    }

    //how many loops? -- this tells us how many timers have expired at the same time.
    abstimer_dbg.consecutive_late=0;

    //let's execute all of them..
    while (abstimer_vars.bitmapInterruptsFired!=0) {
//check that...
        while (abstimer_vars.bitmapInterruptsFired!=0) {
            //radiotimer overflow...
            if      (abstimer_vars.bitmapInterruptsFired & (1<<ABSTIMER_SRC_RADIOTIMER_OVERFLOW)) {

                // update debug stats
                abstimer_dbg.num_radiotimer_overflow++;

                // keep previous value -- this is now  poipoi
                abstimer_vars.radiotimer_overflow_previousVal = \
                        abstimer_vars.compareVal[ABSTIMER_SRC_RADIOTIMER_OVERFLOW];
                // remember compare val in case the callback modifies it.
                tempcompare = abstimer_vars.compareVal[ABSTIMER_SRC_RADIOTIMER_OVERFLOW];

                // call the callback
                abstimer_vars.callback[ABSTIMER_SRC_RADIOTIMER_OVERFLOW]();

                //==== step 2. Reschedule the timers which fired and need to be rescheduled

                // reschedule automatically if wasn't changed during callback
                if (abstimer_vars.compareVal[ABSTIMER_SRC_RADIOTIMER_OVERFLOW]==tempcompare) {
                    // this is a periodic timer, reschedule automatically -- only if the callback has not already set it.
                    abstimer_vars.compareVal[ABSTIMER_SRC_RADIOTIMER_OVERFLOW] += abstimer_vars.radiotimer_period;
                }

                // clear the interrupt flag
                abstimer_vars.bitmapInterruptsFired &= ~(1<<ABSTIMER_SRC_RADIOTIMER_OVERFLOW);
                //radiotimer compare inside the slot...
            } else if (abstimer_vars.bitmapInterruptsFired & (1<<ABSTIMER_SRC_RADIOTIMER_COMPARE)) {

                // update debug stats
                abstimer_dbg.num_radiotimer_compare++;

                // remember compare val
                tempcompare = abstimer_vars.compareVal[ABSTIMER_SRC_RADIOTIMER_COMPARE];

                // call the callback
                abstimer_vars.callback[ABSTIMER_SRC_RADIOTIMER_COMPARE]();
                // XV: I do not understand this ... why is rescheduled in the next slot?

                // reschedule automatically if wasn't changed during callback
                if (abstimer_vars.compareVal[ABSTIMER_SRC_RADIOTIMER_COMPARE]==tempcompare) {

                    // reschedule automatically after *overflow*
                    abstimer_vars.compareVal[ABSTIMER_SRC_RADIOTIMER_COMPARE]  = abstimer_vars.compareVal[ABSTIMER_SRC_RADIOTIMER_OVERFLOW]+ \
                            abstimer_vars.radiotimer_compare_offset;
                }

                // clear the interrupt flag
                abstimer_vars.bitmapInterruptsFired &= ~(1<<ABSTIMER_SRC_RADIOTIMER_COMPARE);
                //bsp timer
            } else if (abstimer_vars.bitmapInterruptsFired & (1<<ABSTIMER_SRC_BSP_TIMER)) {

                // update debug stats
                abstimer_dbg.num_bsp_timer++;

                // call the callback
                abstimer_vars.callback[ABSTIMER_SRC_BSP_TIMER]();

                // clear the interrupt flag
                abstimer_vars.bitmapInterruptsFired &= ~(1<<ABSTIMER_SRC_BSP_TIMER);

                // no automatic rescheduling

            }
        }

        // make sure all interrupts have been handled
        if (abstimer_vars.bitmapInterruptsFired!=0) {
            while(1);
        }

        //===== step 4. schedule the next operation

        abstimer_reschedule();

        //===== step 5. make sure I'm not late for my next schedule

        // evaluate how much time has passed since theoretical currentTime,
        // (over estimate by ABSTIMER_GUARD_TICKS)
        now   = sctimer_getValue(); //this gets the value of the counter
        timeSpent  = (uint16_t)((uint16_t)now-(uint16_t)abstimer_vars.currentTime);
        timeSpent += ABSTIMER_GUARD_TICKS;

        //debug -- to detect wraps...
        if (timeSpent > 65000) {
            //in case of negative wrap, lets say that a small time has elapsed.
            timeSpent=ABSTIMER_GUARD_TICKS;
        }

        // verify that, for each timer, that duration doesn't exceed how much time is left
        //find smallest next timer and mark it in the bitmap to be executed next. Can only be one marked at a time.
        min=0xFFFF;
        for (i=0; i<ABSTIMER_SRC_MAX; i++) {

            // calculate distance to next timeout
            calc = (uint16_t)abstimer_vars.compareVal[i]-(uint16_t)abstimer_vars.currentTime;

            if ((abstimer_vars.isArmed[i]==TRUE) && (timeSpent>calc) && (calc<min)) {
                //this is the nearest in time and we are already late or it is closer to its deadline, (distance < ABSTIMER_GUARD_TICKS)
                min=calc;
                // this interrupt needs to be serviced now
                abstimer_vars.bitmapInterruptsFired = (1<<i);
                // update the next timeout value
                abstimer_vars.nextCurrentTime=abstimer_vars.compareVal[i];
                // update debug statistics
                abstimer_dbg.num_late_schedule++;
                abstimer_dbg.consecutive_late++;

            }
        }
        if (abstimer_vars.bitmapInterruptsFired!=0) {
            abstimer_dbg.count_late++;

            //a timer (or more) is so close that we need to execute it right now. there are several problems:
            // 1) the isr function of that timer sets another timeout, also close in time, and the time it takes to execute the actual callback is higher
            //    than the difference between now and the next timeout.. this will cause a timer to be lost.
            // 2) if we set currentTime as the time where this late timeout is expecting to be executed, currentTime can be still in the future because
            //    the GUARD_TIME can be bigger than needed in this case. IN that situation, timeSpent will be "negative" .. i.e close to 65535 and will cause an
            //    execution of all the subsequent timers (during 2s) in isr mode... (looping here as all are "late")
            // 3) if we set currentTime ti now, the "late" timer can be in the past or in the future.. in case it is in the future, there is no problem, in case it is in the
            //    past and this timer sets another timeout, the timeout can also be in the past, causing an interrupt to be lost and possibly hanging the timer sequence for a while.

            //abstimer_vars.currentTime = now;//right now. + a guard time as we want to avoid that the distance calculation becomes negative.;
            abstimer_vars.currentTime = abstimer_vars.nextCurrentTime ;//this is the expected time... NOte that can be in the past!!
            //abstimer_vars.nextCurrentTime =  abstimer_vars.currentTime ; //next timer is right now as well

        }
    }

    //debug
    if (abstimer_dbg.nested_isr!=1) while(1);

    abstimer_dbg.nested_isr=0;
    sctimer_clearISR();
    debugpins_frame_clr();
    // kick the OS
    return KICK_SCHEDULER;
}