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

📄 sched_up.c

📁 rtai-3.1-test3的源代码(Real-Time Application Interface )
💻 C
📖 第 1 页 / 共 4 页
字号:
 * @ingroup timer * @anchor rt_get_time * @brief Get the current time. * * rt_get_time returns the time, in internal count units, since * start_rt_timer was called. In periodic mode this number is in * multiples of the periodic tick. In oneshot mode it is directly the * TSC count for CPUs having a time stamp clock (TSC), while it is a * (FIXME) on 8254 units for those not having it (see functions @ref * rt_set_oneshot_mode() and @ref rt_set_periodic_mode() for an * explanation).  * * @return The current time in internal count units is returned. */RTIME rt_get_time(void){	return oneshot_timer ? rdtsc() : rt_times.tick_time;}/** * @ingroup timer * @anchor rt_get_time_cpuid * @brief Get the current time. * * rt_get_time_cpuid returns the time, in internal count units, since * start_rt_timer was called. In periodic mode this number is in * multiples of the periodic tick. In oneshot mode it is directly the * TSC count for CPUs having a time stamp clock (TSC), while it is a * (FIXME) on 8254 units for those not having it (see functions @ref * rt_set_oneshot_mode() and @ref rt_set_periodic_mode() for an * explanation).  * This version ending with _cpuid must be used with the MUP * scheduler when there is the need to declare from which cpuid the  * time must be gotten (FIXME). In fact one can need to get the time * of another CPU and timers can differ from CPU to CPU. (FIXME) * All these functions have the same behavior with UP and SMP * schedulers. * * @param cpuid corresponds to the CPUI identifier. * * @return The current time in internal count units is returned. */RTIME rt_get_time_cpuid(unsigned int cpuid){	return oneshot_timer ? rdtsc(): rt_times.tick_time;}/** * @ingroup timer * @anchor rt_get_time_ns * @brief Get the current time. * * rt_get_time_ns is the same as @ref rt_get_time() but the returned * time is converted to nanoseconds.  * * @return The current time in internal count units is returned. */RTIME rt_get_time_ns(void){	return oneshot_timer ?	       llimd(rdtsc(), 1000000000, tuned.cpu_freq) :	       llimd(rt_times.tick_time, 1000000000, TIMER_FREQ);}/** * @ingroup timer * @anchor rt_get_time_ns_cpuid * @brief Get the current time. * * rt_get_time_ns is the same as rt_get_time but the returned time is * converted to nanoseconds. * The version ending with _cpuid must be used with the MUP scheduler * when there is the need to declare from which cpuidthe time must be * got. In fact one can need to get the time of another CPU and timers * can differ from CPU to CPU.  * All these functions have the same behavior with UP and SMP * schedulers.  * * @param cpuid corresponds to the CPUI identifier. * * @return The current time in internal count units is returned. */RTIME rt_get_time_ns_cpuid(unsigned int cpuid){	return oneshot_timer ?	       llimd(rdtsc(), 1000000000, tuned.cpu_freq) :	       llimd(rt_times.tick_time, 1000000000, TIMER_FREQ);}/** * @ingroup timer * @anchor rt_get_cpu_time_ns * @brief Get the current time. * * rt_get_cpu_time_ns always returns the CPU time in nanoseconds * whatever timer is in use. * * @return The current time in internal count units is returned. */RTIME rt_get_cpu_time_ns(void){	return llimd(rdtsc(), 1000000000, tuned.cpu_freq);}/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */RT_TASK *rt_get_base_linux_task(RT_TASK **base_linux_tasks){        return (base_linux_tasks[0] = &rt_linux_task);}RT_TASK *rt_alloc_dynamic_task(void){#ifdef CONFIG_RTAI_MALLOC        return rt_malloc(sizeof(RT_TASK)); // For VC's, proxies and C++ support.#else	return NULL;#endif}RT_TASK **rt_register_watchdog(RT_TASK *wd, int cpuid){    	RT_TASK	*task;    	if (wdog_task) return (RT_TASK**) -EBUSY;	task = &rt_linux_task;	while ((task = task->next)) {	    	if (task != wd && task->priority == RT_SCHED_HIGHEST_PRIORITY) {		    	return (RT_TASK**) -EBUSY;		}	}    	wdog_task = wd;	return (RT_TASK**) 0;}void rt_deregister_watchdog(RT_TASK *wd, int cpuid){    	if (wdog_task != wd) return;    	wdog_task = NULL;}/* ++++++++++++++ SCHEDULER ENTRIES AND RELATED INITIALISATION ++++++++++++++ */struct rt_fun_entry rt_fun_lxrt[MAX_LXRT_FUN];#if CONFIG_RTAI_NETRPC#include <rtai_registry.h>static struct rt_native_fun_entry rt_sched_entries[] = {	{ { 0, rt_named_task_init },		    NAMED_TASK_INIT },  	{ { 0, rt_named_task_init_cpuid },	    NAMED_TASK_INIT_CPUID },  	{ { 0, rt_named_task_delete },	 	    NAMED_TASK_DELETE },  	{ { 1, rt_task_yield },			    YIELD },  	{ { 1, rt_task_suspend },		    SUSPEND },	{ { 1, rt_task_resume },		    RESUME },	{ { 1, rt_task_make_periodic },		    MAKE_PERIODIC },	{ { 1, rt_task_wait_period },		    WAIT_PERIOD },	{ { 1, rt_sleep },			    SLEEP },	{ { 1, rt_sleep_until },		    SLEEP_UNTIL },	{ { 0, start_rt_timer },		    START_TIMER },	{ { 0, stop_rt_timer },			    STOP_TIMER },	{ { 0, rt_get_time },			    GET_TIME },	{ { 0, count2nano },			    COUNT2NANO },	{ { 0, nano2count },			    NANO2COUNT },	{ { 0, rt_busy_sleep },			    BUSY_SLEEP },	{ { 0, rt_set_periodic_mode },		    SET_PERIODIC_MODE },	{ { 0, rt_set_oneshot_mode },		    SET_ONESHOT_MODE },	{ { 0, rt_task_signal_handler },	    SIGNAL_HANDLER  },	{ { 0, rt_task_use_fpu },		    TASK_USE_FPU },	{ { 0, rt_linux_use_fpu },		    LINUX_USE_FPU },	{ { 0, rt_preempt_always },		    PREEMPT_ALWAYS_GEN },	{ { 0, rt_get_time_ns },		    GET_TIME_NS },	{ { 0, rt_get_cpu_time_ns },		    GET_CPU_TIME_NS },	{ { 0, rt_set_runnable_on_cpus },	    SET_RUNNABLE_ON_CPUS },	{ { 0, rt_set_runnable_on_cpuid },	    SET_RUNNABLE_ON_CPUID },	{ { 0, rt_get_timer_cpu },		    GET_TIMER_CPU },	{ { 0, start_rt_apic_timers },		    START_RT_APIC_TIMERS },	{ { 0, rt_preempt_always_cpuid },	    PREEMPT_ALWAYS_CPUID },	{ { 0, count2nano_cpuid },		    COUNT2NANO_CPUID },	{ { 0, nano2count_cpuid },		    NANO2COUNT_CPUID },	{ { 0, rt_get_time_cpuid },		    GET_TIME_CPUID },	{ { 0, rt_get_time_ns_cpuid },		    GET_TIME_NS_CPUID },	{ { 1, rt_task_make_periodic_relative_ns }, MAKE_PERIODIC_NS },	{ { 0, rt_set_sched_policy },		    SET_SCHED_POLICY },	{ { 1, rt_task_set_resume_end_times },	    SET_RESUME_END },	{ { 0, rt_spv_RMS },			    SPV_RMS },	{ { 0, rt_task_wakeup_sleeping },	    WAKEUP_SLEEPING },	{ { 1, rt_change_prio },		    CHANGE_TASK_PRIO },	{ { 0, rt_set_resume_time },  		    SET_RESUME_TIME },	{ { 0, rt_set_period },			    SET_PERIOD },	{ { 0, rt_is_hard_timer_running },	    HARD_TIMER_RUNNING },	{ { 0, rt_get_adr },			    GET_ADR },	{ { 0, rt_get_name },			    GET_NAME },	{ { 0, 0 },			            000 }};static void nihil(void) { };struct rt_fun_entry rt_fun_lxrt[MAX_LXRT_FUN];void reset_rt_fun_entries(struct rt_native_fun_entry *entry){	while (entry->fun.fun) {		if (entry->index >= MAX_LXRT_FUN) {			rt_printk("*** RESET ENTRY %d FOR USER SPACE CALLS EXCEEDS ALLOWD TABLE SIZE %d, NOT USED ***\n", entry->index, MAX_LXRT_FUN);		} else {			rt_fun_lxrt[entry->index] = (struct rt_fun_entry){ 1, nihil };		}		entry++;        }}int set_rt_fun_entries(struct rt_native_fun_entry *entry){	int error;	error = 0;	while (entry->fun.fun) {		if (rt_fun_lxrt[entry->index].fun != nihil) {			rt_printk("*** SUSPICIOUS ENTRY ASSIGNEMENT FOR USER SPACE CALL AT %d, DUPLICATED INDEX OR REPEATED INITIALIZATION ***\n", entry->index);			error = -1;		} else if (entry->index >= MAX_LXRT_FUN) {			rt_printk("*** ASSIGNEMENT ENTRY %d FOR USER SPACE CALLS EXCEEDS ALLOWED TABLE SIZE %d, NOT USED ***\n", entry->index, MAX_LXRT_FUN);			error = -1;		} else {			rt_fun_lxrt[entry->index] = entry->fun;		}		entry++;        }	if (error) {		reset_rt_fun_entries(entry);	}	return 0;}static void init_sched_entries(void){	int i;	for (i = 0; i < MAX_LXRT_FUN; i++) {		rt_fun_lxrt[i] = (struct rt_fun_entry) { 1, nihil };	}	set_rt_fun_entries(rt_sched_entries);}#elsevoid reset_rt_fun_entries(struct rt_native_fun_entry *entry){}int set_rt_fun_entries(struct rt_native_fun_entry *entry){	return 0;}static void init_sched_entries(void){}#endifint set_rt_fun_ext_index(struct rt_fun_entry *fun, int idx){	return -EACCES;}void reset_rt_fun_ext_index( struct rt_fun_entry *fun, int idx){	return;}/* ++++++++++++++++++++++++++ SCHEDULER PROC FILE +++++++++++++++++++++++++++ */#ifdef CONFIG_PROC_FS/* ----------------------< proc filesystem section >----------------------*/static int rtai_read_sched(char *page, char **start, off_t off, int count,                           int *eof, void *data){	PROC_PRINT_VARS;	unsigned int i = 1;	unsigned long t;	RT_TASK *task;	task = &rt_linux_task;	PROC_PRINT("\nRTAI Uniprocessor Real Time Task Scheduler.\n\n");	PROC_PRINT("    Calibrated CPU Frequency: %lu Hz\n", (unsigned long)tuned.cpu_freq);	PROC_PRINT("    Calibrated timer interrupt to scheduler latency: %d ns\n", imuldiv(tuned.latency - tuned.setup_time_TIMER_CPUNIT, 1000000000, tuned.cpu_freq));	PROC_PRINT("    Calibrated one shot setup time: %d ns\n\n",                  imuldiv(tuned.setup_time_TIMER_CPUNIT, 1000000000, tuned.cpu_freq));        PROC_PRINT("Number of RT CPUs in system: %d\n\n", NR_RT_CPUS);        PROC_PRINT("Priority  Period(ns)  FPU  Sig  State  Task  RT_TASK *  TIME\n" );        PROC_PRINT("-------------------------------------------------------------\n" );/** Display all the active RT tasks and their state.** Note: As a temporary hack the tasks are given an id which is*       the order they appear in the task list, needs fixing!*/	while ((task = task->next)) {/** The display for the task period is set to an integer (%d) as 64 bit* numbers are not currently handled correctly by the kernel routines.* Hence the period display will be wrong for time periods > ~4 secs.*/			if ((!task->lnxtsk || task->is_hard) && task->exectime[1]) {				t = 1000UL*(unsigned long)llimd(task->exectime[0], 10, tuned.cpu_freq)/(unsigned long)llimd(rdtsc() - task->exectime[1], 10, tuned.cpu_freq);			} else {			       t = 0;			}                PROC_PRINT("%-9d %-11lu %-4s %-4s 0x%-4x %-4d  %p   %-lu\n",                               task->priority,                               (unsigned long)count2nano(task->period),                               task->uses_fpu ? "Yes" : "No",                               task->signal ? "Yes" : "No",                               task->state,                               i, task, t);		i++;	}        PROC_PRINT("TIMED\n");        task = &rt_linux_task;        while ((task = task->tnext) != &rt_linux_task) {                PROC_PRINT("> %p ", task);        }        PROC_PRINT("\nREADY\n");        task = &rt_linux_task;        while ((task = task->rnext) != &rt_linux_task) {                PROC_PRINT("> %p ", task);        }        PROC_PRINT("\n");	PROC_PRINT_DONE;}  /* End function - rtai_read_sched */static int rtai_proc_sched_register(void) {        struct proc_dir_entry *proc_sched_ent;        proc_sched_ent = create_proc_entry("scheduler", S_IFREG|S_IRUGO|S_IWUSR, rtai_proc_root);        if (!proc_sched_ent) {                printk("Unable to initialize /proc/rtai/scheduler\n");                return(-1);        }        proc_sched_ent->read_proc = rtai_read_sched;        return(0);}  /* End function - rtai_proc_sched_register */static void rtai_proc_sched_unregister(void) {        remove_proc_entry("scheduler", rtai_proc_root);}  /* End function - rtai_proc_sched_unregister *//* ------------------< end of proc filesystem section >------------------*/#endif /* CONFIG_PROC_FS */static int __rtai_up_init(void){	sched_mem_init();	init_sched_entries();	rt_linux_task.uses_fpu = LinuxFpu ? 1 : 0;	rt_linux_task.magic = 0;	rt_linux_task.policy = 0;	rt_linux_task.state = RT_SCHED_READY;	rt_linux_task.msg_queue.prev = &(rt_linux_task.msg_queue);	rt_linux_task.msg_queue.next = &(rt_linux_task.msg_queue);	rt_linux_task.msg_queue.task = &rt_linux_task;	rt_linux_task.msg = 0;	rt_linux_task.ret_queue.prev = &(rt_linux_task.ret_queue);	rt_linux_task.ret_queue.next = &(rt_linux_task.ret_queue);	rt_linux_task.ret_queue.task = NOTHING;	rt_linux_task.priority = rt_linux_task.base_priority = RT_SCHED_LINUX_PRIORITY;	rt_linux_task.signal = 0;	rt_linux_task.prev = &rt_linux_task;	rt_linux_task.next = 0;	rt_linux_task.resume_time = RT_TIME_END;	rt_linux_task.tprev = rt_linux_task.tnext =	rt_linux_task.rprev = rt_linux_task.rnext = &rt_linux_task;	rt_current = &rt_linux_task;	fpu_task = &rt_linux_task;	tuned.latency = imuldiv(Latency, tuned.cpu_freq, 1000000000);	tuned.setup_time_TIMER_CPUNIT = imuldiv( SetupTimeTIMER, 						 tuned.cpu_freq, 						 1000000000);	tuned.setup_time_TIMER_UNIT   = imuldiv( SetupTimeTIMER, 						 TIMER_FREQ, 						 1000000000);	tuned.timers_tol[0] = 0;	oneshot_timer = OneShot ? 1 : 0;	oneshot_running = 0;	preempt_always = Preempt_Always ? 1 : 0;#ifdef CONFIG_PROC_FS	rtai_proc_sched_register();#endif	printk("\n***** STARTING THE UP REAL TIME SCHEDULER WITH %sLINUX *****", LinuxFpu ? "": "NO ");	printk("\n***** FP SUPPORT AND READY FOR A %s TIMER *****", oneshot_timer ? "ONESHOT": "PERIODIC");	printk("\n***<> LINUX TICK AT %d (HZ) <>***", HZ);	printk("\n***<> CALIBRATED CPU FREQUENCY %lu (HZ) <>***", (unsigned long)tuned.cpu_freq);	printk("\n***<> CALIBRATED TIMER-INTERRUPT-TO-SCHEDULER LATENCY %d (ns) <>***", imuldiv(tuned.latency - tuned.setup_time_TIMER_CPUNIT, 1000000000, tuned.cpu_freq));	printk("\n***<> CALIBRATED ONE SHOT SETUP TIME %d (ns) <>***", imuldiv(tuned.setup_time_TIMER_CPUNIT, 1000000000, tuned.cpu_freq));	printk("\n***<> COMPILER: %s***\n\n", CONFIG_RTAI_COMPILER);	rt_mount_rtai();// 0x7dd763ad == nam2num("MEMSRQ").	if ((frstk_srq.srq = rt_request_srq(0x7dd763ad, frstk_srq_handler, 0)) < 0) {		printk("MEM SRQ: no sysrq available.\n");		return frstk_srq.srq;	}	frstk_srq.in = frstk_srq.out = 0;	RT_SET_RTAI_TRAP_HANDLER(rt_trap_handler);#ifdef CONFIG_RTAI_SCHED_ISR_LOCK	rt_set_ihook(&rtai_handle_isched_lock);#endif /* CONFIG_RTAI_SCHED_ISR_LOCK */	return rtai_init_features(); /* see rtai_schedcore.h */}extern void krtai_objects_release(void);static void __rtai_up_exit(void){	RT_SET_RTAI_TRAP_HANDLER(NULL);	stop_rt_timer();	while (rt_linux_task.next) {		rt_task_delete(rt_linux_task.next);	}	krtai_objects_release();#ifdef CONFIG_PROC_FS        rtai_proc_sched_unregister();#endif	while (frstk_srq.out != frstk_srq.in);	if (rt_free_srq(frstk_srq.srq) < 0) {		printk("MEM SRQ: frstk_srq %d illegal or already free.\n", frstk_srq.srq);	}	rtai_cleanup_features();	sched_mem_end();#ifdef CONFIG_RTAI_SCHED_ISR_LOCK	rt_set_ihook(NULL);#endif /* CONFIG_RTAI_SCHED_ISR_LOCK */	rt_umount_rtai();	printk("\n***** THE UP REAL TIME SCHEDULER HAS BEEN REMOVED *****\n\n");}module_init(__rtai_up_init);module_exit(__rtai_up_exit);

⌨️ 快捷键说明

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