コード例 #1
0
ファイル: lwb-g-sync.c プロジェクト: kasunch/lwb
//--------------------------------------------------------------------------------------------------
static inline void lwb_estimate_skew() {

    uint16_t t_diff = CURRENT_SCHEDULE_INFO().time - OLD_SCHEDULE_INFO().time;
    // The maximum time that can be measured with rtimer (32 kHz) is 2.048 seconds before integer wrap-round.
    // This is due to 16-bit counters are used in Glossy.
    // Therefore, if t_diff is a multiple of 2, then we do not need to use it for skew calculation.
    int16_t skew_tmp = lwb_context.t_sync_ref - (lwb_context.t_last_sync_ref + (uint16_t)RTIMER_SECOND * (t_diff % 2));

    if (skew_tmp < 500 && t_diff != 0) {

        /// @todo Why 64 is used in here.
        ///       I think 64 is used to make skew_tmp large. The skew_tmp is calculated in rtimer
        ///       clock ticks. If it is smaller than t_diff, clock skew per unit time becomes zero.
        ///       Therefore, skew_tmp is multiplied by 64 to make it larger.
        lwb_context.skew = (int32_t)(64 * (int32_t)skew_tmp) / (int32_t)t_diff;
        /// @todo "dirty hack" to temporary fix a Glossy bug that rarely occurs in disconnected networks
        OLD_SCHEDULE_INFO().time = CURRENT_SCHEDULE_INFO().time;
        lwb_context.t_last_sync_ref = GLOSSY_T_REF;

    } else {

        lwb_context.sync_state = LWB_SYNC_STATE_BOOTSTRAP;
        set_t_ref_l_updated(0);
    }
}
コード例 #2
0
ファイル: glossy-test.c プロジェクト: Conrad2210/Glossy_hda
char glossy_scheduler(struct rtimer *t, void *ptr) {
	PT_BEGIN(&pt);

	if (IS_INITIATOR()) {	// Glossy initiator.
		while (1) {
			printf("[SCHEDULER]: Get Data from queue\n");
			// Increment sequence number.
			glossy_data.seq_no++;
			// Glossy phase.
			leds_on(LEDS_GREEN);
			rtimer_clock_t t_stop = RTIMER_TIME(t) + GLOSSY_DURATION;
			// Start Glossy.
			glossy_start((uint8_t *)&glossy_data, DATA_LEN, GLOSSY_INITIATOR, GLOSSY_SYNC, N_TX,
					APPLICATION_HEADER, t_stop, (rtimer_callback_t)glossy_scheduler, t, ptr);
			// Store time at which Glossy has started.
			t_start = RTIMER_TIME(t);
			// Yield the protothread. It will be resumed when Glossy terminates.
			PT_YIELD(&pt);

			// Off phase.
			leds_off(LEDS_GREEN);
			// Stop Glossy.
			glossy_stop();
			if (!GLOSSY_IS_BOOTSTRAPPING()) {
				// Glossy has already successfully bootstrapped.
				if (!GLOSSY_IS_SYNCED()) {
					// The reference time was not updated: increment reference time by GLOSSY_PERIOD.
					set_t_ref_l(GLOSSY_REFERENCE_TIME + GLOSSY_PERIOD);
					set_t_ref_l_updated(1);
				}
			}
			// Schedule begin of next Glossy phase based on GLOSSY_PERIOD.
			rtimer_set(t, t_start + GLOSSY_PERIOD, 1, (rtimer_callback_t)glossy_scheduler, ptr);
			// Estimate the clock skew over the last period.
			estimate_period_skew();
			// Poll the process that prints statistics (will be activated later by Contiki).
			process_poll(&glossy_print_stats_process);
			// Yield the protothread.
			PT_YIELD(&pt);
		}
	} else {	// Glossy receiver.
		while (1) {
			// Glossy phase.
			leds_on(LEDS_GREEN);
			rtimer_clock_t t_stop;
			if (GLOSSY_IS_BOOTSTRAPPING()) {
				// Glossy is still bootstrapping:
				// Schedule end of Glossy phase based on GLOSSY_INIT_DURATION.
				t_stop = RTIMER_TIME(t) + GLOSSY_INIT_DURATION;
			} else {
				// Glossy has already successfully bootstrapped:
				// Schedule end of Glossy phase based on GLOSSY_DURATION.
				t_stop = RTIMER_TIME(t) + GLOSSY_DURATION;
			}
			// Start Glossy.
			glossy_start((uint8_t *)&glossy_data, DATA_LEN, GLOSSY_RECEIVER, GLOSSY_SYNC, N_TX,
					APPLICATION_HEADER, t_stop, (rtimer_callback_t)glossy_scheduler, t, ptr);
			// Yield the protothread. It will be resumed when Glossy terminates.
			PT_YIELD(&pt);

			// Off phase.
			leds_off(LEDS_GREEN);
			// Stop Glossy.
			glossy_stop();
			if (GLOSSY_IS_BOOTSTRAPPING()) {
				// Glossy is still bootstrapping.
				if (!GLOSSY_IS_SYNCED()) {
					// The reference time was not updated: reset skew_estimated to zero.
					skew_estimated = 0;
				}
			} else {
				// Glossy has already successfully bootstrapped.
				if (!GLOSSY_IS_SYNCED()) {
					// The reference time was not updated:
					// increment reference time by GLOSSY_PERIOD + period_skew.
					set_t_ref_l(GLOSSY_REFERENCE_TIME + GLOSSY_PERIOD + period_skew);
					set_t_ref_l_updated(1);
					// Increment sync_missed.
					sync_missed++;
				} else {
					// The reference time was not updated: reset sync_missed to zero.
					sync_missed = 0;
				}
			}
			// Estimate the clock skew over the last period.
			estimate_period_skew();
			if (GLOSSY_IS_BOOTSTRAPPING()) {
				// Glossy is still bootstrapping.
				if (skew_estimated == 0) {
					// The reference time was not updated:
					// Schedule begin of next Glossy phase based on last begin and GLOSSY_INIT_PERIOD.
					rtimer_set(t, RTIMER_TIME(t) + GLOSSY_INIT_PERIOD, 1,
							(rtimer_callback_t)glossy_scheduler, ptr);
				} else {
					// The reference time was updated:
					// Schedule begin of next Glossy phase based on reference time and GLOSSY_INIT_PERIOD.
					rtimer_set(t, GLOSSY_REFERENCE_TIME + GLOSSY_PERIOD - GLOSSY_INIT_GUARD_TIME, 1,
							(rtimer_callback_t)glossy_scheduler, ptr);
				}
			} else {
				// Glossy has already successfully bootstrapped:
				// Schedule begin of next Glossy phase based on reference time and GLOSSY_PERIOD.
				rtimer_set(t, GLOSSY_REFERENCE_TIME + GLOSSY_PERIOD +
						period_skew - GLOSSY_GUARD_TIME * (1 + sync_missed), 1,
						(rtimer_callback_t)glossy_scheduler, ptr);
			}
			// Poll the process that prints statistics (will be activated later by Contiki).
			process_poll(&glossy_print_stats_process);
			// Yield the protothread.
			PT_YIELD(&pt);
		}
	}

	PT_END(&pt);
}