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

📄 rtai.c

📁 rtai-3.1-test3的源代码(Real-Time Application Interface )
💻 C
📖 第 1 页 / 共 2 页
字号:
}static unsigned long linux_save_flags_and_cli(void){	unsigned long linux_flags;	linux_flags = cpu.intr_flag;    cpu.intr_flag = 0;	return linux_flags;}unsigned long linux_save_flags_and_cli_cpuid(int cpuid){	return linux_save_flags_and_cli();}void rtai_just_copy_back(unsigned long flags, int cpuid){	cpu.intr_flag = flags;}/* *  hard_sti() is asm-defined as "ei" in system.h. This function *  is used at rthal.ei_if_rtai when RTAI has been mounted. */ static void do_hard_sti(void){	hard_sti();}/* * Special fast version of rdtsc called from dispatch_timer_irq * with interrupts disabled. * When arriving here we _KNOW_ hat a timer interrupt has occured */static inline void rdtsc_special(void){#ifdef CONFIG_ETRAX_DISABLE_CASCADED_TIMERS_IN_RTAI	unsigned int count = *R_TIMER0_DATA;	#else	unsigned int count = *R_TIMER01_DATA;#endif		/* We know there was a timer interrupt when this function was called */	rtai_tsc += rtai_delay - rtai_lastcount + count;		rtai_lastcount = count;}/* * This function is called as interrupt handler for most of the * interrupts when RTAI is mounted. See also dispatch_timer_irq. */asmlinkage void dispatch_irq(int irq, struct pt_regs *regs){	if (irq < 0 || irq >= NR_IRQS)		return;			/* Is there an RT-handler installed? */	if (global_irq_handlers[irq]) { 		/* The handler should:		 * ACK the interrupt properly and immediately.		 * Pend it to Linux if necessary. */		((void (*)(int))global_irq_handlers[irq])(irq);		/* Unmask ASAP since this is a RT interrupt. */		unmask_irq(irq);				} else {				/* There is no RT-handler; pend the interrupt to Linux. */		set_bit_non_atomic(irq, (int*) &global.pending_irqs);				}	/* Are interrupts enabled for Linux? */	if (cpu.intr_flag) {					/* Dispatch any pending interrupts to Linux. */		linux_sti();	}} /* * This function is called as interrupt handler for the timer * interrupt when RTAI is mounted. */asmlinkage void dispatch_timer_irq(int irq, struct pt_regs *regs){	/* A minimum rdtsc (updates data used in scheduler) */	rdtsc_special(); 	/* ACK the timer interrupt */	*R_TIMER_CTRL = r_timer_ctrl_shadow | IO_STATE(R_TIMER_CTRL, i0, clr);	/* The timer irq is not masked and should not be so either. */	/* The watchdog should preferably be disabled when running RTAI. */#ifdef CONFIG_ETRAX_WATCHDOG	reset_watchdog();#endif	/* Is there a RT-handler installed on the timer irq? */	if (global_irq_handlers[TIMER_IRQ]) { 						/* The handler pends the interrupt to Linux if necessary. */		((void (*)(int))global_irq_handlers[TIMER_IRQ])(TIMER_IRQ);		} else {						/* There is no RT-handler so pend the interrupt to Linux */		set_bit_non_atomic(TIMER_IRQ, (int*) &global.pending_irqs);	}		/* Are interrupts enabled for Linux? */	if (cpu.intr_flag) {				/* Dispatch any pending interrupts to Linux */		linux_sti();	}	/* For speed (ei_if_rtai is done a little later anyway) */	hard_sti();} /*  * This function is a way to enter the kernel in our own way from user-space. * * FIX: This function is never called. A kernel patch has to be added in future * versions.  A file rtai_srq.h has to be added to the CRIS port before this * will work. Perhaps the break function could be used in a clever way. */asmlinkage long long dispatch_srq(int srq, unsigned long whatever){	if (srq > 1 && srq < NR_SYSRQS && sysrq[srq].user_handler) {		return sysrq[srq].user_handler(whatever);	}	for (srq = 2; srq < NR_SYSRQS; srq++) {		if (sysrq[srq].label == whatever) {			return (long long) srq;		}	}	return 0;}/* --------------------------------------------------------------------------*//* Used by the scheduler */int rt_is_linux(void){	return global.used_by_linux;}void rt_switch_to_linux(int cpuid){	global.used_by_linux = 1;	cpu.intr_flag = cpu.linux_intr_flag;  /* Restore */}void rt_switch_to_real_time(int cpuid){	if (global.used_by_linux)		cpu.linux_intr_flag = cpu.intr_flag; /* Save */	cpu.intr_flag = 0;	global.used_by_linux = 0;}/* --------------------------------------------------------------------------*//* * rt_request_timer set's the new timer latch value and  * free's + requests the global timer irq as a realtime interrupt. */void rt_request_timer(void (*handler)(void), unsigned int tick, int unused){	unsigned long flags;	flags = hard_lock_all();		/* Wait for a timer underflow and clear the int. bit.	   Needs to wait since we pend the irq for Linux later.	   Otherwise we could be 10ms off. */	do {		;	} while ( !( *R_VECT_READ & IO_STATE(R_VECT_READ, timer0, active)) );	*R_TIMER_CTRL = r_timer_ctrl_shadow | IO_STATE(R_TIMER_CTRL, i0, clr);	/* set up rt_times structure */	rt_times.linux_tick = LATCH;	rt_times.periodic_tick = (tick > 0) ? tick : rt_times.linux_tick;	rt_times.tick_time  = rdtsc();	rt_times.intr_time  = rt_times.tick_time + rt_times.periodic_tick;	rt_times.linux_time = rt_times.tick_time + (RTIME) rt_times.linux_tick;	/* Set the new timer divide factor */	rt_set_timer_delay(rt_times.periodic_tick);	rt_free_global_irq(TIMER_IRQ);	rt_request_global_irq(TIMER_IRQ, handler);		/* pend linux timer irq to handle the current jiffie */ 	rt_pend_linux_irq(TIMER_IRQ);	hard_unlock_all(flags);}void rt_free_timer(void){	unsigned long flags;	flags = hard_lock_all();#ifdef CONFIG_ETRAX_DISABLE_CASCADED_TIMERS_IN_RTAI	/* Clear the corresponding fields of the shadow. */	r_timer_ctrl_shadow = r_timer_ctrl_shadow & (		~IO_FIELD(R_TIMER_CTRL, timerdiv0, 255) &		~IO_STATE(R_TIMER_CTRL, tm0, reserved));        /* Stop the timer and load the original timerdiv0 */        *R_TIMER_CTRL = r_timer_ctrl_shadow                   |                IO_FIELD(R_TIMER_CTRL, timerdiv0, TIMER0_DIV) |                IO_STATE(R_TIMER_CTRL, tm0, stop_ld);        /* Restart the timer and save the changes to r_timer_ctrl_shadow */        *R_TIMER_CTRL = r_timer_ctrl_shadow = r_timer_ctrl_shadow |                IO_FIELD(R_TIMER_CTRL, timerdiv0, TIMER0_DIV)     |                IO_STATE(R_TIMER_CTRL, tm0, run);#else	/* Configure the timers to operate in cascading mode. */        *R_TIMER_CTRL =                IO_FIELD( R_TIMER_CTRL, timerdiv1, RTAI_CASCADED_TIMER1_DIV) |                IO_FIELD( R_TIMER_CTRL, timerdiv0, RTAI_CASCADED_TIMER0_DIV) |                IO_STATE( R_TIMER_CTRL, i1, nop)           |                IO_STATE( R_TIMER_CTRL, tm1, stop_ld)      |                IO_STATE( R_TIMER_CTRL, clksel1, cascade0) |                IO_STATE( R_TIMER_CTRL, i0, nop)           |                IO_STATE( R_TIMER_CTRL, tm0, stop_ld)      |                IO_STATE( R_TIMER_CTRL, clksel0, flexible);        *R_TIMER_CTRL = r_timer_ctrl_shadow =                IO_FIELD( R_TIMER_CTRL, timerdiv1, RTAI_CASCADED_TIMER1_DIV)  |                IO_FIELD( R_TIMER_CTRL, timerdiv0, RTAI_CASCADED_TIMER0_DIV)  |                IO_STATE( R_TIMER_CTRL, i1, nop)           |                IO_STATE( R_TIMER_CTRL, tm1, run)          |                IO_STATE( R_TIMER_CTRL, clksel1, cascade0) |                IO_STATE( R_TIMER_CTRL, i0, nop)           |                IO_STATE( R_TIMER_CTRL, tm0, run)          |                IO_STATE( R_TIMER_CTRL, clksel0, flexible);        *R_TIMER_PRESCALE = RTAI_CASCADED_TIMER_PRESCALE;#endif	rt_free_global_irq(TIMER_IRQ);	hard_unlock_all(flags);}/* --------------------------------------------------------------------------*/extern void soft_timer_interrupt(int, void*, struct pt_regs*);void __rt_mount_rtai(void){	unsigned long flags;	    	flags = hard_lock_all();	/* Save the old rthal struct */	linux_rthal = rthal;	  	rthal.do_IRQ           	 = dispatch_irq;	rthal.do_timer_IRQ       = dispatch_timer_irq;  	rthal.do_SRQ           	 = do_nothing; /* Set later upon request */	rthal.disint          	 = linux_cli;	rthal.enint            	 = linux_sti;  	rthal.getflags         	 = linux_save_flags;  	rthal.setflags         	 = linux_restore_flags;  	rthal.getflags_and_cli 	 = linux_save_flags_and_cli;	rthal.ei_if_rtai         = do_hard_sti;	rthal.unmask_if_not_rtai = do_nothing_uint;		/* Save the timer handler */	saved_timer_action_handler = irq_action[TIMER_IRQ]->handler;	irq_action[TIMER_IRQ]->handler = soft_timer_interrupt;	    	hard_unlock_all(flags);	  	printk("\n***** RTAI MOUNTED *****\n\n");}extern void rt_printk_cleanup(void);extern void rt_printk_init(void);void __rt_umount_rtai(void){  	unsigned long flags;    	flags = hard_lock_all();	/* Restore the old rthal struct */	rthal = linux_rthal;	/* Restore timer-interrupt handler */	irq_action[TIMER_IRQ]->handler = saved_timer_action_handler;	/* Remove SRQ for rt_printk etc. */    	rt_printk_cleanup();	hard_unlock_all(flags);	  	printk("\n***** RTAI UNMOUNTED *****\n\n");}static int init_rtai_cris(void){	int i;		global.pending_irqs = 0;	cpu.intr_flag = 1;	cpu.linux_intr_flag = 1;	for (i = 0; i < NR_IRQS; i++) {		global_irq_handlers[i] = 0;		chained_to_linux[i] = 0;	}	        for (i = 0; i < NR_SYSRQS; i++) {		sysrq[i].rtai_handler = 0;		sysrq[i].user_handler = 0;		sysrq[i].label        = 0;        }		rt_printk_init();#ifdef CONFIG_ETRAX_DISABLE_CASCADED_TIMERS_IN_RTAI        /* Keep timers as they are but save the	 * old timer control shadow. */	saved_r_timer_ctrl_shadow = r_timer_ctrl_shadow;#else	/* Configure the timers to operate in cascading mode. */        *R_TIMER_CTRL =                IO_FIELD( R_TIMER_CTRL, timerdiv1, RTAI_CASCADED_TIMER1_DIV) |                IO_FIELD( R_TIMER_CTRL, timerdiv0, RTAI_CASCADED_TIMER0_DIV) |                IO_STATE( R_TIMER_CTRL, i1, nop)           |                IO_STATE( R_TIMER_CTRL, tm1, stop_ld)      |                IO_STATE( R_TIMER_CTRL, clksel1, cascade0) |                IO_STATE( R_TIMER_CTRL, i0, nop)           |                IO_STATE( R_TIMER_CTRL, tm0, stop_ld)      |                IO_STATE( R_TIMER_CTRL, clksel0, flexible);        *R_TIMER_CTRL = r_timer_ctrl_shadow =                IO_FIELD( R_TIMER_CTRL, timerdiv1, RTAI_CASCADED_TIMER1_DIV) |                IO_FIELD( R_TIMER_CTRL, timerdiv0, RTAI_CASCADED_TIMER0_DIV) |                IO_STATE( R_TIMER_CTRL, i1, nop)           |                IO_STATE( R_TIMER_CTRL, tm1, run)          |                IO_STATE( R_TIMER_CTRL, clksel1, cascade0) |                IO_STATE( R_TIMER_CTRL, i0, nop)           |                IO_STATE( R_TIMER_CTRL, tm0, run)          |                IO_STATE( R_TIMER_CTRL, clksel0, flexible);        *R_TIMER_PRESCALE = RTAI_CASCADED_TIMER_PRESCALE;#endif		#ifdef CONFIG_PROC_FS	rtai_proc_register();#endif		return 0;}static void cleanup_rtai_cris(void){#ifdef CONFIG_PROC_FS	rtai_proc_unregister();#endif	/* Release any timer-interrupt handler */	rt_free_timer();	#ifdef CONFIG_ETRAX_DISABLE_CASCADED_TIMERS_IN_RTAI	/* Restore timer control shadow */	r_timer_ctrl_shadow = saved_r_timer_ctrl_shadow;#endif }void rt_mount_rtai(void){	if ( !(rtai_mounted++) ){		init_rtai_cris();		__rt_mount_rtai();	}}void rt_umount_rtai(void){	if ( !(--rtai_mounted) ) {		__rt_umount_rtai();		cleanup_rtai_cris();	}}module_init(init_rtai_cris);module_exit(cleanup_rtai_cris);/* --------------------------------------------------------------------------*//* Mostly copied from i386 */#ifdef CONFIG_PROC_FSstruct proc_dir_entry *rtai_proc_root = NULL;static int rtai_read_rtai(char *page, char **start, off_t off, int count,                          int *eof, void *data){	PROC_PRINT_VARS;	int i;	PROC_PRINT("\nRTAI Real Time Kernel, Version: %s\n\n", RTAI_RELEASE);	PROC_PRINT("    RTAI mount count: %d\n", rtai_mounted);	PROC_PRINT("    TIMER Frequency: %d\n", FREQ_8254);	PROC_PRINT("    TIMER Latency: %d ns\n", LATENCY_8254);	PROC_PRINT("    TIMER Setup: %d ns\n", SETUP_TIME_8254);#ifndef CONFIG_ETRAX_DISABLE_CASCADED_TIMERS_IN_RTAI	PROC_PRINT("\n    Using timers in cascade-mode.\n");#endif	PROC_PRINT("\nirqs used by RTAI: \n");	for (i = 0; i < NR_GLOBAL_IRQS; i++) {		if (global_irq_handlers[i]) {			PROC_PRINT("%d ", i);		}	}	PROC_PRINT("\nRTAI sysreqs in use: \n");	for (i = 0; i < NR_GLOBAL_IRQS; i++) {		if (sysrq[i].rtai_handler || sysrq[i].user_handler) {			PROC_PRINT("%d ", i);		}	}	PROC_PRINT("\n\n");	PROC_PRINT_DONE;}       /* End function - rtai_read_rtai */static int rtai_proc_register(void){	struct proc_dir_entry *ent;	rtai_proc_root = create_proc_entry("rtai", S_IFDIR, 0);	if (!rtai_proc_root) {		printk("Unable to initialize /proc/rtai\n");		return(-1);	}	/* rtai.o is compiled into the kernel */	/* rtai_proc_root->owner = THIS_MODULE; */	ent = create_proc_entry("rtai", S_IFREG|S_IRUGO|S_IWUSR, rtai_proc_root);	if (!ent) {		printk("Unable to initialize /proc/rtai/rtai\n");		return(-1);	}	ent->read_proc = rtai_read_rtai;	return(0);}       /* End function - rtai_proc_register */static void rtai_proc_unregister(void){	remove_proc_entry("rtai", rtai_proc_root);	remove_proc_entry("rtai", 0);}       /* End function - rtai_proc_unregister */#endif /* CONFIG_PROC_FS *//* --------------------------------------------------------------------------*/EXPORT_SYMBOL(rt_mask_and_ack_irq);EXPORT_SYMBOL(rt_mask_irq);EXPORT_SYMBOL(rt_unmask_irq);EXPORT_SYMBOL(rt_disable_irq);EXPORT_SYMBOL(rt_enable_irq);EXPORT_SYMBOL(rt_request_global_irq);EXPORT_SYMBOL(rt_free_global_irq);EXPORT_SYMBOL(rt_free_linux_irq);EXPORT_SYMBOL(rt_free_srq);EXPORT_SYMBOL(rt_free_timer);EXPORT_SYMBOL(rt_mount_rtai); EXPORT_SYMBOL(rt_umount_rtai);EXPORT_SYMBOL(rt_pend_linux_irq);EXPORT_SYMBOL(rt_pend_linux_srq); EXPORT_SYMBOL(rt_printk);EXPORT_SYMBOL(rt_request_linux_irq);EXPORT_SYMBOL(rt_request_srq);EXPORT_SYMBOL(rt_request_timer);EXPORT_SYMBOL(rt_shutdown_irq);EXPORT_SYMBOL(rt_startup_irq);EXPORT_SYMBOL(rt_switch_to_linux);EXPORT_SYMBOL(rt_switch_to_real_time);EXPORT_SYMBOL(rt_is_linux);EXPORT_SYMBOL(rt_times);EXPORT_SYMBOL(tuned);EXPORT_SYMBOL(dispatch_irq);EXPORT_SYMBOL(dispatch_timer_irq);EXPORT_SYMBOL(dispatch_srq);EXPORT_SYMBOL(rtai_just_copy_back);EXPORT_SYMBOL(rtai_delay);EXPORT_SYMBOL(rtai_tsc);EXPORT_SYMBOL(rtai_lastcount);EXPORT_SYMBOL(rtai_proc_root);EXPORT_SYMBOL(linux_save_flags_and_cli_cpuid);

⌨️ 快捷键说明

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