⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sched_up.c

📁 rtai-3.1-test3的源代码(Real-Time Application Interface )
💻 C
📖 第 1 页 / 共 4 页
字号:
}/** * @ingroup timer * @anchor rt_set_periodic_mode * @brief Set timer mode. * * rt_set_periodic_mode sets the periodic mode for the timer. It * consists of a fixed frequency timing of the tasks in multiple of * the period set with a call to @ref start_rt_timer(). The resolution * is that of the 8254 (1193180 Hz) on a UP machine, or if the 8254 * based SMP scheduler is being used. For the SMP scheduler timed by * the local APIC timer and for the MUP scheduler the timer resolution * is that of the local APIC timer frequency, generally the bus * frequency divided 16. Any timing request not being an integer * multiple of the set timer period is satisfied at the closest period * tick. It is the default mode when no call is made to set the * oneshot mode.  * * @note Stopping the timer by @ref stop_rt_timer() sets the timer back * into its default (periodic) mode. Always call @ref * rt_set_oneshot_mode() before each @ref start_rt_timer() if you want to * be sure to have it oneshot on multiple insmod without rmmoding the * RTAI scheduler in use.  */void rt_set_periodic_mode(void){	stop_rt_timer();	oneshot_timer = oneshot_running = 0;}/** * @ingroup timer * @anchor rt_set_oneshot_mode * @brief Set timer mode. * * rt_set_periodic_mode sets the periodic mode for the timer. It * consists of a fixed frequency timing of the tasks in multiple of * the period set with a call to @ref start_rt_timer(). The resolution * is that of the 8254 (1193180 Hz) on a UP machine, or if the 8254 * based SMP scheduler is being used. For the SMP scheduler timed by * the local APIC timer and for the MUP scheduler the timer resolution * is that of the local APIC timer frequency, generally the bus * frequency divided 16. Any timing request not being an integer * multiple of the set timer period is satisfied at the closest period * tick. It is the default mode when no call is made to set the * oneshot mode.  * * @note Stopping the timer by @ref stop_rt_timer() sets the timer back * into its default (periodic) mode. Always call @ref * rt_set_oneshot_mode() before each @ref start_rt_timer() if you want to * be sure to have it oneshot on multiple insmod without rmmoding the * RTAI scheduler in use.  */void rt_set_oneshot_mode(void){	stop_rt_timer();	oneshot_timer = 1;}int rt_get_timer_cpu(void){	return -EINVAL;}DECLR_8254_TSC_EMULATION;/** * @ingroup timer * @anchor start_rt_timer * @brief Start timer. * * start_rt_timer starts the timer with a period @e period. The * period is in internal count units and is required only for the * periodic mode. In the oneshot mode the period value is ignored. * This functions uses the 8254 with the UP and the 8254 based SMP * scheduler.  * Otherwise it uses a single local APIC with the APIC based SMP * schedulers and an APIC for each CPU with the MUP scheduler. In the * latter case all local APIC timers are paced in the same way, * according to the timer mode set. * * @return The period in internal count units. */RTIME start_rt_timer(int period){	unsigned long flags;	hard_save_flags_and_cli(flags);	if (oneshot_timer) {		SETUP_8254_TSC_EMULATION;		rt_request_timer(rt_timer_handler, 0, 0);		tuned.timers_tol[0] = rt_half_tick = tuned.latency;		oneshot_running = shot_fired = 1;	} else {		rt_request_timer(rt_timer_handler, period > LATCH ? LATCH : period, 0);		tuned.timers_tol[0] = rt_half_tick = (rt_times.periodic_tick + 1)>>1;	}	rt_time_h = rt_times.tick_time + rt_half_tick;	hard_restore_flags(flags);	rt_request_linux_irq(TIMER_8254_IRQ, recover_jiffies, "rtai_jif_chk", recover_jiffies);	return period;}RTIME start_rt_timer_cpuid(int period, int cpuid){	return start_rt_timer(period);}/** * @ingroup timer * @anchor start_rt_apic_timer * @brief Start local apic timer. *  * start_rt_apic_timers starts local APIC timers according to what is * found in @e setup_data. * * @param setup_mode is a pointer to an array of structures *        apic_timer_setup_data, see function rt_setup_apic_timers *        (FIXME) in RTAI module functions described further on in *        this manual. * @param rcvr_jiffies_cpuid is the CPU number whose time log has to *  	  be used to keep Linux timing and pacing in tune. *	  This function is specific to the MUP scheduler. If it is *	  called with either the UP or SMP scheduler it will use: *	  - a periodic timer if all local APIC timers are periodic *	    with the same period; *	  - a oneshot timer if all the local APIC timers are oneshot,  *	    or have different timing modes, are periodic with *	    different periods.  */void start_rt_apic_timers(struct apic_timer_setup_data *setup_mode, unsigned int rcvr_jiffies_cpuid){	int cpuid, period;	period = 0;	for (cpuid = 0; cpuid < NR_RT_CPUS; cpuid++) {		period += setup_mode[cpuid].mode;	}	if (period == NR_RT_CPUS) {		period = 2000000000;		for (cpuid = 0; cpuid < NR_RT_CPUS; cpuid++) {			if (setup_mode[cpuid].count < period) {				period = setup_mode[cpuid].count;			}		}		start_rt_timer(nano2count(period));		} else {		rt_set_oneshot_mode();		start_rt_timer(0);		}}/** * @ingroup timer * @anchor stop_rt_timer * @brief Stop timer. * * stop_rt_timer stops the timer. The timer mode is set to periodic. * * @return The period in internal count units. */void stop_rt_timer(void){	unsigned long flags;	rt_free_linux_irq(TIMER_8254_IRQ, recover_jiffies);	hard_save_flags_and_cli(flags);	CLEAR_8254_TSC_EMULATION;	rt_free_timer();	oneshot_timer = oneshot_running = 0;	hard_restore_flags(flags);}int rt_sched_type(void){	return RT_SCHED_UP;}/** * @ingroup tasks * @anchor rt_preempt_always * @brief Enable hard preemption * * In the oneshot mode the next timer expiration is programmed after a * timer shot by choosing among the timed tasks the one with a * priority higher than the task chosen to run as current, with the * constraint of always assuring a correct Linux timing. In such a * view there is no need to fire the timer immediately. In fact it can * happen that the current task can be so fast to get suspended and * rerun before the one that was devised to time the next shot when it * was made running. In such a view @b RTAI schedulers try to shoot * only when strictly needed. This minimizes the number of slow setups * of the 8254 timer used with UP and 8254 based SMP * schedulers. While such a policy minimizes the number of actual * shots, greatly enhancing efficiency, it can be unsuitable when an * application has to be guarded against undesired program loops or * other unpredicted error causes. * Calling these functions with a nonzero value assures that a timed * high priority preempting task is always programmed to be fired * while another task is currently running. The default is no * immediate preemption in oneshot mode, i.e. firing of the next shot * programmed only when strictly needed to satisfy tasks timings. * * @note With UP and SMP schedulers there is always only a timing * source so that cpu_idinrt_preempt_always_cpuid is not used. With * the MUP scheduler you have an independent timer for each CPU, so * rt_preempt_always applies to all the CPUs while * rt_preempt_always_cpuid should be used when preemption is to be * forced only on a specific CPU.  */void rt_preempt_always(int yes_no){	preempt_always = yes_no ? 1 : 0;}/** * @ingroup tasks * @anchor rt_preempt_always_cpuid * @brief Enable hard preemption * * In the oneshot mode the next timer expiration is programmed after a * timer shot by choosing among the timed tasks the one with a * priority higher than the task chosen to run as current, with the * constraint of always assuring a correct Linux timing. In such a * view there is no need to fire the timer immediately. In fact it can * happen that the current task can be so fast to get suspended and * rerun before the one that was devised to time the next shot when it * was made running. In such a view @b RTAI schedulers try to shoot * only when strictly needed. This minimizes the number of slow setups * of the 8254 timer used with UP and 8254 based SMP * schedulers. While such a policy minimizes the number of actual * shots, greatly enhancing efficiency, it can be unsuitable when an * application has to be guarded against undesired program loops or * other unpredicted error causes. * Calling these functions with a nonzero value assures that a timed * high priority preempting task is always programmed to be fired * while another task is currently running. The default is no * immediate preemption in oneshot mode, i.e. firing of the next shot * programmed only when strictly needed to satisfy tasks timings. * * @note With UP and SMP schedulers there is always only a timing * source so that cpu_idinrt_preempt_always_cpuid is not used. With * the MUP scheduler you have an independent timer for each CPU, so * rt_preempt_always applies to all the CPUs while * rt_preempt_always_cpuid should be used when preemption is to be * forced only on a specific CPU.  */void rt_preempt_always_cpuid(int yes_no, unsigned int cpuid){	rt_preempt_always(yes_no);}RT_TRAP_HANDLER rt_set_task_trap_handler( RT_TASK *task,					  unsigned int vec,					  RT_TRAP_HANDLER handler){	RT_TRAP_HANDLER old_handler;	if (!task || (vec >= RTAI_NR_TRAPS)) {		return (RT_TRAP_HANDLER) -EINVAL;	}	old_handler = task->task_trap_handler[vec];	task->task_trap_handler[vec] = handler;	return old_handler;}int rt_trap_handler(int vec, int signo, struct pt_regs *regs, void *dummy_data){        if (!rt_current) {		return 0;	}	if (rt_current->task_trap_handler[vec]) {                return rt_current->task_trap_handler[vec]( vec,                                                           signo,                                                           regs,                                                           rt_current);	}	rt_printk("Default Trap Handler: vector %d: Suspend RT task %p\n", vec,rt_current);	rt_task_suspend(rt_current);	rt_task_delete(rt_current); // In case the suspend does not work ?        return 1;}static int OneShot = ONE_SHOT;MODULE_PARM(OneShot, "i");static int Preempt_Always = PREEMPT_ALWAYS;MODULE_PARM(Preempt_Always, "i");static int LinuxFpu = LINUX_FPU;MODULE_PARM(LinuxFpu, "i");static int Latency = LATENCY_8254;MODULE_PARM(Latency, "i");static int SetupTimeTIMER = SETUP_TIME_8254;MODULE_PARM(SetupTimeTIMER, "i");static void frstk_srq_handler(void){	while (frstk_srq.out != frstk_srq.in) {		sched_free(frstk_srq.mp[frstk_srq.out]);		frstk_srq.out = (frstk_srq.out + 1) & (MAX_FRESTK_SRQ - 1);	}}static void init_sched_entries(void);/* ++++++++++++++++++++++++++ TIME CONVERSIONS +++++++++++++++++++++++++++++ *//** * @ingroup timer * @anchor count2nano * @brief Convert internal count units to nanoseconds. * * This function converts the time of timercounts internal count units * into nanoseconds. * Remember that the count units are related to the time base being  * used (see functions @ref rt_set_oneshot_mode() and @ref * rt_set_periodic_mode() for an explanation). * * @param counts internal count units. * * @return The given time in nanoseconds is returned. */RTIME count2nano(RTIME counts){	int sign;	if (counts > 0) {		sign = 1;	} else {		sign = 0;		counts = - counts;	}	counts = oneshot_timer ?	         llimd(counts, 1000000000, tuned.cpu_freq):	         llimd(counts, 1000000000, TIMER_FREQ);	return sign ? counts : - counts;}/** * @ingroup timer * @anchor nano2count * @brief Convert nanoseconds to internal count units. * * This function converts the time of nanosecs @e nanoseconds into * internal counts units. * Remember that the count units are related to the time base being * used (see functions @ref rt_set_oneshot_mode() and @ref * rt_set_periodic_mode() for an explanation). * * The versions ending with_cpuid are to be used with the MUP * scheduler since with such a scheduler it is possible to have * independent timers, i.e. periodic of different periods or a mixing * of periodic and oneshot, so that it is impossible to establish * which conversion units should be used in the case one asks for a * conversion from any CPU for any other CPU. All these functions have * the same behavior with UP and SMP schedulers.  * * @param ns Number of nanoseconds. * * @return The given time in nanoseconds is returned. */RTIME nano2count(RTIME ns){	int sign;	if (ns > 0) {		sign = 1;	} else {		sign = 0;		ns = - ns;	}	ns =  oneshot_timer ?	      llimd(ns, tuned.cpu_freq, 1000000000) :	      llimd(ns, TIMER_FREQ, 1000000000);	return sign ? ns : - ns;}/** * @ingroup timer * @anchor count2nano_cpuid * @brief Convert internal count units to nanoseconds. * * This function converts the time of timercounts internal count units * into nanoseconds. * It is to be used with the MUP scheduler since with such a scheduler * it is possible to have independent timers, i.e. periodic of * different periods or a mixing of periodic and oneshot, so that it * is impossible to establish which conversion units should be used in * the case one asks for a conversion from any CPU for any other * CPU. All these functions have the same behavior with UP and SMP * schedulers. * * @param counts internal count units.  * * @param cpuid Identifier of the CPU (FIXME). * * @return The given time in nanoseconds is returned. */RTIME count2nano_cpuid(RTIME counts, unsigned int cpuid){	return count2nano(counts);}/** * @ingroup timer * @anchor nano2count_cpuid * @brief Convert nanoseconds to internal count units. * * This function converts the time of nanosecs @e nanoseconds into * internal counts units. * Remember that the count units are related to the time base being * used (see functions @ref rt_set_oneshot_mode() and @ref * rt_set_periodic_mode() for an explanation). * * This function is to be used with the MUP scheduler since with such * a scheduler it is possible to have independent timers, * i.e. periodic of different periods or a mixing  of periodic and * oneshot, so that it is impossible to establish which conversion * units should be used in the case one asks for a conversion from * any CPU for any other CPU. All these functions have the same * behavior with UP and SMP schedulers. * * @param ns Number of nanoseconds. * * @param cpuid Identifier of the CPU (FIXME). * * @return The given time in nanoseconds is returned. */RTIME nano2count_cpuid(RTIME ns, unsigned int cpuid){	return nano2count(ns);}/* +++++++++++++++++++++++++++++++ TIMINGS ++++++++++++++++++++++++++++++++++ *//**

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -