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

📄 sched_mup.c

📁 rtai-3.1-test3的源代码(Real-Time Application Interface )
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 PreemptAlways = PREEMPT_ALWAYS;MODULE_PARM(PreemptAlways, "i");static int LinuxFpu = LINUX_FPU;MODULE_PARM(LinuxFpu, "i");static int Latency = TIMER_LATENCY;MODULE_PARM(Latency, "i");static int SetupTimeTIMER = TIMER_SETUP_TIME;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 +++++++++++++++++++++++++++++ */RTIME count2nano(RTIME counts){	int sign;	if (counts > 0) {		sign = 1;	} else {		sign = 0;		counts = - counts;	}	counts = oneshot_timer_cpuid ?		 llimd(counts, 1000000000, tuned.cpu_freq):		 llimd(counts, 1000000000, TIMER_FREQ);	return sign ? counts : - counts;}RTIME nano2count(RTIME ns){	int sign;	if (ns > 0) {		sign = 1;	} else {		sign = 0;		ns = - ns;	}	ns =  oneshot_timer_cpuid ?	      llimd(ns, tuned.cpu_freq, 1000000000) :	      llimd(ns, TIMER_FREQ, 1000000000);	return sign ? ns : - ns;}RTIME count2nano_cpuid(RTIME counts, unsigned int cpuid){	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;}RTIME nano2count_cpuid(RTIME ns, unsigned int cpuid){	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;}/* +++++++++++++++++++++++++++++++ TIMINGS ++++++++++++++++++++++++++++++++++ */RTIME rt_get_time(void){	int cpuid;	return rt_smp_oneshot_timer[cpuid = hard_cpu_id()] ? rdtsc() : rt_smp_times[cpuid].tick_time;}RTIME rt_get_time_cpuid(unsigned int cpuid){	return oneshot_timer ? rdtsc(): rt_times.tick_time;}RTIME rt_get_time_ns(void){	int cpuid = hard_cpu_id();	return oneshot_timer ? llimd(rdtsc(), 1000000000, tuned.cpu_freq) :	    		       llimd(rt_times.tick_time, 1000000000, TIMER_FREQ);}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);}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){        int cpuid;        for (cpuid = 0; cpuid < smp_num_cpus; cpuid++) {                base_linux_tasks[cpuid] = rt_smp_linux_task + cpuid;        }        return rt_smp_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[cpuid]) 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[cpuid] = wd;	return (RT_TASK**) 0;}void rt_deregister_watchdog(RT_TASK *wd, int cpuid){    	if (wdog_task[cpuid] != wd) return;	wdog_task[cpuid] = NULL;}/* ++++++++++++++ SCHEDULER ENTRIES AND RELATED INITIALISATION ++++++++++++++ */#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;        int cpuid, i = 1;	unsigned long t;	RT_TASK *task;	PROC_PRINT("\nRTAI MUP Real Time Task Scheduler.\n\n");	PROC_PRINT("    Calibrated CPU Frequency: %lu Hz\n", tuned.cpu_freq);	PROC_PRINT("    Calibrated 8254 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  CPU  Task  RT_TASK *  TIME\n");        PROC_PRINT("------------------------------------------------------------------\n");        for (cpuid = 0; cpuid < NR_RT_CPUS; cpuid++) {                task = &rt_linux_task;/** 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 %-4d  %p    %-lu\n",                               task->priority,                               (unsigned long)count2nano_cpuid(task->period, task->runnable_on_cpus),                               task->uses_fpu ? "Yes" : "No",                               task->signal ? "Yes" : "No",                               task->state,                               cpuid,                               i, task, t);			i++;                } /* End while loop - display all RT tasks on a CPU. */		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);		}        }  /* End for loop - display RT tasks on all CPUs. */	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 */int __rtai_mup_init(void){	int cpuid;	sched_mem_init();	init_sched_entries();	for (cpuid = 0; cpuid < NR_RT_CPUS; cpuid++) {		rt_linux_task.uses_fpu = LinuxFpu != 0 ? 1 : 0;		rt_linux_task.magic = 0;		rt_linux_task.policy = 0;		rt_linux_task.runnable_on_cpus = cpuid;		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_SCHED_LINUX_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.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_linux_task.next = 0;		rt_smp_current[cpuid] = &rt_linux_task;		rt_smp_fpu_task[cpuid] = &rt_linux_task;		oneshot_timer = OneShot ? 1 : 0;		oneshot_running = 0;		preempt_always = PreemptAlways ? 1 : 0;	}	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;#ifdef CONFIG_PROC_FS	rtai_proc_sched_register();#endif	printk("\n***** STARTING THE MUP REAL TIME SCHEDULER WITH %sLINUX FP SUPPORT *****", LinuxFpu ? "": "NO ");	printk("\n***<> LINUX TICK AT %d (HZ) <>***", HZ);	printk("\n***<> CALIBRATED CPU FREQUENCY %lu (HZ) <>***", tuned.cpu_freq);	printk("\n***<> CALIBRATED APIC_INTERRUPT-TO-SCHEDULER LATENCY %d (ns) <>***", imuldiv(tuned.latency - tuned.setup_time_TIMER_CPUNIT, 1000000000, tuned.cpu_freq));	printk("\n***<> CALIBRATED ONE SHOT APIC 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_request_sched_ipi();	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);void __rtai_mup_exit(void){	int cpuid;	rt_set_rtai_trap_handler(NULL);	stop_rt_timer();	for (cpuid = 0; cpuid < NR_RT_CPUS; cpuid++) {		while (rt_linux_task.next) {			rt_task_delete(rt_linux_task.next);		}	}	krtai_objects_release();	rtai_cleanup_features();#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);	}	rt_free_sched_ipi();	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 MUP REAL TIME SCHEDULER HAS BEEN REMOVED *****\n\n");}module_init(__rtai_mup_init);module_exit(__rtai_mup_exit);/* +++++++++++++++++++++++++++++ SCHEDULER END ++++++++++++++++++++++++++++ */

⌨️ 快捷键说明

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