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

📄 rtai.c

📁 rtai-3.1-test3的源代码(Real-Time Application Interface )
💻 C
📖 第 1 页 / 共 2 页
字号:
                rtai_trap_handler[trap] = handler;        }        return old_handler;}void rt_free_rtai_trap_handler(int trap){	rtai_trap_handler[trap] = NULL;}/* Here are the trapped pic functions for Linux interrupt handlers. */static void shared_unmask_irq(unsigned int irq){	unsigned long flags;	flags = rt_spin_lock_irqsave(&global.ic_lock);	if (linux_irqs[irq].pend_count && (processor[hard_cpu_id()].intr_flag & I_BIT)) {		rt_spin_unlock_irqrestore(flags, &global.ic_lock);		linux_sti();	} else		rt_spin_unlock_irqrestore(flags, &global.ic_lock);}/* Request and free interrupts, system requests and interprocessors messages *//* Request for regular Linux irqs also included. They are nicely chained to  *//* Linux, forcing sharing with any already installed handler, so that we can *//* have an echo from Linux for global handlers. We found that usefull during *//* debug, but can be nice for a lot of other things, e.g. see the jiffies    *//* recovery in rtai_sched.c, and the global broadcast to local apic timers.  */static unsigned long irq_action_flags[NR_IRQS];static int chained_to_linux[NR_IRQS];int rt_request_global_irq_ext(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), void *dev_id){	unsigned long flags;	if (irq >= NR_IRQS || !handler) {		return -EINVAL;	}	if (global_irq[irq].handler != NULL) {		return -EBUSY;	}	flags = hard_lock_all();	irq_desc[irq].mask_ack	= do_nothing_picfun;	irq_desc[irq].mask	= do_nothing_picfun;	irq_desc[irq].unmask	= shared_unmask_irq;	shadow_irq_desc[irq].disable_depth = 1;		global_irq[irq].handler = handler;	global_irq[irq].dev_id = dev_id;	hard_unlock_all(flags);	return 0;}/* We don't share IRQ's under RT, so, don't need the dev-pointer. */int rt_free_global_irq(unsigned int irq){	unsigned long flags;	if (irq >= NR_IRQS || !global_irq[irq].handler) {		return -EINVAL;	}	flags = hard_lock_all();	irq_desc[irq].mask_ack	= linux_mask_ack;	irq_desc[irq].mask	= ic_mask_irq[irq];	irq_desc[irq].unmask	= ic_unmask_irq[irq];	global_irq[irq].handler = NULL;	hard_unlock_all(flags);	return 0;}int rt_request_linux_irq(unsigned int irq,	void (*linux_handler)(int irq, void *dev_id, struct pt_regs *regs),	char *linux_handler_id, void *dev_id){	unsigned long flags;//##	//	if (irq == TIMER_8254_IRQ) {//		processor[0].trailing_irq_handler = linux_handler;//		return 0;//	}	if (irq >= NR_IRQS || !linux_handler) {		return -EINVAL;	}	save_flags_cli(flags);	if (!chained_to_linux[irq]++) {		if (irq_desc[irq].action) {			irq_action_flags[irq] = irq_desc[irq].action->flags;			irq_desc[irq].action->flags |= SA_SHIRQ;		}	}	restore_flags(flags);	request_irq(irq, linux_handler, SA_SHIRQ, linux_handler_id, dev_id);	return 0;}int rt_free_linux_irq(unsigned int irq, void *dev_id){	unsigned long flags;//##//	if (irq == TIMER_8254_IRQ) {//		processor[0].trailing_irq_handler = 0;//		return 0;//	}	if (irq >= NR_IRQS || !chained_to_linux[irq]) {		return -EINVAL;	}	free_irq(irq, dev_id);	save_flags_cli(flags);	if (!(--chained_to_linux[irq]) && irq_desc[irq].action) {		irq_desc[irq].action->flags = irq_action_flags[irq];	}	restore_flags(flags);	return 0;}int rt_request_srq(unsigned int label, void (*rtai_handler)(void), long long (*user_handler)(unsigned int whatever)){	unsigned long flags;	unsigned int srq;	if (!rtai_handler) {		return -EINVAL;	}	flags = rt_spin_lock_irqsave(&global.data_lock);	for (srq = 2; srq < NR_SYSRQS; srq++) {		if (!(sysrq[srq].rtai_handler)) {			sysrq[srq].rtai_handler = rtai_handler;			sysrq[srq].label = label;			if (user_handler) {				sysrq[srq].user_handler = user_handler;				if (!rthal.do_SRQ) {					rthal.do_SRQ = dispatch_srq;				}			}			rt_spin_unlock_irqrestore(flags, &global.data_lock);			return srq;		}	}	rt_spin_unlock_irqrestore(flags, &global.data_lock);	return -EBUSY;}int rt_free_srq(unsigned int srq){	unsigned long flags;	flags = rt_spin_lock_irqsave(&global.data_lock);	if (srq < 2 || srq >= NR_SYSRQS || !sysrq[srq].rtai_handler) {		rt_spin_unlock_irqrestore(flags, &global.data_lock);		return -EINVAL;	}	sysrq[srq].rtai_handler = 0;	sysrq[srq].user_handler = 0;	sysrq[srq].label = 0;	for (srq = 2; srq < NR_SYSRQS; srq++) {		if (sysrq[srq].user_handler) {			rt_spin_unlock_irqrestore(flags, &global.data_lock);			return 0;		}	}	if (rthal.do_SRQ) {		rthal.do_SRQ = 0;	}	rt_spin_unlock_irqrestore(flags, &global.data_lock);	return 0;}int rt_is_linux(void){    return test_bit(hard_cpu_id(), (void *)&global.used_by_linux);}void rt_switch_to_linux(int cpuid){	TRACE_RTAI_SWITCHTO_LINUX(cpuid);	set_bit(cpuid, &global.used_by_linux);	processor[cpuid].intr_flag = processor[cpuid].linux_intr_flag;}void rt_switch_to_real_time(int cpuid){	TRACE_RTAI_SWITCHTO_RT(cpuid);	if ( global.used_by_linux & (1<<cpuid) )		processor[cpuid].linux_intr_flag = processor[cpuid].intr_flag;	processor[cpuid].intr_flag = 0;	clear_bit(cpuid, &global.used_by_linux);}/* RTAI mount-unmount functions to be called from the application to       *//* initialise the real time application interface, i.e. this module, only  *//* when it is required; so that it can stay asleep when it is not needed   */#ifdef CONFIG_RTAI_MOUNT_ON_LOAD#define rtai_mounted 1#elsestatic int rtai_mounted;#endif// Trivial, but we do things carefully, the blocking part is relatively short,// should cause no troubles in the transition phase.// All the zeroings are strictly not required as mostly related to static data.// Done esplicitly for emphasis. Simple, just lock and grab everything from// Linux.void __rt_mount_rtai(void){     	unsigned long flags, i;	flags = hard_lock_all();	rthal.do_IRQ		= dispatch_irq;	rthal.do_SRQ		= dispatch_srq;	rthal.do_TRAP		= dispatch_trap;	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.fdisint		= linux_cli;	rthal.fenint		= linux_sti;	rthal.copy_back		= rtai_just_copy_back;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,21)	rthal.getflags_and_sti	= linux_save_flags_sti;#endif	for (i = 0; i < NR_IRQS; i++) {		irq_desc[i].mask_ack	= linux_mask_ack;		irq_desc[i].mask	= ic_mask_irq[i];		irq_desc[i].unmask	= ic_unmask_irq[i];		linux_irqs[i].pend_count = 0;	}#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19)	rthal.c_do_IRQ = dispatch_irq;#endif	INIT_LIST_HEAD(&global.pending_linux_irq);	arch_mount_rtai();	saved_timer_action_handler = irq_desc[TIMER_8254_IRQ].action->handler;	irq_desc[TIMER_8254_IRQ].action->handler = linux_timer_interrupt;	hard_unlock_all(flags);	printk("\n***** RTAI NEWLY MOUNTED (MOUNT COUNT %d) ******\n\n", rtai_mounted);}// Simple, now we can simply block other processors and copy original data back// to Linux.void __rt_umount_rtai(void){	int i;	unsigned long flags;	flags = hard_lock_all();	arch_umount_rtai();        rthal = linux_rthal;	for (i = 0; i < NR_IRQS; i++) {		irq_desc[i].mask_ack	= ic_mask_ack_irq[i];		irq_desc[i].mask	= ic_mask_irq[i];		irq_desc[i].unmask	= ic_unmask_irq[i];	}	irq_desc[TIMER_8254_IRQ].action->handler = saved_timer_action_handler;	hard_unlock_all(flags);	printk("\n***** RTAI UNMOUNTED (MOUNT COUNT %d) ******\n\n", rtai_mounted);}#ifdef CONFIG_RTAI_MOUNT_ON_LOADvoid rt_mount_rtai(void) { }void rt_umount_rtai(void) { }#elsevoid rt_mount_rtai(void){	rt_spin_lock(&rtai_mount_lock);	MOD_INC_USE_COUNT;	TRACE_RTAI_MOUNT();	if(++rtai_mounted==1)		__rt_mount_rtai();	rt_spin_unlock(&rtai_mount_lock);}void rt_umount_rtai(void){	rt_spin_lock(&rtai_mount_lock);	MOD_DEC_USE_COUNT;	TRACE_RTAI_UMOUNT();	if(!--rtai_mounted)		__rt_umount_rtai();	rt_spin_unlock(&rtai_mount_lock);}#endif/* module init-cleanup */extern void rt_printk_sysreq_handler(void);// Let's prepare our side without any problem, so that there remain just a few// things to be done when mounting RTAI. All the zeroings are strictly not// required as mostly related to static data. Done explicitly for emphasis.static __init int init_rtai(void){     	unsigned int i;	tuned.cpu_freq = FREQ_SYS_CLK;	linux_rthal = rthal;	init_pending_srqs();	global.active_srqs     = 0;	global.used_by_linux   = ~(0xFFFFFFFF << smp_num_cpus);	global.locked_cpus     = 0;	spin_lock_init(&(global.data_lock));	spin_lock_init(&(global.ic_lock));	for (i = 0; i < NR_RT_CPUS; i++) {		processor[i].intr_flag         = I_BIT | (1 << i);		processor[i].linux_intr_flag   = I_BIT | (1 << i);		processor[i].pending_irqs      = 0;		processor[i].active_irqs       = 0;	}        for (i = 0; i < NR_SYSRQS; i++) {		sysrq[i].rtai_handler = 0;		sysrq[i].user_handler = 0;		sysrq[i].label        = 0;        }	for (i = 0; i < NR_IRQS; i++) {		global_irq[i].handler = 0;		shadow_irq_desc[i] = irq_desc[i];		ic_mask_ack_irq[i] = irq_desc[i].mask_ack;		ic_mask_irq[i] = irq_desc[i].mask;		ic_unmask_irq[i] = irq_desc[i].unmask;	}	sysrq[rt_printk_srq].rtai_handler = rt_printk_sysreq_handler;	sysrq[rt_printk_srq].label = 0x1F0000F1;#ifdef CONFIG_RTAI_MOUNT_ON_LOAD	__rt_mount_rtai();#endif#ifdef CONFIG_PROC_FS	rtai_proc_register();#endif	return 0;}static __exit void cleanup_rtai(void){#ifdef CONFIG_RTAI_MOUNT_ON_LOAD	__rt_umount_rtai();#endif#ifdef CONFIG_PROC_FS	rtai_proc_unregister();#endif	return;}module_init(init_rtai);module_exit(cleanup_rtai);MODULE_LICENSE("GPL");/* ----------------------< proc filesystem section >----------------------*/#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("    Clock frequency: %d Hz\n", FREQ_SYS_CLK);	PROC_PRINT("    Timer latency: %d ns\n", LATENCY_MATCH_REG);	PROC_PRINT("    Timer setup: %d ns\n", SETUP_TIME_MATCH_REG);        PROC_PRINT("\nGlobal irqs used by RTAI: \n");	for (i = 0; i < NR_IRQS; i++) {		if (global_irq[i].handler) {			PROC_PRINT("%d\t%lu\n", i, global_irq[i].count);		}        }        PROC_PRINT("\nRTAI sysreqs in use: \n");        for (i = 0; i < NR_SYSRQS; i++) {		if (sysrq[i].rtai_handler || sysrq[i].user_handler) {			PROC_PRINT("%d ", i);		}        }	if ( global.lost_irqs )		PROC_PRINT( "### Lost IRQs: %d ###\n", global.lost_irqs );	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_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 *//* ------------------< end of proc filesystem section >------------------*//********** SOME TIMER FUNCTIONS TO BE LIKELY NEVER PUT ELSWHERE *************//* Real time timers. No oneshot, and related timer programming, calibration. *//* Use the utility module. It is also to be decided if this stuff has to     *//* stay here.                                                                */struct calibration_data tuned;struct rt_times rt_times;struct rt_times rt_smp_times[NR_RT_CPUS];/******** END OF SOME TIMER FUNCTIONS TO BE LIKELY NEVER PUT ELSWHERE *********/// Our printk function, its use should be safe everywhere.#include <linux/console.h>int rtai_print_to_screen(const char *format, ...){        static spinlock_t display_lock = SPIN_LOCK_UNLOCKED;        static char display[25*80];        unsigned long flags;        struct console *c;        va_list args;        int len;        flags = rt_spin_lock_irqsave(&display_lock);        va_start(args, format);        len = vsprintf(display, format, args);        va_end(args);        c = console_drivers;        while(c) {                if ((c->flags & CON_ENABLED) && c->write)                        c->write(c, display, len);                c = c->next;	}        rt_spin_unlock_irqrestore(flags, &display_lock);	return len;}EXPORT_SYMBOL(rt_mask_ack_irq);EXPORT_SYMBOL(rt_mask_irq);EXPORT_SYMBOL(rt_disable_irq);EXPORT_SYMBOL(rt_enable_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_pend_linux_irq);EXPORT_SYMBOL(rt_pend_linux_srq);EXPORT_SYMBOL(rt_printk);EXPORT_SYMBOL(rt_request_global_irq_ext);EXPORT_SYMBOL(rt_request_linux_irq);EXPORT_SYMBOL(rt_request_srq);EXPORT_SYMBOL(rt_request_timer);EXPORT_SYMBOL(rt_reset_full_intr_vect);EXPORT_SYMBOL(rt_set_full_intr_vect);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_umount_rtai);EXPORT_SYMBOL(rt_unmask_irq);EXPORT_SYMBOL(rtai_proc_root);EXPORT_SYMBOL(rt_smp_times);EXPORT_SYMBOL(rt_times);EXPORT_SYMBOL(tuned);EXPORT_SYMBOL(locked_cpus);EXPORT_SYMBOL(linux_save_flags_and_cli);EXPORT_SYMBOL(linux_save_flags_and_cli_cpuid);EXPORT_SYMBOL(rtai_just_copy_back);EXPORT_SYMBOL(global);EXPORT_SYMBOL(rtai_print_to_screen);EXPORT_SYMBOL(rtai_tsc);EXPORT_SYMBOL(rt_set_rtai_trap_handler);EXPORT_SYMBOL(rt_free_rtai_trap_handler);EXPORT_SYMBOL(rt_is_linux);EXPORT_SYMBOL(up_task_sw);#include <asm-arm/arch/rtai_exports.h>

⌨️ 快捷键说明

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