コード例 #1
0
static void rt_timer_tick(void)
{
	cpu_used[NR_RT_CPUS]++;
	if (passed++ < 5) {
		t0 = rdtsc();
	} else {
		t = rdtsc();
		if ((jit = t - t0 - imuldiv(rt_times.periodic_tick, CPU_FREQ, FREQ_8254)) < 0) {
			jit = -jit;
		}
		if (jit > maxj) {
			maxj = jit;
		}
		t0 = t;
	}

	rt_times.tick_time = rt_times.intr_time;
	rt_times.intr_time = rt_times.tick_time + rt_times.periodic_tick;
	rt_set_timer_delay(0);
	if (rt_times.tick_time >= rt_times.linux_time) {
		rt_times.linux_time += rt_times.linux_tick;
		rt_pend_linux_irq(TIMER_8254_IRQ);
	} 
	if (Mode) {
		rt_sem_signal(&sem);
	} else {
		rt_task_resume(&thread);
	}
}
コード例 #2
0
static int rt_timer_tick_ext(int irq, unsigned long data)
{
	RTIME t;
	int jit;

	if (loops++ < INILOOPS) {
		t0 = rdtsc();
	} else {
		t = rdtsc();
		if (use_parport) {
			outb(bit = 1 - bit, PARPORT); 
		}
		if ((jit = abs((int)(t - t0) - bus_period)) > maxj) {
			maxj = jit;
			if (maxj > bus_threshold) {
				int msg;
				msg = imuldiv(maxj, 1000000000, CPU_FREQ);
				rtf_put(0, &msg, sizeof(msg));
			}
		}
		t0 = t;
	}
	rt_times.tick_time = rt_times.intr_time;
	rt_times.intr_time = rt_times.tick_time + rt_times.periodic_tick;
	rt_set_timer_delay(0);
	if (rt_times.tick_time >= rt_times.linux_time) {
		rt_times.linux_time += rt_times.linux_tick;
		hard_sti();
		rt_pend_linux_irq(TIMER_8254_IRQ);
		return 0;
	} 
	hard_sti();
	return 1;
}
コード例 #3
0
static int rt_timer_tick_ext(int irq, unsigned long data)
{
	int ret = 1;
	cpu_used[NR_RT_CPUS]++;
	if (passed++ < 5) {
		t0 = rdtsc();
	} else {
		t = rdtsc();
		if ((jit = t - t0 - imuldiv(rt_times.periodic_tick, CPU_FREQ, FREQ_8254)) < 0) {
			jit = -jit;
		}
		if (jit > maxj) {
			maxj = jit;
		}
		t0 = t;
	}

	rt_times.tick_time = rt_times.intr_time;
	rt_times.intr_time = rt_times.tick_time + rt_times.periodic_tick;
	rt_set_timer_delay(0);
	if (rt_times.tick_time >= rt_times.linux_time) {
		rt_times.linux_time += rt_times.linux_tick;
		rt_pend_linux_irq(TIMER_8254_IRQ);
		ret = 0;
	} 
rt_sched_lock();
	if (Mode) {
		rt_sem_signal(&sem);
	} else {
		rt_task_resume(&thread);
	}
rt_sched_unlock();
	return ret;
}
コード例 #4
0
ファイル: handler.c プロジェクト: ArcEye/3.4.55-rtai
static void timer_tick(void)
{
	rt_times.tick_time = rt_times.intr_time;
	rt_times.intr_time = rt_times.tick_time + rt_times.periodic_tick;
	rt_set_timer_delay(0);
	if (rt_times.tick_time >= rt_times.linux_time) {
		rt_times.linux_time += rt_times.linux_tick;
		rt_pend_linux_irq(TIMER_8254_IRQ);
	}
	if (run) {
		if (rt_waiting_return(tasknode, taskport)) {
			overuns++;
		}
		switch(run) {
			case 1: RT_sem_signal(tasknode, -taskport, rmt_sem);
				rt_printk("SEM SIGNAL %d\n", ++cnt);
				break;
			case 2:
				RT_task_resume(tasknode, -taskport, rmt_task);
				rt_printk("TASK RESUME %d\n", ++cnt);
				break;
			case 3:
				RT_send_if(tasknode, -taskport, rmt_task, run);
				rt_printk("TASK SEND %d\n", ++cnt);
				break;
		}
	}
}
コード例 #5
0
ファイル: at91-timer.c プロジェクト: ArcEye/RTAI
int rtai_calibrate_TC (void)
{
	unsigned long flags;
	RTIME t, dt;
	int i;

	flags = rtai_critical_enter(NULL);
	rt_set_timer_delay(LATCH);
	t = rtai_rdtsc();
	for (i = 0; i < 10000; i++) { 
		rt_set_timer_delay(LATCH);
	}
	dt = rtai_rdtsc() - t;
	rtai_critical_exit(flags);

	return rtai_imuldiv(dt, 100000, RTAI_CPU_FREQ);
}
コード例 #6
0
ファイル: at91-timer.c プロジェクト: ArcEye/RTAI
void rt_free_timer (void)
{
	unsigned long flags;

	rt_periodic = 0;
	__ipipe_mach_timerstolen = 0;		// ipipe can reprogram timer for Linux now
	at91_tc_write(AT91_TC_CMR, AT91_TC_TIMER_CLOCK3); // back to oneshot mode
	rt_set_timer_delay(__ipipe_mach_ticks_per_jiffy); // regular timer delay
	rt_release_irq(RTAI_TIMER_IRQ);		// free this irq
	rtai_save_flags_and_cli(flags);		// critical section
	extern_timer_isr = NULL;		// let ipipe run as normally
	rtai_restore_flags(flags);		// end of critical section
}
コード例 #7
0
ファイル: fastick2.c プロジェクト: ArcEye/RTAI
static void rt_timer_tick(void)
{
	char wakeup;
	rtf_put(CMDF, &wakeup, sizeof(wakeup));
	rt_times.tick_time = rt_times.intr_time;
	rt_times.intr_time = rt_times.tick_time + rt_times.periodic_tick;
	rt_set_timer_delay(0);
	if (rt_times.tick_time >= rt_times.linux_time) {
		if (rt_times.linux_tick > 0) {
			rt_times.linux_time += rt_times.linux_tick;
		}
		rt_pend_linux_irq(TIMER_8254_IRQ);
	} 
}
コード例 #8
0
ファイル: at91-timer.c プロジェクト: ArcEye/RTAI
int rt_request_timer (void (*handler)(void), unsigned tick, int use_apic)
{
	unsigned long flags;

	flags = rtai_critical_enter(NULL);

	__ipipe_mach_timerstolen = 1;		// no need to reprogram timer on timer_tick() call

	rt_times.tick_time = rtai_rdtsc();
	rt_times.linux_tick = __ipipe_mach_ticks_per_jiffy;
	if (tick > 0) {
		rt_periodic = 1;

		/* Periodic setup --
		Use the built-in Adeos service directly. */
		if (tick > __ipipe_mach_ticks_per_jiffy) {
			tick = __ipipe_mach_ticks_per_jiffy;
		}
		rt_times.intr_time = rt_times.tick_time + tick;
		rt_times.linux_time = rt_times.tick_time + rt_times.linux_tick;
		rt_times.periodic_tick = tick;

		/* Prepare TCx to reload automaticly on RC compare */
		at91_tc_write(AT91_TC_CCR, AT91_TC_CLKDIS);
		at91_tc_write(AT91_TC_CMR, AT91_TC_TIMER_CLOCK3 | AT91_TC_WAVESEL_UP_AUTO | AT91_TC_WAVE);
		at91_tc_write(AT91_TC_RC, rt_times.periodic_tick);
		at91_tc_write(AT91_TC_CCR, AT91_TC_CLKEN | AT91_TC_SWTRG);
	} else {
		rt_periodic = 0;

		/* Oneshot setup. */
		rt_times.intr_time = rt_times.tick_time + rt_times.linux_tick;
		rt_times.linux_time = rt_times.tick_time + rt_times.linux_tick;
		rt_times.periodic_tick = rt_times.linux_tick;

		/* Prepare TCx behaviour as oneshot timer */
		at91_tc_write(AT91_TC_CMR, AT91_TC_TIMER_CLOCK3);
		rt_set_timer_delay(rt_times.periodic_tick);
	}

        rt_release_irq(RTAI_TIMER_IRQ);

	rt_request_irq(RTAI_TIMER_IRQ, (rt_irq_handler_t)handler, NULL, 0);
	extern_timer_isr = rtai_timer_handler;	// shunt for ipipe.c __ipipe_grab_irq

	rtai_critical_exit(flags);

        return 0;
}
コード例 #9
0
ファイル: hal.c プロジェクト: ArcEye/RTAI
int rt_request_timer (void (*handler)(void), unsigned tick, int use_apic)
{
	unsigned long flags;

	rtai_save_flags_and_cli(flags);

	// read tick values: current time base register and linux tick
	rt_times.tick_time = rtai_rdtsc();
	rt_times.linux_tick = tb_ticks_per_jiffy;
    	if (tick > 0) { // periodic Mode
		// if tick is greater than tb_ticks_per_jiffy schedule a linux timer first
		if (tick > tb_ticks_per_jiffy) {
			tick = tb_ticks_per_jiffy;
		}
		rt_times.intr_time = rt_times.tick_time + tick;
		rt_times.linux_time = rt_times.tick_time + rt_times.linux_tick;
		rt_times.periodic_tick = tick;
#ifdef CONFIG_40x
		/* Set the PIT auto-reload mode */
		mtspr(SPRN_TCR, mfspr(SPRN_TCR) | TCR_ARE);
		/* Set the PIT reload value and just let it run. */
		mtspr(SPRN_PIT, tick);
#endif /* CONFIG_40x */
	} else { //one-shot Mode
		// in this mode we set all to decade at linux_tick
		rt_times.intr_time = rt_times.tick_time + rt_times.linux_tick;
		rt_times.linux_time = rt_times.tick_time + rt_times.linux_tick;
		rt_times.periodic_tick = rt_times.linux_tick;
#ifdef CONFIG_40x
		/* Disable the PIT auto-reload mode */
		mtspr(SPRN_TCR, mfspr(SPRN_TCR) & ~TCR_ARE);
#endif /* CONFIG_40x */
	}

	// request an IRQ and register it
	rt_release_irq(RTAI_TIMER_DECR_IRQ);
	decr_timer_handler = handler;

	// pass throught ipipe: register immediate timer_trap handler
	// on i386 for a periodic mode is rt_set_timer_delay(tick); -> is set rate generator at tick; in one shot set LATCH all for the 8254 timer. Here is the same.
	rtai_disarm_decr(rtai_cpuid(), 1);
	rt_set_timer_delay(rt_times.periodic_tick);
	rtai_set_gate_vector(DECR_VECTOR, rtai_decr_timer_handler, 0);

	rtai_request_tickdev();
	rtai_restore_flags(flags);
	return 0;
}
コード例 #10
0
ファイル: ktasklet.c プロジェクト: cjecho/RTAI
static void rt_timer_tick(void)
{
	struct rt_tasklet_struct *tasklet;
	rt_times.tick_time = rt_times.intr_time;
	rt_times.intr_time = rt_times.tick_time + rt_times.periodic_tick;
	rt_set_timer_delay(0);
	if (rt_times.tick_time >= rt_times.linux_time) {
		if (rt_times.linux_tick > 0) {
			rt_times.linux_time += rt_times.linux_tick;
		}
		rt_pend_linux_irq(TIMER_8254_IRQ);
	}
	if ((tasklet = rt_find_tasklet_by_id(nam2num("TSKLET")))) {
		rt_exec_tasklet(tasklet);
	}
}
コード例 #11
0
ファイル: handler.c プロジェクト: ArcEye/3.4.55-rtai
static void timer_tick(void)
{
	rt_times.tick_time = rt_times.intr_time;
	rt_times.intr_time = rt_times.tick_time + rt_times.periodic_tick;
	rt_set_timer_delay(0);
	if (rt_times.tick_time >= rt_times.linux_time) {
		if (rt_times.linux_tick) {
			rt_times.linux_time += rt_times.linux_tick;
		}
		rt_pend_linux_irq(TIMER_8254_IRQ);
	}
	if (run) {
		if (rt_waiting_return(tasknode, taskport)) {
			overuns++;
		}
		rt_task_resume(&sup_task);
	}
}
コード例 #12
0
ファイル: hal.c プロジェクト: ArcEye/RTAI
int rt_request_timers(void *rtai_time_handler)
{
	int cpuid;

	if (!rt_linux_hrt_next_shot) {
		rt_linux_hrt_next_shot = _rt_linux_hrt_next_shot;
	}
	for (cpuid = 0; cpuid < num_active_cpus(); cpuid++) {
		struct rt_times *rtimes;
		int ret;
		ret = ipipe_timer_start(rtai_time_handler, rt_linux_hrt_set_mode, rt_linux_hrt_next_shot, cpuid);
		if (ret < 0 || ret == CLOCK_EVT_MODE_SHUTDOWN) {
			printk("THE TIMERS REQUEST FAILED RETURNING %d FOR CPUID %d, FREEING ALL TIMERS.\n", ret, cpuid);
			do {
				ipipe_timer_stop(cpuid);
			} while (--cpuid >= 0);
			return -1;
		}
		rtimes = &rt_smp_times[cpuid];
		if (ret == CLOCK_EVT_MODE_ONESHOT || ret == CLOCK_EVT_MODE_UNUSED) {
			rtimes->linux_tick = 0;
		} else {
			rt_smp_times[0].linux_tick = rtai_llimd((1000000000 + HZ/2)/HZ, rtai_tunables.clock_freq, 1000000000);
		}			
		rtimes->tick_time  = rtai_rdtsc();
                rtimes->intr_time  = rtimes->tick_time + rtimes->linux_tick;
                rtimes->linux_time = rtimes->tick_time + rtimes->linux_tick;
		rtimes->periodic_tick = rtimes->linux_tick;
	}
#if 0 // #ifndef CONFIG_X86_LOCAL_APIC, for calibrating 8254 with our set delay
	rtai_cli();
	outb(0x30, 0x43);
	rt_set_timer_delay(rtai_tunables.clock_freq/50000);
	rtai_sti();
#endif
	return 0;
}