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

📄 rtai.c

📁 rtai-3.1-test3的源代码(Real-Time Application Interface )
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * MIPS Port - Steve Papacharalambous (stevep@lineo.com) - 7 June 2001 * COPYRIGHT (C) 2001 Steve Papacharalambous. * COPYRIGHT (C) 2001  Paolo Mantegazza (mantegazza@aero.polimi.it) * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *//* * ACKNOWLEDGMENTS:  * - Steve Papacharalambous (stevep@zentropix.com) has contributed an * informative proc filesystem procedure. * Stuart Hughes (sehughes@zentropix.com) has helped a lot in debugging the  * porting of this module to 2.4.xx. *//* * Module to hook plain Linux up to do real time the way you like, hardware, * hopefully, fully trapped; the machine is in your hand, do what you want! *//* * Modified for 2.4.18 and other various things by Steven Seeger * sseeger@stellartec.com 07/08/2002 */#include <linux/module.h>#include <linux/version.h>#include <linux/sched.h>#include <linux/interrupt.h>#include <linux/irq.h>#include <linux/init.h>#include <linux/string.h>#include <asm/system.h>#include <asm/hw_irq.h>#include <asm/io.h>#ifdef CONFIG_PROC_FS#include <linux/stat.h>#include <linux/proc_fs.h>#include "rtai_proc_fs.h"#endif#include <asm/rtai.h>#include <asm/rtai_srq.h>#include <rtai_version.h>MODULE_LICENSE("GPL");/* proc filesystem additions. */static int rtai_proc_register(void);static void rtai_proc_unregister(void);/* End of proc filesystem additions. *//* Some defines. */#undef CONFIG_RTAI_MOUNT_ON_LOAD#define CONFIG_RTAI_MOUNT_ON_LOAD 1#define NR_GLOBAL_IRQS          64#define NR_RTAI_IRQS            64#define NR_SYSRQS               32#define LAST_GLOBAL_RTAI_IRQ    63#define IRQ_DESC ((irq_desc_t *)rthal.irq_desc)#define HINT_DIAG_LSTI#define HINT_DIAG_ECHO#define HINT_DIAG_LRSTF#ifdef HINT_DIAG_ECHO#define HINT_DIAG_MSG(x) x#else#define HINT_DIAG_MSG(x)#endif/* External definitions. */extern void *set_except_vector(int n, void *addr);extern unsigned char debug_pport;/* Function prototypes. */unsigned long linux_save_flags_and_cli(void);void rtai_just_copy_back(unsigned long flags, int cpuid);/* Data declarations. */static void (*global_irq_handler[NR_GLOBAL_IRQS])(void);static unsigned long linux_hz = 0;static unsigned long rtai_hz = 0;static unsigned int rt_timer_active;extern unsigned long cycles_per_jiffy; //new to 2.4.18static struct sysrq_t {	unsigned int label;	void (*rtai_handler)(void);	long long (*user_handler)(unsigned int whatever);} sysrq[NR_SYSRQS];struct rt_hal linux_rthal;static unsigned int (*linux_isr[NR_IRQS])(int irq, struct pt_regs *) = {0};/* * Array of pointers to pt_regs structures.  This is used by the * dispatch_xxxx functions to save the pt_regs structure pointers * until the linux ISR is invoked. * * This is a horrible temporary hack.  - Stevep :-( */struct pt_regs *rtai_regs[NR_IRQS];static struct hw_interrupt_type *linux_irq_desc_handler[NR_IRQS];static struct global_rt_status global;volatile unsigned int *locked_cpus = &global.locked_cpus;static struct cpu_own_status { 	volatile unsigned int intr_flag;	volatile unsigned int linux_intr_flag;	volatile unsigned int pending_irqs_l;	volatile unsigned int pending_irqs_h;   	volatile unsigned int activ_irqs;	volatile int irqs[NR_GLOBAL_IRQS];} processor[NR_RT_CPUS];static inline unsigned long hard_lock_all(void){	unsigned long flags;	hard_save_flags_and_cli(flags);	return(flags);} /* End function - hard_lock_all */#define hard_unlock_all(flags) hard_restore_flags((flags))/* * This is used in place of the standard Linux kernel function as the  * standard Linux assembler version doesn't work properly with the IDT * CPU (causes adel exceptions out of the wazoo) and the c version uses * cli which becomes a soft cli when rtai is mounted.  - Stevep */static inline unsigned long rtai_xchg_u32(volatile int *m, unsigned long val){	unsigned long flags, retval;	hard_save_flags_and_cli(flags);	retval = *m;	*m = val;	hard_restore_flags(flags);	return(retval);} /* End function - rtai_xchg_u32 *//* * Functions to control Advanced-Programmable Interrupt Controllers (A-PIC). */ /* * Now Linux has a per PIC spinlock, as it has always been in RTAI.  So there * is more a need to duplicate them here.  Note however that they are not * safe since interrupts has just soft disabled, so we have to provide the * hard cli/sti.  Moreover we do not want to run Linux_sti uselessly so we * clear also the soft flag. */static void (*internal_ic_ack_irq[NR_GLOBAL_IRQS]) (unsigned int irq);static void (*ic_ack_irq[NR_GLOBAL_IRQS]) (unsigned int irq);static void (*ic_end_irq[NR_GLOBAL_IRQS]) (unsigned int irq);static void (*linux_end_irq[NR_GLOBAL_IRQS]) (unsigned int irq);static void do_nothing_picfun(unsigned int irq) { }unsigned int rt_startup_irq(unsigned int irq){	unsigned long flags, lflags;	volatile int *lflagp;	int retval;	lflags = rtai_xchg_u32(lflagp = &processor[hard_cpu_id()].intr_flag, 0);	hard_save_flags_and_cli(flags);	retval = linux_irq_desc_handler[irq]->startup(irq);	hard_restore_flags(flags);	*lflagp = lflags;	return(retval);} /* End function - rt_startup_irq */void rt_shutdown_irq(unsigned int irq){	unsigned long flags, lflags;	volatile int *lflagp;	lflags = rtai_xchg_u32(lflagp = &processor[hard_cpu_id()].intr_flag, 0);	hard_save_flags_and_cli(flags);	linux_irq_desc_handler[irq]->shutdown(irq);	hard_restore_flags(flags);	*lflagp = lflags;} /* End function - rt_shutdown_irq */void rt_enable_irq(unsigned int irq){	unsigned long flags, lflags;	volatile int *lflagp;	lflags = rtai_xchg_u32(lflagp = &processor[hard_cpu_id()].intr_flag, 0);	hard_save_flags_and_cli(flags);	linux_irq_desc_handler[irq]->enable(irq);	hard_restore_flags(flags);	*lflagp = lflags;} /* End function - rt_enable_irq */void rt_disable_irq(unsigned int irq){	unsigned long flags, lflags;	volatile int *lflagp;	lflags = rtai_xchg_u32(lflagp = &processor[hard_cpu_id()].intr_flag, 0);	hard_save_flags_and_cli(flags);	linux_irq_desc_handler[irq]->disable(irq);	hard_restore_flags(flags);	*lflagp = lflags;} /* End function - rt_disable_irq */void rt_mask_and_ack_irq(unsigned int irq){	unsigned long flags, lflags;	volatile int *lflagp;	lflags = rtai_xchg_u32(lflagp = &processor[hard_cpu_id()].intr_flag, 0);	hard_save_flags_and_cli(flags);	ic_ack_irq[irq](irq);	hard_restore_flags(flags);	*lflagp = lflags;} /* End function - rt_mask_and_ack_irq */void rt_ack_irq(unsigned int irq){	unsigned long flags, lflags;	volatile int *lflagp;	lflags = rtai_xchg_u32(lflagp = &processor[hard_cpu_id()].intr_flag, 0);	hard_save_flags_and_cli(flags);	internal_ic_ack_irq[irq](irq);	hard_restore_flags(flags);	*lflagp = lflags;} /* End function - rt_ack_irq */void rt_unmask_irq(unsigned int irq){	unsigned long flags, lflags;	volatile int *lflagp;	lflags = rtai_xchg_u32(lflagp = &processor[hard_cpu_id()].intr_flag, 0);        hard_save_flags_and_cli(flags);	ic_end_irq[irq](irq);	hard_restore_flags(flags);	*lflagp = lflags;} /* End function - rt_unmask_irq *//* * The functions below are the same as those above, except that we do not need * to save the hard flags as they have the interrupt bit set for sure. */unsigned int trpd_startup_irq(unsigned int irq){	unsigned int lflags;	volatile unsigned int *lflagp;	int retval;	lflags = rtai_xchg_u32(lflagp = &processor[hard_cpu_id()].intr_flag, 0);	hard_cli();	retval = linux_irq_desc_handler[irq]->startup(irq);	hard_sti();	*lflagp = lflags;	return(retval);} /* End function - trpd_startup_irq */void trpd_shutdown_irq(unsigned int irq){	unsigned int lflags;	volatile unsigned int *lflagp;	lflags = rtai_xchg_u32(lflagp = &processor[hard_cpu_id()].intr_flag, 0);	hard_cli();	linux_irq_desc_handler[irq]->shutdown(irq);	hard_sti();	*lflagp = lflags;} /* End function - trpd_shutdown_irq */void trpd_enable_irq(unsigned int irq){	unsigned int lflags;	volatile unsigned int *lflagp;	lflags = rtai_xchg_u32(lflagp = &processor[hard_cpu_id()].intr_flag, 0);	hard_cli();	linux_irq_desc_handler[irq]->enable(irq);	hard_sti();	*lflagp = lflags;} /* End function - trpd_enable_irq */void trpd_disable_irq(unsigned int irq){	unsigned int lflags;	volatile unsigned int *lflagp;	lflags = rtai_xchg_u32(lflagp = &processor[hard_cpu_id()].intr_flag, 0);	hard_cli();	linux_irq_desc_handler[irq]->disable(irq);	hard_sti();	*lflagp = lflags;} /* End function - trpd_disable_irq */void trpd_end_irq(unsigned int irq){	unsigned int lflags;	volatile unsigned int *lflagp;	lflags = rtai_xchg_u32(lflagp = &processor[hard_cpu_id()].intr_flag, 0);	hard_cli();	linux_end_irq[irq](irq);	hard_sti();	*lflagp = lflags;} /* End function - trpd_end_irq */void trpd_set_affinity(unsigned int irq, unsigned long mask){	unsigned int lflags;	volatile unsigned int *lflagp;	lflags = rtai_xchg_u32(lflagp = (int *)&processor[hard_cpu_id()].intr_flag, 0);	hard_cli();	linux_irq_desc_handler[irq]->set_affinity(irq, mask);	hard_sti();	*lflagp = lflags;} /* End function - trpd_set_affinity */static struct hw_interrupt_type trapped_linux_irq_type = {	"RT SPVISD",	trpd_startup_irq,	trpd_shutdown_irq,	trpd_enable_irq,	trpd_disable_irq,	do_nothing_picfun,	trpd_end_irq,	trpd_set_affinity };static struct hw_interrupt_type real_time_irq_type = {	"REAL TIME",	(unsigned int (*)(unsigned int))do_nothing_picfun,	do_nothing_picfun,	do_nothing_picfun,	do_nothing_picfun,	do_nothing_picfun,	do_nothing_picfun,	(void (*)(unsigned int, unsigned long)) do_nothing_picfun };void rt_switch_to_linux(int cpuid){	set_bit(cpuid, &global.used_by_linux);	processor[cpuid].intr_flag = processor[cpuid].linux_intr_flag;} /* End function - rt_switch_to_linux */void rt_switch_to_real_time(int cpuid){	processor[cpuid].linux_intr_flag =			xchg(&(processor[cpuid].intr_flag), 0);	clear_bit(cpuid, &global.used_by_linux);} /* End function - rt_switch_to_linux *//* * 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_GLOBAL_IRQS];static int chained_to_linux[NR_GLOBAL_IRQS];int rt_request_global_irq(unsigned int irq, void (*handler)(void)){	unsigned long flags;	if(irq >= NR_GLOBAL_IRQS  || !handler) {

⌨️ 快捷键说明

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