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

📄 rtai.c

📁 rtai-3.1-test3的源代码(Real-Time Application Interface )
💻 C
📖 第 1 页 / 共 3 页
字号:
{	unpatch_function(&__cli,saved_insns_cli);	unpatch_function(&__sti,saved_insns_sti);	unpatch_function(&__save_flags_ptr,saved_insns_save_flags);	unpatch_function(&__restore_flags,saved_insns_restore_flags);}#endifvoid __rt_mount_rtai(void){#define MSR(x) ((struct pt_regs *)((x)->thread.ksp + STACK_FRAME_OVERHEAD))->msr	struct task_struct *task;     	unsigned long flags, i;	printk("rtai: mounting\n");#ifdef CONFIG_SMP	global_irq[HARD_LOCK_IPI].handler = hard_lock_all_handler;#endif	flags = hard_lock_all();#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2) // approximate	install_patch();#else	int_control.int_cli           = linux_cli;	int_control.int_sti           = linux_sti;	int_control.int_save_flags    = linux_save_flags;	int_control.int_restore_flags = linux_restore_flags;#endif#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,3) // approximate	int_control.int_set_lost      = (void (*)(unsigned long))rt_pend_linux_irq;#endif	ppc_md.get_irq = trpd_get_irq;	do_IRQ_intercept = (unsigned long)dispatch_irq;	timer_interrupt_intercept = (unsigned long)dispatch_timer_irq;	rtai_soft_sti = linux_sti; /* and not linux_soft_sti */	atomic_set(&ppc_n_lost_interrupts, 0);	for (i = 0; i < NR_MASK_WORDS; i++) {		ppc_lost_interrupts[i] = 0;	}	for (i = 0; i < NR_IRQS; i++) {		if (IRQ_DESC[i].handler) {			IRQ_DESC[i].handler = &trapped_linux_irq_type;		}	}	task = &init_task;	MSR(task) |= MSR_EE;	if (task->thread.regs) {		(task->thread.regs)->msr |= MSR_EE;	}	for_each_task(task) {		MSR(task) |= MSR_EE;		if (task->thread.regs) {			(task->thread.regs)->msr |= MSR_EE;		}	}	hard_unlock_all(flags);	//printk("\n***** RTAI NEWLY MOUNTED (MOUNT COUNT %d) ******\n\n", rtai_mounted);	printk("rtai: mount done\n");}// Simple, now we can simply block other processors and copy original data back// to Linux. The HARD_LOCK_IPI is the last one to be reset.void __rt_umount_rtai(void){	int i;	unsigned long flags;	flags = hard_lock_all();	rtai_srq_bckdr			= 0;	rtai_soft_sti			= 0;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2)	uninstall_patch();	for(i=0;i<NR_CPUS;i++){		disarm_decr[i]=0;	}#endif#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,3)	int_control               = ppc_int_control;#endif	timer_interrupt_intercept = ppc_timer_handler;	do_IRQ_intercept          = ppc_irq_dispatcher;	ppc_md.get_irq            = ppc_get_irq;	for (i = 0; i < NR_IRQS; i++) {		IRQ_DESC[i].handler = linux_irq_desc_handler[i];	}#ifdef CONFIG_SMP	global_irq[HARD_LOCK_IPI].handler = 0;	global_irq[HARD_LOCK_IPI].dest_status = 0;#endif#ifdef CONFIG_4xx        /* Reenable auto-reload mode used by Linux */        if ((mfspr(SPRN_TCR) & TCR_ARE) == 0) {		while (get_dec_4xx() > 0);		mtspr(SPRN_TCR,  mfspr(SPRN_TCR) | TCR_ARE);		set_dec_4xx(tb_ticks_per_jiffy);        }#else	while (get_dec() <= tb_ticks_per_jiffy);	set_dec(tb_ticks_per_jiffy);#endif	/* XXX We probably should change the per-process soft	 * interrupt flags back to MSR_EE here. */	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);	rtai_mounted++;	MOD_INC_USE_COUNT;	TRACE_RTAI_MOUNT();	if(rtai_mounted==1)__rtai_mount_rtai();	rt_spin_unlock(&rtai_mount_lock);}void rt_umount_rtai(void){	rt_spin_lock(&rtai_mount_lock);	rtai_mounted--;	MOD_DEC_USE_COUNT;	TRACE_RTAI_UMOUNT();	if(!rtai_mounted)__rtai_umount_rtai();	rt_spin_unlock(&rtai_mount_lock);}#endif// Module parameters to allow frequencies to be overriden via insmodstatic int CpuFreq = 0;MODULE_PARM(CpuFreq, "i");/* module init-cleanup */static 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 esplicitly for emphasis.int init_module(void){     	unsigned int i;	// Passed in CPU frequency overides auto detected Linux value	if (CpuFreq == 0) {	    	extern unsigned tb_ticks_per_jiffy;		CpuFreq = HZ * tb_ticks_per_jiffy;	}	tuned.cpu_freq = CpuFreq;	printk("rtai: decrementer frequency %d Hz\n",tuned.cpu_freq);#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,3)	ppc_int_control    = int_control;#endif	ppc_get_irq        = ppc_md.get_irq;	ppc_irq_dispatcher = do_IRQ_intercept;	ppc_timer_handler  = timer_interrupt_intercept;       	global.pending_irqs    = 0;       	global.activ_irqs      = 0;       	global.pending_srqs    = 0;       	global.activ_srqs      = 0;       	global.cpu_in_sti      = 0;	global.used_by_linux   = ~(0xFFFFFFFF << smp_num_cpus);#ifdef CONFIG_SMP	global.locked_cpus     = 0;	global.hard_nesting    = 0;      	spin_lock_init(&(global.hard_lock));#endif      	spin_lock_init(&(global.data_lock));      	spin_lock_init(&global.global.ic_lock);	for (i = 0; i < NR_RT_CPUS; i++) {		processor[i].intr_flag         = (1 << IFLAG) | (1 << i);		processor[i].linux_intr_flag   = (1 << IFLAG) | (1 << i);		processor[i].pending_irqs      = 0;		processor[i].activ_irqs        = 0;		processor[i].rt_timer_handler  = 0;		processor[i].trailing_irq_handler      = 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_RTAI_IRQS; i++) {		global_irq[i].ppc_irq = 0;		global_irq[i].mapped  = RTAI_IRQ_UNMAPPED;#ifdef CONFIG_SMP		global_irq[i].dest_status = 0;#endif		global_irq[i].handler = 0;		global_irq[i].ext = 0;		global_irq[i].irq_count = 0;	}	for (i = 0; i < NR_IRQS; i++) {		ic_ack_irq[i] = do_nothing_picfun;		if ((linux_irq_desc_handler[i] = IRQ_DESC[i].handler)) {			ic_ack_irq[i] = (IRQ_DESC[i].handler)->ack;		}		if (IRQ_DESC[i].handler && IRQ_DESC[i].action) {#ifdef CONFIG_SMP			if (i < OPENPIC_VEC_IPI) {				map_global_ppc_irq(i);			} else {				map_cpu_own_ppc_irq(i);			}#else			map_global_ppc_irq(i);#endif		} else {			rtai_irq[i] = -1;		}	}	sysrq[1].rtai_handler = rt_printk_sysreq_handler;	sysrq[1].label = 0x1F0000F1;#ifdef CONFIG_RTAI_MOUNT_ON_LOAD	__rt_mount_rtai();#endif#ifdef CONFIG_PROC_FS	rtai_proc_register();#endif	return 0;}void cleanup_module(void){#ifdef CONFIG_RTAI_MOUNT_ON_LOAD	__rt_umount_rtai();#endif#ifdef CONFIG_PROC_FS	rtai_proc_unregister();#endif	return;}/* ----------------------< 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("    Mount count: %d\n", rtai_mounted);        PROC_PRINT("    Frequency  : %d\n", FREQ_DECR);        PROC_PRINT("    Latency    : %d ns\n", LATENCY_DECR);        PROC_PRINT("    Setup time : %d ns\n", SETUP_TIME_DECR);        PROC_PRINT("\nGlobal irqs used by RTAI:\n");        for (i = 0; i <= LAST_GLOBAL_RTAI_IRQ; i++) {          if (global_irq[i].handler) {            PROC_PRINT("%3d: %10i\n", 		       global_irq[i].ppc_irq, global_irq[i].irq_count);          }        }#ifdef CONFIG_SMP        PROC_PRINT("\nCpu_Own irqs used by RTAI: \n");        for (i = LAST_GLOBAL_RTAI_IRQ + 1; i < NR_RTAI_IRQS; i++) {          if (global_irq[i].handler) {            PROC_PRINT("%d ", global_irq[i].ppc_irq);          }        }#endif        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);          }        }        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];void rt_request_timer(void (*handler)(void), unsigned int tick, int unused){	unsigned int cpuid;	RTIME t;	unsigned long flags;	TRACE_RTAI_TIMER(TRACE_RTAI_EV_TIMER_REQUEST, handler, tick);	if (processor[cpuid = hard_cpu_id()].rt_timer_handler) {		return;	}	flags = hard_lock_all();#ifdef CONFIG_4xx	/* Disable auto-reload mode used by Linux */	mtspr(SPRN_TCR,  mfspr(SPRN_TCR) & ~TCR_ARE);	do {		t = rdtsc();	} while (get_dec_4xx() > 0);#else	do {		t = rdtsc();	} while (get_dec() <= tb_ticks_per_jiffy);#endif#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2)	disarm_decr[cpuid]=1;#else	rtai_regs.trap = 1;#endif	rt_times.linux_tick = tb_ticks_per_jiffy;	rt_times.periodic_tick = tick > 0 && tick < tb_ticks_per_jiffy ? tick : rt_times.linux_tick;	rt_times.tick_time  = t;	rt_times.intr_time  = t + rt_times.periodic_tick;	rt_times.linux_time = t + rt_times.linux_tick;	processor[cpuid].rt_timer_handler = handler;	rt_set_decrementer_count(rt_times.periodic_tick);	hard_unlock_all(flags);	return;}void rt_free_timer(void){	unsigned long flags;	TRACE_RTAI_TIMER(TRACE_RTAI_EV_TIMER_FREE, 0, 0);	flags = hard_lock_all();#ifdef CONFIG_4xx	/* Restore auto-reload mode for Linux */	mtspr(SPRN_TCR, mfspr(SPRN_TCR) | TCR_ARE);	/* Set the PIT reload value and just let it run. */	mtspr(SPRN_PIT, tb_ticks_per_jiffy);#endif#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2)	disarm_decr[hard_cpu_id()]=0;#else	rtai_regs.trap = 0;#endif	processor[hard_cpu_id()].rt_timer_handler = 0;	hard_unlock_all(flags);}void rt_request_apic_timers(void (*handler)(void), struct apic_timer_setup_data *apic_timer_data){	RTIME t;	int cpuid;	unsigned long flags;	struct apic_timer_setup_data *p;	struct rt_times *rt_times;	TRACE_RTAI_TIMER(TRACE_RTAI_EV_TIMER_REQUEST_APIC, handler, 0);	flags = hard_lock_all();	do {		t = rdtsc();	} while (get_dec());	for (cpuid = 0; cpuid < NR_RT_CPUS; cpuid++) {		*(p = apic_timer_data + cpuid) = apic_timer_data[cpuid];		rt_times = rt_smp_times + cpuid;		p->mode = 1;		rt_times->linux_tick = tb_ticks_per_jiffy;		rt_times->tick_time = llimd(t + tb_ticks_per_jiffy, FREQ_DECR, tuned.cpu_freq);		rt_times->periodic_tick = 		p->count = p->mode > 0 ? imuldiv(p->count, FREQ_DECR, 1000000000) : tb_ticks_per_jiffy;		rt_times->intr_time = rt_times->tick_time + rt_times->periodic_tick;		rt_times->linux_time = rt_times->tick_time + rt_times->linux_tick;		processor[cpuid = hard_cpu_id()].rt_timer_handler = handler;	}	hard_unlock_all(flags);	for (cpuid = 0; cpuid < NR_RT_CPUS; cpuid++) {		if ((p = apic_timer_data + cpuid)->mode > 0) {			p->mode = 1;			p->count = imuldiv(p->count, FREQ_DECR, 1000000000);		} else {			p->mode = 0;			p->count = imuldiv(p->count, tuned.cpu_freq, 1000000000);		}	}}void rt_free_apic_timers(void){	unsigned long flags, cpuid;	TRACE_RTAI_TIMER(TRACE_RTAI_EV_TIMER_APIC_FREE, 0, 0);	flags = hard_lock_all();	for (cpuid = 0; cpuid < NR_RT_CPUS; cpuid++) {		processor[cpuid = hard_cpu_id()].rt_timer_handler = 0;	}	hard_unlock_all(flags);}/******** 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;}/* *  rt_printk.c, hacked from linux/kernel/printk.c. * * Modified for RT support, David Schleef. * * Adapted to RTAI, and restyled his way by Paolo Mantegazza. Now it has been * taken away from the fifos module and has become an integral part of the basic * RTAI module. */#define PRINTK_BUF_LEN	(4096)#define TEMP_BUF_LEN	(256)static char rt_printk_buf[PRINTK_BUF_LEN];static int buf_front, buf_back;static char buf[TEMP_BUF_LEN];int rt_printk(const char *fmt, ...){        static spinlock_t display_lock = SPIN_LOCK_UNLOCKED;	va_list args;	int len, i;	unsigned long flags;        flags = rt_spin_lock_irqsave(&display_lock);	va_start(args, fmt);	len = vsprintf(buf, fmt, args);	va_end(args);	if (buf_front + len >= PRINTK_BUF_LEN) {		i = PRINTK_BUF_LEN - buf_front;		memcpy(rt_printk_buf + buf_front, buf, i);		memcpy(rt_printk_buf, buf + i, len - i);		buf_front = len - i;	} else {		memcpy(rt_printk_buf + buf_front, buf, len);		buf_front += len;	}        rt_spin_unlock_irqrestore(flags, &display_lock);	rt_pend_linux_srq(1);	return len;}static void rt_printk_sysreq_handler(void){	int tmp;	while(1) {		tmp = buf_front;		if (buf_back  > tmp) {			printk("%.*s", PRINTK_BUF_LEN - buf_back, rt_printk_buf + buf_back);			buf_back = 0;		}		if (buf_back == tmp) {			break;		}		printk("%.*s", tmp - buf_back, rt_printk_buf + buf_back);		buf_back = tmp;	}}

⌨️ 快捷键说明

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