关于51系列单片机中断嵌套[推荐阅读]

时间:2019-05-14 17:39:35下载本文作者:会员上传
简介:写写帮文库小编为你整理了多篇相关的《关于51系列单片机中断嵌套》,但愿对你工作学习有帮助,当然你在写写帮文库还可以找到更多《关于51系列单片机中断嵌套》。

第一篇:关于51系列单片机中断嵌套

说最基本的,老的51单片机(80C51系列)有5个中断源,2个优先级,可以实现二级中断服务嵌套。现在很多扩展的51单片机已经有4个优先级(或更多)和更多的中断源了。

在说到中断之前,我先来定义一下优先级,明白了什么是优先级,后面的阐述就容易明白了。实际上很多人都是混淆了优先级的含义,所以才觉得糊里糊涂。

中断的优先级有两个:查询优先级和执行优先级。

什么是查询优级呢?我们从datasheet或书上看到的默认(IP寄存器不做设置,上电复位后为00H)的优先级:

外部中断0 > 定时/计数器0 > 外部中断1 > 定时/计数器1 > 串行中断 或 int0,timer0,int1,timer1,serial port 或 INT0、T0、INT1、T1、UART 或 PX0>PT0>PX1>PT1>PS>......其实都是查询优级。首先查询优先级是不可以更改和设置的。这是一个中断优先权排队的问题。是指多个中断源同时产生中断信号时,中断仲裁器选择对哪个中断源优先处理的顺序。而这与是否发生中断服务程序的嵌套毫不相干。当CPU查询各个中断标志位的时候,会依照上述5个查询优先级顺序依次查询,当数个中断同时请求的时候,会优先查询到高优查询先级的中断标志位,但并不代表高查询优先级的中断可以打断已经并且正在执行的低查询优先级的中断服务。

例如:当计数器0中断和外部中断1(按查询优先级,计数器0中断>外部中断1)同时到达时,会进入计时器0的中断服务函数;但是在外部中断1的中断服务函数正在服务的情况下,这时候任何中断都是打断不了它的,包括逻辑优先级比它高的外部中断0计数器0中断。

而中断的执行优先级就是你对IP寄存器的设置了。在2个优先级的情况下,某位为1,则相应的中断源为高优先级;为0,则为低优先级。

关于中断的优先级有三条原则:

1、CPU同时接收到几个中断时,首先响应优先级最高的中断请求;

2、正在进行的中断过程不能被新的同级或低行优优先级的中断请求所中断;

3、正在进行的低行优优先级中断服务,能被高行优优先级中断请求中断;

若:同一执行优先级中的中断申请不止一个时,则有一个中断优先权排队问题。同一执行优先级的中断优先权排队,由中断系统硬件确定的自然优先级形成,优先权自高到低的顺序即: 外部中断0>定时/计数0>外部中断1>定时/计数1>串行接口

例如:设置IP = 0x10,即设置串口中断为最高优先级,则串口中断可以打断任何其他的中断服务函数实现嵌套,且只有串口中断能打断其他中断的服务函数。若串口中断没有触发,则其他几个中断之间还是保持逻辑优先级,相互之间无法嵌套。

关于中断嵌套。可以这样说,当一个中断正在执行的时候,如果事先设置了中断优先级寄存器IP,那么当一个更高优先级的中断到来的时候会发生中断嵌套,如果没有设置则不会发

生任何嵌套;如果有同一个优先级的中断触发,它并不是在“不断的申请”,而是将它相应的中断标志位置即IE寄存器的某位置位,当CPU执行完当前中断之后,按照查询优先级重新去查询各个中断标志位,进入相应中断。

要记住,没有设置IP时,单片机会按照查询优先级(或都说逻辑优先级)来排队进入服务。如果要想让某个中断优先响应,则要设置IP,更改执行优先级(或者说物理优先级)。要注意的是,当设置了IP后,当低执行优先级中断在运行时,如果有高执行优先级的中断产生,则会嵌套调用进入高执行优先级的中断。如果你是用C语言写的程序,并在中断服务时 using 了寄存组,要注意,两个不同执行优先级的中断服务程序不要 using 同一组寄存器。

看两个问题,如下: 在各个中断都是低优先级的时候,如果定时器0的溢出进入中断。在这个中断处理的过程中,外部中断0也被触发了,那么是不是要发生中断嵌套? 如果定时器0发生中断的时候,进入中断处理程序,这个时候外部中断1条件触发条件满足了。因为定时器0自然优先级比外部中断1高,那么定时器0的中断处理程序继续执行。假设定时器中断处理程序执行的过程中,外部中断1的触发。条件消失了,那么等定时器0的中断处理完后,程序还是会进入外部中断1处理程序吗?

答案1:在IP事先设置了外部中断0的优先级的情况下,CUP会中止定时器0的中断服务,进入外部中断0服务程序,执行完以后再回到定时器0中断服务程序。否则不会。

答案2:肯定会进入中断的;外部中断1的触发条件满足后会置位外部1的中断标志,即使后来外部中断1的触发条件消失了,也不会清除已置位的中断标志,所以等定时器0的中断处理完后,程序判断外部中断的中断标志为1后依然会进入外部中断1处理程序的,只有在外部中断1处理程序中执行reti指令才会硬件清除外部中断1的中断标志(这也正是为什么中断返回使用reti指令而不可以用ret替换的原因)...

第二篇:51单片机中断学习

51单片机中断学习

一、中断的概念

CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理(中断发生);CPU暂时中断当前的工作,转去处理事件B(中断响应和中断服务);

待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A(中断返回),这一过程称为中断

二、中断源

在51单片机中有5个中断源

中断号优先级中断源中断入口地址

01(最高)外部中断00003H12定时器0000BH

23外部中断10013H

34定时器10018H

45串口总段0023H

三、中断寄存器

单片机有10个寄存器主要与中断程序的书写控制有关

1.中断允许控制寄存器IE

2.定时器控制寄存器TCON

3.串口控制寄存器SCON

4.中断优先控制寄存器IP

5.定时器工作方式控制寄存器TMOD

6.定时器初值赋予寄存器(TH0/TH1,TL0/TL1)T

第三篇:亲子关系中断[范文]

“亲子关系中断”与疗愈

“亲子关系中断”。通常来说,0-7岁的孩子,尤其是0-3岁之间的孩子,最好和父母在一起,受到父母的照顾。如果要和父母分开的话,分开的时间也不要太长。因为0-3岁的孩子,神经系统还没有足够的承受力,如果跟父母分离很长时间,会产生极度的恐惧,对孩子来讲是一个很大的情绪创伤。孩子长大之后,他/她内心的安全感,他/她与人连结的能力都会受到影响。

“铁脸实验”,把一群一两岁的孩子放在一个游戏室里,让这些孩子去玩,然后让妈妈全部出去。孩子玩了一会,发现妈妈不见了,就开始哭,开始叫。实验人员规定,这种情况下,不管孩子怎么哭怎么叫,妈妈都不要理他/她,妈妈都要拒绝他/她。这样几轮下来之后,突然有一刻,所有的孩子都不再哭了,都安静下来了。这时候妈妈再上来逗孩子,孩子的表情都成了“铁脸”,没表情了,麻木了,不理妈妈了。

实验到了这里,无法在进行下去,因为妈妈们投诉得很厉害。由此也可以看到,当小孩子被妈妈拒绝,被妈妈忽略,被妈妈不理会,离开妈妈的时候,遭到的创伤。

当孩子比较小的时候,你可以上班,可以出差,但是请尽量多的与孩子待在一起。你每次回家,最好多拥抱他/她一会。孩子在父母的怀抱里,感觉是最安全的。父母,尤其是妈妈,既是创伤的开始,也是疗愈的开始。

在孩子0-3岁这段时间,谁在照顾他/她,他/她就可能把这个人当成自己的爸爸妈妈。所以养育孩子,最好父母自己带;第二给自己的父母带,也就是爷爷奶奶、姥姥姥爷带,再其次是给自己的兄弟姐妹带,比如叔叔姑姑;最次是给陌生人带,比如让阿姨带,让保姆带,而且父母也不经常去看孩子,这对孩子会是相当大的心理创伤。

问:如果创伤已经发生,怎样去弥补?

答:刚才说了,有一种方式叫“强抱”,紧紧地去拥抱孩子,不管孩子愿不愿意,你都去拥抱他/她。例如七八岁的孩子,调皮捣蛋,父母去抱他/她,他/她往往会把父母推开。但是你耐心一点,多抱一会儿,比如一个小时,你会发现孩子会软化下来,孩子其实很需要你。

问:如果早年有亲子关系的创伤,父母已经去世了,该怎么办?

答:有个方法,找个老婆回来,先当她是妈,然后再把她当成伴侣,也有疗愈效果。

第四篇:linux中断总结

1.Linux中断的注册与释放:

, , 实现中断注册接口: int request_irq(unsigned int irq,irqreturn_t(*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *dev_name, void *dev_id);void free_irq(unsigned int irq, void *dev_id);函数参数说明

unsigned int irq:所要注册的中断号

irqreturn_t(*handler)(int, void *, struct pt_regs *):中断服务程序的入口地址。unsigned long flags:与中断管理有关的位掩码选项,有三组值: 1.SA_INTERRUPT :快速中断处理程序,当使用它的是后处理器上所有的其他中断都被禁用。2.SA_SHIRQ :该中断是在设备之间可共享的

3.SA_SAMPLE_RANDOM :这个位表示产生的中断能够有贡献给 /dev/random 和 /dev/urandom 使用的加密池.(此处不理解)const char *dev_name:设备描述,表示那一个设备在使用这个中断。void *dev_id:用作共享中断线的指针.它是一个独特的标识, 用在当释放中断线时以及可能还被驱动用来指向它自己的私有数据区(来标识哪个设备在中断)。这个参数在真正的驱动程序中一般是指向设备数据结构的指针.在调用中断处理程序的时候它就会传递给中断处理程序的void *dev_id。(这是我的理解)如果中断没有被共享, dev_id 可以设置为 NULL, 但是使用这个项指向设备结构不管如何是个好主意.我们将在“实现一个处理”一节中看到 dev_id 的一个实际应用。

中断号的查看可以使用下面的命令:“cat /proc/interrupts”。

/proc/stat 记录了几个关于系统活动的低级统计量, 包括(但是不限于)自系统启动以来收到的中断数.stat 的每一行以一个文本字串开始, 是该行的关键词;intr 标志是我们在找的.第一个数是所有中断的总数, 而其他每一个代表一个单个 IRQ 线, 从中断 0 开始.所有的计数跨系统中所有处理器而汇总的.这个快照显示, 中断号 4 已使用 1 次, 尽管当前没有安装处理.如果你在测试的驱动请求并释放中断在每个打开和关闭循环, 你可能发现 /proc/stat 比 /proc/interrupts 更加有用.以下是一个统计中断时间间隔的中断服务程序。

irqreturn_t short_interrupt(int irq, void *dev_id, struct pt_regs *regs){ static long mytime=0;static int i=0;struct net_device *dev=(struct net_device *)dev_id;if(i==0){ mytime=jiffies; }else if(i<20){ mytime =jiffies-mytime;printk(“Request on IRQ %d time %dn”,irq , mytime);mytime=jiffies; printk(“Interrupt on %s-----%d n”,dev->name,dev->irq);} i;return IRQ_HANDLED;} 这个函数实现的只是对两次发生中断的时间间隔的统计,时间单位是毫秒

前言

在前面分析了中断的基本原理后,就可以写一个内核中断程序来体验以下,也可以借此程序继续深入来了解内核中断的执行过程 一.内核中断程序 :

我们还是来看一看成程序:

在看程序之前,要熟悉如何进行模块编程,和了解module_pararm()的用法。如果不熟悉的话请大家看,module_param()的学习和Linux内核模块编程,在此不作解释。1.程序interrupt.c /* 2 *file name :interrupt.c 3 *atuthor : john 4 */ 5 #include 6 #include 7 #include 8 #include 9 10 MODULE_LICENSE(“GPL”);11 static int irq;12 char *interface;13 static irqreturn_t myirq_handler(int irq,void *dev);14 15 static int __init myirq_init(void)16 { 17 printk(“the module is working!n”);18 printk(“the irq is ready for working!n”);19 if(request_irq(irq,myirq_handler,IRQF_SHARED,interface,&irq)){ 20

printk(KERN_ERR “%s interrrupt can't register %d IRQ n”,interface,irq);21 return-EIO;22 } 23 printk(“%s request %d IRQn”,interface,irq);24 return 0;25 } 26 static irqreturn_t myirq_handler(int irq,void *dev)27 { 28 printk(“%d IRQ is workingn”,irq);29 return IRQ_NONE;30 } 31 static void __exit myirq_exit(void)32 { 33 printk(“the module is leaving!n”);34 printk(“the irq is bye bye!n”);35 free_irq(irq,&irq);36 printk(“%s interrupt free %d IRQn”,interface,irq);37 38 } 39 module_init(myirq_init);0 module_exit(myirq_exit);41 module_param(interface,charp,0644);42 module_param(irq,int,0644);43 1 /* 2 *file name :interrupt.c 3 *atuthor : john 4 */ 5 #include 6 #include 7 #include 8 #include 9 10 MODULE_LICENSE(“GPL”);11 static int irq;12 char *interface;13 static irqreturn_t myirq_handler(int irq,void *dev);14 15 static int __init myirq_init(void)16 { 17 printk(“the module is working!n”);18 printk(“the irq is ready for working!n”);19 if(request_irq(irq,myirq_handler,IRQF_SHARED,interface,&irq)){ 20

printk(KERN_ERR “%s interrrupt can't register %d n”,interface,irq);21 return-EIO;22 } 23 printk(“%s request %d IRQn”,interface,irq);24 return 0;25 } 26 static irqreturn_t myirq_handler(int irq,void *dev)

IRQ 27 { 28 printk(“%d IRQ is workingn”,irq);29 return IRQ_NONE;30 } 31 static void __exit myirq_exit(void)32 { 33 printk(“the module is leaving!n”);34 printk(“the irq is bye bye!n”);35 free_irq(irq,&irq);36 printk(“%s interrupt free %d IRQn”,interface,irq);37 38 } 39 module_init(myirq_init);40 module_exit(myirq_exit);41 module_param(interface,charp,0644);42 module_param(irq,int,0644);43 2.Makefile的编写 1 obj-m:=tiger.o 2 3 CURRENT_PATH:=$(shell pwd)4 VERSION_NUM:=$(shell uname-r)5 LINUX_PATH:=/usr/src/linux-headers-$(VERSION_NUM)6 7 8 all : 9 make-C $(LINUX_PATH)M=$(CURRENT_PATH)modules 10 clean: 11 make-C $(LINUX_PATH)M=$(CURRENT_PATH)clean 1 obj-m:=tiger.o 2 3 CURRENT_PATH:=$(shell pwd)4 VERSION_NUM:=$(shell uname-r)5 LINUX_PATH:=/usr/src/linux-headers-$(VERSION_NUM)6 7 8 all : 9 make-C $(LINUX_PATH)M=$(CURRENT_PATH)modules 10 clean: 11 make-C $(LINUX_PATH)M=$(CURRENT_PATH)clean(程序的调试,加载和运行,在此不进行说明)3.首先我们来分析下内核加载模块

在内核加载模块中最重要的的action就是注册中断处理程序。很明显,这一动作是通过request_irq()函数来完成的。int request_irq(unsigned int irq, irq_handler_t handler,unsigned long flags, const char *devname, void *dev_id)A.先来分析形参:

第一个参数irq: 表示要分配的中断号。对于一些设备(系统时钟或键盘)它的值是预先固定的,而对于大多数设备来说,这个值是动态确定的。第二个参数 handler: 表示要挂入到中断请求对列中的中断服务例程,这个中断服务函数的原型是static irqreturn_t handler(int , void *);中断处理程序的前缀为static,因为它从来不会被别的文件中的代码直接调用。第三个参数flags:为标志位。可以取IRQF_DISABLED、IRQF_SHARED和IRQF_SAMPLE_RANDOM之一。在本实例程序中取 IRQF_SHARED,该标志表示多个中断处理程序共享irq中断线。一般某个中断线上的中断服务程序在执行时会屏蔽请求该线的其他中断,如果取 IRQF_DISABLED标志,则在执行该中断服务程序时会屏蔽所有其他的中断。取IRQF_SAMPLE_RANDOM则表示设备可以被看做是事件随见的发生源。以下是官方解释: /* * These flags used only by the kernel as part of the * irq handling routines.* * IRQF_DISABLEDirq is used to feed the random generator * IRQF_SHAREDset by callers when they expect sharing mismatches to occur * IRQF_TIMERInterrupt is per cpu * IRQF_NOBALANCINGInterrupt is used for polling(only the interrupt that is * registered first in an shared interrupt is considered for * performance reasons)*/ #define IRQF_DISABLED 0x00000020 #define IRQF_SAMPLE_RANDOM 0x00000040 #define IRQF_SHARED 0x00000080 #define IRQF_PROBE_SHARED 0x00000100 #define IRQF_TIMER 0x00000200 #define IRQF_PERCPU 0x00000400 #define IRQF_NOBALANCING 0x00000800 #define IRQF_IRQPOLL 0x00001000 /* * These flags used only by the kernel as part of the * irq handling routines.* * IRQF_DISABLEDirq is used to feed the random generator * IRQF_SHAREDset by callers when they expect sharing mismatches to occur * IRQF_TIMERInterrupt is per cpu * IRQF_NOBALANCINGInterrupt is used for polling(only the interrupt that is * registered first in an shared interrupt is considered for * performance reasons)*/ #define IRQF_DISABLED 0x00000020 #define IRQF_SAMPLE_RANDOM 0x00000040 #define IRQF_SHARED 0x00000080 #define IRQF_PROBE_SHARED 0x00000100 #define IRQF_TIMER 0x00000200 #define IRQF_PERCPU 0x00000400 #define IRQF_NOBALANCING 0x00000800 #define IRQF_IRQPOLL 0x00001000 第四个参数devname:是请求中断的设备的名称。当你加载模块成功后可以在/proc/interrupts中查看到具体设备的名称,与此同时也可以看到这个设备对应的中断号以及请求次数。

第五个参数dev_id:为一个指针型变量。注意该参数为void型,也就是说通过强制转换可以转换为任意类型。dev_id主要用于共享中断线,对每个注册的中断处理程序来说,(Dev_id must be globally unique.Normally the address of the device data structure is used as the cookie.)dev_id参数必须唯一(指向任一设备结构的指针就可以满足此要求,选择设备结构因为它是唯一的,而且中断处理程序可能会用到它)如果无需共享中断线,则将该参数赋值为NULL。B:函数返回值

requset_irq()函数成功执行后返回0。如果返回非0值,就表示错误发生。此时,指定的中断处理程序不会被注册。这里面有几个疑问: 为什么要注册中断函数

共享中断线的概念,参数dev_id的作用是什么 看一个图进行说明:

1>由图可知:有16个中断线。要使用中断线,就要进行中断线的 申请,也常把申请一条中断线称为申请一个中断号,这就 与request_irq()函数中的第一个形参 irq 有关系。2>Linux有256个中断向量,而外部中中断向量只有16个(32~47)。由于硬件上的限制,很多外部设备不得不共享中断线。

(例如:一些PC机所用的网卡和图形卡可以把它们分配到一条中断线上)让每个中断源独自占用一条中断线是不实现的。3>共享中断线的话虽然解决了中断资源的问题,但是,此时引出了另一个问题(任何事物都有其两面性),此时仅仅用中断描述符并不能提供中断产生的所有信息。为了解决这个问题,内核必须对中断线给出近一步的描述,所以在Linux设计中,为每个中断请求IRQ设置了一个专用队列(中断请求队列)。

4>中断服例程序和中断处理程序的区别: a.中断服务例程(interrupt service routine):

Linux中,15条中断线对应15个中断处理程序,依次命名是IRQ0x00_interrupt(),IRQ0x01_interrupt().....IRQ0X1f_interrupt().中断处理程序相当于某个中断向量的总处理程序。

eg:IRQ0X05_interupt()是5号中断(向量为37)的总处理程序。b.中断服务例程是针对一个具体设备的中断。5>.注册中断服务例程: 在IDT表完成初始化时,每个中断服务队列还为空。此时即使打开中断且某个外设的中断真的发生了,也得不到实际的服务。因为CPU虽然通过中断门进入了某个中断向量的总处理程序。但是,具体的中断服务例程还没有挂入中断请求队列。所以,在设备驱动程序的初始化阶段,必须通过request_irq()函数将响应的中断服务例程挂入中断请求队列,也就是进行注册。

6>分析一下中断服务程序,即request_irq()函数中第二个参数所对应的函数 static irqreturn_t myirq_handler(int irq,void *dev_id){ printk(“ISR is Workingn”);return IRQ_HANDLED;} 中断服务例程的形参: a.int irq :中断号。

b.void *dev_id :与request_irq()的参数dev_id一致,可以根据这个设备id号得到相应设备的数据结构,进而得到相应设备的信息和相关数据。

c.返回值:中断程序的返回值是一个特殊类型 rqreturn_t。但是中断程序的返回值却只有两个值IRQ_NONE和IRQ_HANDLED。

IRQ_NONE:中断程序接收到中断信号后发现这并不是注册时指定的中断原发出的中断信号。IRQ_HANDLED:接收到了准确的中断信号,并且作了相应正确的处理。一般 中断处理程序要做什么service,主要取决于产生的设备和该设备为什么要发送中断。John哥说明:

1.当一个给定的中断处理程序正在执行时,这条中断线上的其它中断都会被屏蔽。but,所有其他中断线上的中断都是打开的。因此这些不同中断线上的其他中断都能被处理。

2.request_irq()函数可能会睡眠,所以,不能在中断上下文或其它不允许阻塞的代码中调用该函数。

4.在深入分析request_irq()函数之前,先来看几个重要的数据结构。

A.irqaction的数据结构(用irqaction结构体来描述一个具体的中断服务例程)113struct irqaction { 114 irq_handler_t handler;115 unsigned long flags;116 const char *name;117 void *dev_id;118 struct irqaction *next;119 int irq;120 struct proc_dir_entry *dir;121 irq_handler_t thread_fn;122 struct task_struct *thread;123 unsigned long thread_flags;124};125 113struct irqaction { 114 irq_handler_t handler;115 unsigned long flags;116 const char *name;117 void *dev_id;118 struct irqaction *next;119 int irq;120 struct proc_dir_entry *dir;121 irq_handler_t thread_fn;122 struct task_struct *thread;123 unsigned long thread_flags;124};125

1>handler:指向具体的一个中断服务例程。

2>flags:表示中断标志位,对应于request_irq()函数中所传递的第三个参数,可取IRQF_DISABLED、IRQF_SAMPLE_RANDOM和IRQF_SHARED其中之一。

3>name:请求中断的设备名称,对应request_irq()函数中所传递的第四个参数

4>dev_id: 共享中断时有用。对应于request_irq()函数中所传递的第五个参数,可取任意值,但必须唯一能够代表发出中断请求的设备,通常取描述该设备的结构体。5>strct irqaction *next:指向irqaction描述符的下一个元素。用一条链表将共享同一条中断线上的中断服务例程链接起来。

6>irq:所申请的中断号

7>dir:指向proc/irq/NN/name entry

8>thread_fn:指向具体的一个线程化的中断。

9>thread:指向线程中断的指针。

10>thread_flags:线程中断的标志。

B.irq_desc的数据结构体 每个中断向量都有它自己的irq_desc 描述符。即用irq_desc来描述中断向量。所有的这些中断描述符组织在一起就形成了irq_desc irq_desc[NR_IRQS]数组

175struct irq_desc { 176 unsigned int irq;177 struct timer_rand_state *timer_rand_state;178 unsigned int *kstat_irqs;179#ifdef CONFIG_INTR_REMAP 180 struct irq_2_iommu *irq_2_iommu;181#endif 182 irq_flow_handler_t handle_irq;183 struct irq_chip *chip;184 struct msi_desc *msi_desc;185 void *handler_data;186 void *chip_data;187 struct irqaction *action;/* IRQ action list */ 188 unsigned int status;/* IRQ status */ 189 190 unsigned int depth;/* nested irq disables */ 191 unsigned int wake_depth;/* nested wake enables */ 192 unsigned int irq_count;/* For detecting broken IRQs */ 193 unsigned long last_unhandled;/* Aging timer for unhandled count */ 194 unsigned int irqs_unhandled;195 raw_spinlock_t lock;196#ifdef CONFIG_SMP 197 cpumask_var_t affinity;198 const struct cpumask *affinity_hint;199 unsigned int node;200#ifdef CONFIG_GENERIC_PENDING_IRQ 201 cpumask_var_t pending_mask;202#endif 203#endif 204 atomic_t threads_active;205 wait_queue_head_t wait_for_threads;206#ifdef CONFIG_PROC_FS 207 struct proc_dir_entry *dir;208#endif 209 const char *name;210} ____cacheline_internodealigned_in_smp;211 212extern void arch_init_copy_chip_data(struct irq_desc *old_desc, 213 struct irq_desc *desc, int node);214extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);215 216#ifndef CONFIG_SPARSE_IRQ 217extern struct irq_desc irq_desc[NR_IRQS];175struct irq_desc { 176 unsigned int irq;177 struct timer_rand_state *timer_rand_state;178 unsigned int *kstat_irqs;179#ifdef CONFIG_INTR_REMAP 180 struct irq_2_iommu *irq_2_iommu;181#endif 182 irq_flow_handler_t handle_irq;183 struct irq_chip *chip;184 struct msi_desc *msi_desc;185 void *handler_data;186 void *chip_data;187 struct irqaction *action;/* IRQ action list */ 188 unsigned int status;/* IRQ status */ 189 190 unsigned int depth;/* nested irq disables */ 191 unsigned int wake_depth;/* nested wake enables */ 192 unsigned int irq_count;/* For detecting broken IRQs */ 193 unsigned long last_unhandled;/* Aging timer for unhandled count */ 194 unsigned int irqs_unhandled;195 raw_spinlock_t lock;196#ifdef CONFIG_SMP 197 cpumask_var_t affinity;198 const struct cpumask *affinity_hint;199 unsigned int node;200#ifdef CONFIG_GENERIC_PENDING_IRQ 201 cpumask_var_t pending_mask;202#endif 203#endif 204 atomic_t threads_active;205 wait_queue_head_t wait_for_threads;206#ifdef CONFIG_PROC_FS 207 struct proc_dir_entry *dir;208#endif 209 const char *name;210} ____cacheline_internodealigned_in_smp;211 212extern void arch_init_copy_chip_data(struct irq_desc *old_desc, 213 struct irq_desc *desc, int node);214extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc);215 216#ifndef CONFIG_SPARSE_IRQ 217extern struct irq_desc irq_desc[NR_IRQS];

1>irq:表示这个描述符所对应的中断号。

2>handle_irq:指向该IRQ线的公共服务程序(即该IRQ所对应的中断处理程序。

3>chip:它是一个struct irq_chip类型的指针,是中断控制器的描述符。在2.6以前的版本中它是hw_irq_controller。

4>handler_data:是handler_irq的参数。5>chip_data:是指向irq_chip的指针。6>atcion:一个struct irqaction类型的指针,它指向一个单链表。该链表是由该中断线上所有中断服务例程链接起来的。7>status:表示中断线当前的状态。

8>depth:中断线被激活时,值为0;当值为正数时,表示被禁止的次数。9>irq_count:表示该中断线上发生中断的次数

10>irqs_unhandled:该IRQ线上未处理中断发生的次数 11>name:申请中断设备的名字。

C.struct irq_chip结构体:

struct irq_chip是一个中断控制器的描述符。Linux支持N种可编程中断控制器PIC(中断控制器),通常不同的体系结构就有一套自己的中断处理方式。内核为了统一的处理中断,提供了底层的中断处理抽象接口,对于每个平台都需要实现底层的接口函数。这样对于上层的中断通用处理程序就无需任何改动。

struct irq_chip的具体代码如下:

111struct irq_chip { 112 const char *name;113 unsigned int(*startup)(unsigned int irq);114 void(*shutdown)(unsigned int irq);115 void(*enable)(unsigned int irq);116 void(*disable)(unsigned int irq);117 118 void(*ack)(unsigned int irq);119 void(*mask)(unsigned int irq);120 void(*mask_ack)(unsigned int irq);121 void(*unmask)(unsigned int irq);122 void(*eoi)(unsigned int irq);123 124 void(*end)(unsigned int irq);125 int(*set_affinity)(unsigned int irq, 126 const struct cpumask *dest);127 int(*retrigger)(unsigned int irq);128 int(*set_type)(unsigned int irq, unsigned int flow_type);129 int(*set_wake)(unsigned int irq, unsigned int on);130 131 void(*bus_lock)(unsigned int irq);132 void(*bus_sync_unlock)(unsigned int irq);133 134 /* Currently used only by UML, might disappear one day.*/ 135#ifdef CONFIG_IRQ_RELEASE_METHOD 136 void(*release)(unsigned int irq, void *dev_id);137#endif 138 /* 139 * For compatibility,->typename is copied into->name.140 * Will disappear.141 */ 142 const char *typename;143};144 111struct irq_chip { 112 const char *name;113 unsigned int(*startup)(unsigned int irq);114 void(*shutdown)(unsigned int irq);115 void(*enable)(unsigned int irq);116 void(*disable)(unsigned int irq);117 118 void(*ack)(unsigned int irq);119 void(*mask)(unsigned int irq);120 void(*mask_ack)(unsigned int irq);121 void(*unmask)(unsigned int irq);122 void(*eoi)(unsigned int irq);123 124 void(*end)(unsigned int irq);125 int(*set_affinity)(unsigned int irq, 126 const struct cpumask *dest);127 int(*retrigger)(unsigned int irq);128

int

(*set_type)(unsigned int irq, unsigned int flow_type);129 int(*set_wake)(unsigned int irq, unsigned int on);130 131 void(*bus_lock)(unsigned int irq);132 void(*bus_sync_unlock)(unsigned int irq);133 134 /* Currently used only by UML, might disappear one day.*/ 135#ifdef CONFIG_IRQ_RELEASE_METHOD 136 void(*release)(unsigned int irq, void *dev_id);137#endif 138 /* 139 * For compatibility,->typename is copied into->name.140 * Will disappear.141 */ 142 const char *typename;143};144

name:中断控制器的名字; Startup:启动中断线; Shutdown:关闭中断线; Enable:允许中断; Disable:禁止中断;

分析了struct irq_desc,struct irq_chip和irqaction的数据结构之后我们来看看他们之间的关系。

现在深入分析request_irq()内部是如何实现的。

135request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, 136 const char *name, void *dev)137{ 138 return request_threaded_irq(irq, handler, NULL, flags, name, dev);139} 140 135request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, 136 const char *name, void *dev)137{ 138 return request_threaded_irq(irq, handler, NULL, flags, name, dev);139} 140

可以看到request_irq()函数里面有封装了request_threaded_irq(irq, handler, NULL, flags, name, dev)函数。

先看一下官方的解释

1006/** 1007 * request_threaded_irqallocate an interrupt line 1008 * @irq: Interrupt line to allocate 1009 * @handler: Function to be called when the IRQ occurs.1010 * Primary handler for threaded interrupts 1011 * If NULL and thread_fn!= NULL the default 1012 * primary handler is installed 1013 * @thread_fn: Function called from the irq handler thread 1014 * If NULL, no irq thread is created 1015 * @irqflags: Interrupt type flags 1016 * @devname: An ascii name for the claiming device 1017 * @dev_id: A cookie passed back to the handler function 1018 * 1019 * This call allocates interrupt resources and enables the 1020 * interrupt line and IRQ handling.From the point this 1021 * call is made your handler function may be invoked.Since 1022 * your handler function must clear any interrupt the board 1023 * raises, you must take care both to initialise your hardware 1024 * and to set up the interrupt handler in the right order.1025 * 1026 * If you want to set up a threaded irq handler for your device 1027 * then you need to supply @handler and @thread_fn.@handler ist 1028 * still called in hard interrupt context and has to check 1029 * whether the interrupt originates from the device.If yes it 1030 * needs to disable the interrupt on the device and return 1031 * IRQ_WAKE_THREAD which will wake up the handler thread and run 1032 * @thread_fn.This split handler design is necessary to support 1033 * shared interrupts.1034 * 1035 * Dev_id must be globally unique.Normally the address of the 1036 * device data structure is used as the cookie.Since the handler 1037 * receives this value it makes sense to use it.1038 * 1039 * If your interrupt is shared you must pass a non NULL dev_id 1040 * as this is required when freeing the interrupt.1041 * 1042 * Flags: 1043 * 1044 * IRQF_SHARED Interrupt is shared 1045 * IRQF_SAMPLE_RANDOM The interrupt can be used for entropy 1046 * IRQF_TRIGGER_* Specify active edge(s)or level 1047 * 1048 */

5.首先分析request_threaded_irq()函数中的各个形参 1>:irq:表示申请的中断号。2>:handler:表示中断服务例程

3.> thread_fn:中断线程化,此处传递的是NULL。NULL表示没有中断线程化。此参数是最新版本中才出现的。为什么要提出中断线程化? 在 Linux 中,中断具有最高的优先级。不论在任何时刻,只要产生中断事件,内核将立即执行相应的中断 处理程序,等到所有挂起的中断和软中断处理完毕后才能执行正常的任务,因此有可能造成实时任务得不

到及时的处理。中断线程化之后,中断将作为内核线程运行而且被赋予不同的实时优先级,实时任务可以

有比中断线程更高的优先级。这样,具有最高优先级的实时任务就能得到优先处理,即使在严重负载下仍

有实时性保证。but,并不是所有的中断都可以被线程化,比如时钟中断,主要用来维护系统时间以及定时器 等,其中定时器是操作系统的脉搏,一旦被线程化,就有可能被挂起,这样后果将不堪设想,所以不应当 被线程化。

4>.irqflags:表示中断标志位。

5>.devname:表示请求中断的设备的名称。

6>.dev_id: 对应于request_irq()函数中所传递的第五个参数,可取任意值,但必须唯一能够代表发出中断请求的设备,通常取描述该设备的结构体。共享中断时所用。现在继续迭代深入 request_threaded_irq()内部是如何实现的。

1049int request_threaded_irq(unsigned int irq, irq_handler_t handler, 1050 irq_handler_t thread_fn, unsigned long irqflags, 1051 const char *devname, void *dev_id)1052{ 1053 struct irqaction *action;1054 struct irq_desc *desc;1055 int retval;1056 1057 /* 1058 * Sanity-check: shared interrupts must pass in a real dev-ID, 1059 * otherwise we'll have trouble later trying to figure out 1060 * which interrupt is which(messes up the interrupt freeing 1061 * logic etc).1062 */ 1063 if((irqflags & IRQF_SHARED)&&!dev_id)1064 return-EINVAL;1065 1066 desc = irq_to_desc(irq);1067 if(!desc)1068 return-EINVAL;1069 1070 if(desc->status & IRQ_NOREQUEST)1071 return-EINVAL;1072 1073 if(!handler){ 1074 if(!thread_fn)1075 return-EINVAL;1076 handler = irq_default_primary_handler;1077 } 1078 1079 action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);1080 if(!action)1081 return-ENOMEM;1082 1083 action->handler = handler;1084 action->thread_fn = thread_fn;1085 action->flags = irqflags;1086 action->name = devname;1087 action->dev_id = dev_id;1088 1089 chip_bus_lock(irq, desc);1090 retval = __setup_irq(irq, desc, action);1091 chip_bus_sync_unlock(irq, desc);1092 1093 if(retval)1094 kfree(action);1095 1096#ifdef CONFIG_DEBUG_SHIRQ 1097 if(!retval &&(irqflags & IRQF_SHARED)){ 1098 /* 1099 * It's a shared IRQ--the driver ought to be prepared for it 1100 * to happen immediately, so let's make sure....1101 * We disable the irq to make sure that a 'real' IRQ doesn't 1102 * run in parallel with our fake.1103 */ 1104 unsigned long flags;1105 1106 disable_irq(irq);1107 local_irq_save(flags);1108 1109 handler(irq, dev_id);1110 1111 local_irq_restore(flags);1112 enable_irq(irq);1113 } 1114#endif 1115 return retval;1116} 1049int request_threaded_irq(unsigned int irq, irq_handler_t handler, 1050 irq_handler_t thread_fn, unsigned long irqflags, 1051 const char *devname, void *dev_id)1052{ 1053 struct irqaction *action;1054 struct irq_desc *desc;1055 int retval;1056 1057 /* 1058 * Sanity-check: shared interrupts must pass in a real dev-ID, 1059 * otherwise we'll have trouble later trying to figure out 1060 * which interrupt is which(messes up the interrupt freeing 1061 * logic etc).1062 */ 1063 if((irqflags & IRQF_SHARED)&&!dev_id)1064 return-EINVAL;1065 1066 desc = irq_to_desc(irq);1067 if(!desc)1068 return-EINVAL;1069 1070 if(desc->status & IRQ_NOREQUEST)1071 return-EINVAL;1072 1073 if(!handler){ 1074 if(!thread_fn)1075 return-EINVAL;1076 handler = irq_default_primary_handler;1077 } 1078 1079 action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);1080 if(!action)1081 return-ENOMEM;1082 1083 action->handler = handler;1084 action->thread_fn = thread_fn;1085 action->flags = irqflags;1086 action->name = devname;1087 action->dev_id = dev_id;1088 1089 chip_bus_lock(irq, desc);1090 retval = __setup_irq(irq, desc, action);1091 chip_bus_sync_unlock(irq, desc);1092 1093 if(retval)1094 kfree(action);1095 1096#ifdef CONFIG_DEBUG_SHIRQ 1097 if(!retval &&(irqflags & IRQF_SHARED)){ 1098 /* 1099 * It's a shared IRQ--the driver ought to be prepared for it 1100 * to happen immediately, so let's make sure....1101 * We disable the irq to make sure that a 'real' IRQ doesn't 1102 * run in parallel with our fake.1103 */ 1104 unsigned long flags;1105 1106 disable_irq(irq);1107 local_irq_save(flags);1108 1109 handler(irq, dev_id);1110 1111 local_irq_restore(flags);1112 enable_irq(irq);1113 } 1114#endif 1115 return retval;1116}

程序的第一行和第二行分别定义了:

(1)struct irqaction *action;

(2)2struct irq_desc *desc;

两个指针action和desc,它们分别指向了结构体irqaction和 irq_desc。

(3)if((irqflags & IRQF_SHARED)&&!dev_id)return-EINVAL;

作用是:判断中断标志位,如果是共享中断的话就必须要有一个唯一的dev_id,否则返回一个错误。

(4)desc = irq_to_desc(irq);

irq_to_desc(irq):根据中断号irq在 irq_desc[NR_IRQS]数组中 返回一个具体的irq_desc。即根据irq找到它的中断处理程序。

(5)if(!desc)

return-EINVAL;

当返回一个空值时返回一个错误。说明申请中断号失败。

(6)if(desc->status & IRQ_NOREQUEST)return-EINVAL;

判断中断线的状态,若为IRQ_NOREQUEST时(IRQ_NOREQUEST表示 IRQ 不能被申请)

(7)if(!handler){ if(!thread_fn)return-EINVAL;handler = irq_default_primary_handler;}

判断中断服务例程是否为空,如果handler为空,则判断线程中断服务例程,若线程中断服务例程也为空,则返回一个错误值。否则中断服务例程指向: rq_default_primary_handler。

(8)

1079 action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);1080 if(!action)1081 return-ENOMEM;1082 1083 action->handler = handler;1084 action->thread_fn = thread_fn;1085 action->flags = irqflags;1086 action->name = devname;1087 action->dev_id = dev_id;

从1079~1087:根据requst_irq()函数中传递的参数生成一个irqaction.1097 if(!retval &&(irqflags & IRQF_SHARED)){ 1098 /* 1099 * It's a shared IRQ--the driver ought to be prepared for it 1100 * to happen immediately, so let's make sure....1101 * We disable the irq to make sure that a 'real' IRQ doesn't 1102 * run in parallel with our fake.1103 */ 1104 unsigned long flags;1105 1106 disable_irq(irq);1107 local_irq_save(flags);1108 1109 handler(irq, dev_id);1110 1111 local_irq_restore(flags);1112 enable_irq(irq);1113 }

1097~1113:如果为共享中断的话,在执行中断服务例程之前,要先把这条中断线上的中断屏蔽,让后在执行,执行完之后打开中断。

6.有注册中断服务函数,那必然有相应的释放中断函数。

可以调用void free_irq(unsigned int irq, void *dev_id)来释放我们申请的中断线。

函数形参:

1>unsigned int riq:表示申请的中断号与request_irq()函数中的第一个形参对应。

2>void *dev_id:与request_irq()函数中的最后一个形参含义和用法相同,在此不再说明。

函数功能:

如果指定的中断线不是共享的,那么,该函数删除处理程序的同时将禁用这条中断线。如果中断线是共享的,则仅删除dev_id所对应的处理程序,而这条中断线本省只有在删除了最后一个处理程序时才会被禁止。

切记:This function must not be called from interrupt context

freee_irq()函数不能在中断上下文中被调用。

3>深入分析下free_irq()函数内部是如何实现的

993void free_irq(unsigned int irq, void *dev_id)994{ 995 struct irq_desc *desc = irq_to_desc(irq);996 997 if(!desc)998 return;999 1000 chip_bus_lock(irq, desc);1001 kfree(__free_irq(irq, dev_id));1002 chip_bus_sync_unlock(irq, desc);1003} 993void free_irq(unsigned int irq, void *dev_id)994{ 995 struct irq_desc *desc = irq_to_desc(irq);996 997 if(!desc)998 return;999 1000 chip_bus_lock(irq, desc);1001 kfree(__free_irq(irq, dev_id));1002 chip_bus_sync_unlock(irq, desc);1003} 可以看到free_irq()函数了封装了_free_irq(irq,dev_id)函数。free_irq()调用_free_irq()把每一个具体的中断服务例程()释放。

本篇文章来源于 Linux公社网站(原文链接:

第五篇:中华文明未曾中断

中华文化未曾中断的原因探析

世界四大文明古国----巴比伦、埃及、印度和中国,各自都有悠久的历史和文化。但是,古埃及文化、巴比伦文化、印度的哈拉巴文化、古希腊文化毁灭殆尽,唯有崛起于东亚大陆黄河流域的中华文化,在坎坷跌宕中延绵发展数千年,经历改朝换代,分分合合,却始终未曾中断,成为世界史上“连续性文化”的典范。那么,为什么中华文化在几千年沧海桑田的变化中,不仅未曾中断,而且不断发展、丰富,形成了博大精深的独特文化体系,被世人称为“神秘的东方文化”呢?

第一,“敬天、法祖”的原始信仰。从地理环境看,大中华处于半封闭的大陆性地域之中:一面临海,三面是高山险阻,由此造成了华夏人与外部世界相对隔绝的状态,自给自足的小农经济也是在这个条件下形成的。人们不求对外的开拓发展,而只追求日出而作、日落而息的稳定的生活方式,以及讲究个人的自我完善的道德生活。从社会性质看,古代华夏是宗法制的农业社会,以家庭为单位,逐步向外辐射,形成家族、宗族为纽带的社会网络。这个网络是以亲情编织起来的,道德伦理就成为这个社会上每个人首先必须遵守的,也是自觉遵守的、高于一切的标准,从而形成华夏人注重血缘关系的社会心理。

正是由于这种半封闭的大陆性地域、农业经济格局、宗法与专制的社会组织结构相互影响和制约,构成了华夏族社会独特的、稳定的生存系统,与此相适应,华夏文化的形成与发展显示了鲜明的伦理型特色。它是一种具有强烈的重德求善的伦理价值取向的文化,正是这种独特的地理环境和社会性质造成了独具一格原始信仰—— “敬天法祖”。而这种“敬天法祖”的原始信仰在六千年的历史长河中衍生出以下观念:

其一、宗法观念。中华民族自从开始在黄河、长江流域繁衍生息之日起,就产生了自己的信仰。这种信仰以部落神、氏族英雄人物为崇拜对象,相传燧人发明用火,伏羲发明家畜驯化,炎帝、神农发明种植、医药,黄帝是发明舟车、宫室、衣服等器物制造的神,还创制了文字。他们是人,也是神,中国古代民族信仰,往往是氏族领袖死后被尊为神,受到本部族的祀奉。

在古代祖先祭祀与天帝信奉相伴相随,纠结在一起。随着部落组织形式的日趋完备,上帝的轮廓、形象逐渐形成,也日趋完整。祭祖先,敬天神,二者紧密纠结胶固,凝为一体,构成中华民族传统的宗祖观念。

宗祖观念的核心是“孝”,它是从血缘而产生的“亲亲”之情,并且通过宗祖神的崇拜和祈求保佑家族繁荣而表达出来,以此维护家族内部的团结。

家庭或家族成员在经济上相互依赖,父母有抚养子女的义务,并有要求子女赡养的权利,子女有赡养父母的义务。作为家长的父亲,享有绝对的权威,有权支配子女,子女对其有尊敬和服从的义务。《尚书.酒诰》云:“肇率牛车,远服贾,用孝养厥父母。”《诗.小雅》亦云:“父兮生我,母兮鞠我,拊我畜我,长我育我,顾我复我,出入腹我,欲报之德,昊天罔报。”“孝”这一道德观念,主要是用来维系宗法制度的,周代奉行嫡长子继承制,并在此基础上确立了“大宗”、“小宗”的宗法制。由此看来,“孝”就不仅限于家庭伦理范畴,子女赡养父母的义务已扩大到“小宗”对“大宗”的义务,并在政治上延伸为卿大夫对诸侯、诸侯对天子的义务。血缘上“追孝”、“尊祖”观念成为维系统治阶级内部的纽带。于是,由家族到国家达到了伦理与政治的统一。之后,孔子又在《孝经》中提出“不孝有三,无后为大。”这就把人放在了一个立体坐标中,一个人不仅要对当代家族的人负责,而且要上对得起列祖列宗,下对得起子孙后代。在老百姓心里,“忘本”、“没良心”、“败家子”、“数祖忘典”是最大的耻辱,而“光宗耀祖”、“德高望重”、“封妻荫子”、“流芳百世”又成为有志者的毕生追求,正是这种宗法观念对中华民族的文化起到了非常深远的影响。

其二、大一统的国家观念。在秦汉以后,“敬天法祖”的原始信仰具体化为“忠孝节义”、“三纲五常”。它使“敬天法祖”的原始信仰内容更趋完善化,它是宗教信仰,又是政治思想,更能适应大一统国家的生存要求。

数千年来,中华民族遭受到内忧外患,政权经过多次更迭,社会经过无数动荡,民族之间以融合为基调,也有过暂时的战争。总之,秦汉以后的中国,人民已习惯于在中央高度统一的政权下生活,因为大一统国家与国与民都具有重大利益:

(1)、大一统国家可以给人民带来实际利益。比如说,国家统一,老百姓可以不见兵戈,安居乐业地过日子;国家统一,可以借助强大的国力抵御各种自然灾害,调剂各地岁收丰歉,从而避免人民流离失所。

(2)、大一统国家可以充分发挥大国的综合国力办成大事。古代中国是个自然经济结构的小农经济之国,一家一户为生产单位,生产的产品除了供全家消费,所余无几。正是借助统一大国的高度集中,把分散、零星的少量财富集中起来,聚沙成塔,集腋成裘,集中全国人力、物力进行大规模的物质建设和文化建设,如修长城、开运河、整治大河河道,进行重大项目的文化建设,修纂大的文化典籍,如《永乐大典》、《四库全书》等。战时还可以调动全国人力抵御外来侵略势力。

(3)、大一统国家吸引力强,便于光大中华文明。第二周期秦汉帝国把大中华文明光大于西域,乃至中亚、西亚;第三周期的隋唐帝国把大中华文明光大于朝鲜、日本,乃至东南亚;第四周期元明清帝国把大中华文明光大于欧亚大陆,乃至非洲。

(4)、大一统国家影响力大,即便分裂时期大中华文化仍占主导地位。第一周期春秋战国时期,东周和东方六国都是华夏文化,逼迫西戎秦国首先把自己“华”化;第二周期三国两晋南北朝时期,尽管出现了许多政权,华夏文化始终保持占主导地位的态势。魏、蜀、吴、两晋、南朝都是华夏文化,北方16国,更是以炎黄子孙的身份自居,不失时机地进行汉化改革;第三周期宋代出了程朱理学,辽、夏、金、元无不争夺汉族儒家名士,接受道教;第四周期清朝相对于元、明仍是分裂时期大中华文明圈内的一个大国,尽管其曾推行“剃头令”,搞“圈地运动”,但是,之后它也极力奉行程朱理学,搞“华、夷之辩”,以证明自己是正宗的大中华文明。

中华民族接受、支持、维护这个大一统的国家制度,从诸子百家到佛、道、儒三教分别站在自己的宗教立场论证其合理性。从“三纲”、“五常”的言行中体现天理,宣扬忠孝是出自人的本性,不忠、不孝是违背人的天性,不但不能成佛、成仙、成圣贤,甚至也不足以为人。从孝敬父母作起,推及到孝忠祖上、祖先、祖国,形成中华民族的价值观:以尊祖、爱国、报恩、报国为荣,以窃国、卖国、篡国为耻。在老百姓心里,最臭的莫过于“汉奸”、“卖国贼”,可以说比骂祖宗八代还厉害。这类人不光个人被判了“死刑”,就连子孙后代也抬不起头来。

就这样,大一统观念促进大一统国家的形成,大一统国家又进一步光大了大中华文明,形成滚雪球式的良性运转,使大中华文明不仅未曾中断,而且不断发展、丰富,形成了博大精深的独特文化体系。

第二,保皇的是儒家,造反的也是儒家。在原始社会和奴隶制社会,敬天法祖的原始信仰,与当时中央政权的统治不太集中、中央统摄力还不够强大的政治形势相适应。秦汉以后,封建王朝势力强大了,上帝的统摄范围也扩大了,不但山川、日月,连人们的内心活动、意念善恶也要受宗教神学的管束。由皇帝直接管理天下的郡县,参与管理的有丞相、三公。但皇帝经常受到诸侯、后党、权臣的干扰,甚至发生宫廷政变,皇权遭到篡夺。为了加强中央集权,巩固社会秩序,汉朝以后,加强了儒学的教化作用。特别是隋唐两代,以科举取士,官方用考试制度强力推行儒教思想,凡是走这条路的士人都要系统地接受儒教思想培训,这对儒教的普及起了有力的作用。宋朝以后,儒教以教化力量巩固了中央集权,使它更趋稳定,故有权臣而没有篡臣。曹操在唐以前有能臣的形象,宋以后,曹操成为奸臣;唐以前,扬雄在思想界有较好的声望,宋以后,由于扬雄做过王莽的官,声望下降。

中国的儒教有一个显著的特点,即高度的政教合一,政教不分,政教一体,皇帝兼任教皇,或称教皇兼皇帝。神权、政权融为一体,儒教的教义得以以政府政令的方式下达。朝廷的“圣谕广训”是圣旨,等同于教皇的手谕。中世纪欧洲的国王即位,要教皇加冕,才算取得上帝的认可。中国皇帝即位,只要自己向天下发布诏书就行了。诏书必以“奉天承运,皇帝诏曰”开始,皇帝的诏书同时具有教皇敕令的权威。

儒教是中华民族特有的准宗教,凡是生活在中国这块古老土地上的各民族,包括各少数民族,如北方的辽、金、元、西夏及清,历代王朝都以儒教为国教,尊孔子为教主。儒、佛、道三教同为古代传统宗教。唯有儒教利用政教结合的优势得以成为国教,儒教的神权与皇权融为一体,不可分割。然而,一旦皇权制度被废除,儒教也随着皇权制度一同凋谢。

历史证明,行政命令打不倒信仰,但政权是可以更迭的,儒教与皇权融为一体,所以才随着皇权的废除而暂时销声匿迹,这便出现了另一种现象:保皇的是儒家,造反的也是儒家。孔子是思想家、教育家,但不能算政治家。儒学被后人宗教化后,既是学术,又是准宗教。它不仅能为统治阶级服务,也能为被统治阶级反抗剥削压迫提供思想武器。

均平原则构成中国古代经济改革和农民起义的指导思想。均平原则是针对财富占有行为的一种分配理论,孔子对此有过经典阐述:“丘也闻有国有家者,不患寡而患不均,不患贫而患不安。盖均无贫,和无寡,安无倾。”中国古代平均主义盖源于此。其实孔子的均平思想是对古代社会大同理想的描摹,也是体现其本人确立的“仁”学风格。“仁”是一种以普遍情感为基调的理论原则,它在分配行为上必然体现出和谐温馨,而不是巧取豪夺、毫不利人、专门利已。但孔子讲的并非绝对平均,他将“仁”、“礼”相互贯通,将平均原则寄于“礼运”之中,礼的实质是区分上下尊卑等级秩序,在分配行为上应该体现不同等级对财富的不同占有,超越或低于起码的标准,那也是不允许的,是对礼制的践踏。因此分配行为应该是依礼而行,均衡有序,使贫富、贵贱之间差距不至于无限扩大。荀子也指出“制礼仪以分之”的目的,就在于“皆使人载其事而各得其宜,然后使壳禄多少厚簿之称。使夫群居合一之道也。”主张“以礼分施,均遍而不偏”,“非礼不进,非义不受”。因此均平思想成为民族意识和分配标准,成为历次改革和农民起义的重要目标和理论武器。从北魏孝文帝的“均田制”,王安石提的“方田均税法”,张居正的“一条鞭法”都是以均平为指导思想提出来的。

农民起义、骚动、**更是如此,“均平”始终是农民起义军最感亲切、最得人心、最有号召力的战斗旗帜。绿林、赤眉起义是因为“力作所得,不足以给赋税。”黄巾军的原发组织“太平道”宣称“人无贵贱,皆天所生。”隋末农民起义首先在山东发难,是由于山东地主是土地兼并及其严重的“狭乡”地区。唐未农民起义军第一次打出了“均平”的旗帜,王仙芝自称“天补平均大将军”。南唐诸佑起义提出了“使富者贫,贫者富”的口号,宋代王小波、李顺起义明确提出“均贫富”。明末李自成提出“均田免粮”的纲领。

儒家不仅为造反大军提供行动纲领和鲜明的旗帜,还为造反大军提供了领袖人物和骨干力量。秦末农民起义的队伍中,范增、张良、萧何、陈平、陆贾、郦食其、曹参皆饱学之士。

《明史•儒林传序》说:“明太祖起布衣,定天下。当干戈抢攘之时,所至征召耆儒,讲论道德,修明治术,兴起教化,焕乎成一代之宏规。虽天亶英姿,而诸儒之功不为无助也。”意思是朱元璋虽然是个马上皇帝,但是在他的高级幕僚中诸儒占主要成分,在他兴兵造反、夺取天下的过程中诸儒功不可没。

朱元璋一开始就注重网罗儒者文士。早在渡江前,他即已征用冯国用及其弟国胜、李善长等人,冯氏兄弟“俱喜读书,通兵法,元末结寨自保”(《明史》卷129《冯胜传》)。朱元璋进军滁阳,途经妙山时,冯氏兄弟“着儒服”来见,朱元璋谓:“若书生耶?试为我计安出?”国用曰:“建康,龙蟠虎踞,帝王都会,自古记之。幸而近我,其帅懦弱不任兵,宜急击下其城,踞以号召四方。事仿仁义,勿贪子女玉帛若群竖子者,天下不难定也”(焦竑编:《国朝献征录》卷六王世贞《宋国公冯胜传》)。朱元璋遂令其为幕府参谋,计议大事。不久,定远人李善长也到军营求见。他“少读书,有智计,习法家言,策事多中”(《明史》卷127《李善长传》)。初谒朱元璋,即曰:“秦乱,汉高起布衣,豁达大度,知人善任,五载成帝业。今元纲既紊,天下土崩瓦解。公,濠产,距沛不远,山川王气,公当受之。法其所为,天下不足定也”(同上),殷殷期其成为当今的汉高祖刘邦。朱元璋对他甚为信任,留在幕府掌书记。

渡江后,朱元璋更是大力罗致人才,“所克城池,得元朝官吏及儒士尽用之”(刘辰:《国初事迹》)。至正十一年(1355),兵克太平,儒士陶安、李习、潘庭坚、梁贞等出城迎接。陶安,博涉经史,尤深于《易》,与朱元璋语,甚合其意,遂留参幕府,拜左司员外郎,从克金陵,升左司郎中;李习,自幼老成持重,治《尚书》,又旁通群经,攻性理之学,被朱元璋用为太平府知府;潘庭坚,元末用荐为富阳县学教谕,朱元璋任之为太平府儒学教授,次年取金陵后改为中书博士;梁贞,元至正中为国子监生,后由国子伴读授太平路儒学教授,见朱元璋时,所言辄援《诗》、《书》,被命为江南行省都事。至正十六年(1356),朱元璋率军取金陵,得儒士夏煜、孙炎、杨宪等十余人,各授官职。又因秦元荐而以书聘陈遇。陈遇,博通经史,尤邃于先天之学,元末为江东明道书院山长。朱元璋称其“学贯三史六经,博览兵书百技,才兼文武,实我良辅”(《国朝献征录》卷116陈镐《陈静诚先生遇传》)。他与朱元璋相见后,希望其“以不嗜杀人,薄敛任贤,复先王礼乐为首务”(《明史》卷135《陈遇传》),被命筹帷幄,诸计划多秘不传。至正十八年(1358),朱元璋下徽州,召儒士唐仲实,问:“汉高帝、光武、唐太祖太宗、元世祖一平天下,其道何由?”对曰:“此数君者,皆以不嗜杀人,故能定天下于一。今公英明神武,驱除祸乱,未尝妄杀。然以今日观之,民虽得归而未遂生息”,元璋深以为然(《明通鉴》“前编”卷一)。又素闻儒士朱升之名,遂“潜就访之。升因进三策曰:‘高筑墙,广积粮,缓称王。’”朱元璋大悦,命预帷幄密议,“大抵礼乐征伐之议,赞画居多”(《朱枫林集》卷九《学士朱升传》)。

在建置百官的同时,又遣起居注吴林、魏观待访求遗贤于四方,以期使更多的儒者文士聚集在自己周围。这样便逐渐形成了一个以刘基、宋濂等出自浙东的儒家学者为核心的幕僚集团,这对朱元璋的思想及他的帝业之成功均有重大影响。

近代更是如此,洪秀全、石达开、康有为、梁启超、孙中山、陈独秀、章太炎、毛泽东本身就是儒家,而且是大儒、鸿儒、通儒。毛泽东曾经崇拜过孔子、陈独秀。他的许多政略出自《论语》,其革命理想也是孔子说的大同世界。

治世治国安民靠儒家,乱时打天下也靠儒家,也就是说在中国历史上,无论治乱兴亡,哪一个阶段都离不开儒家,这本身就是文明的继承。换句话说,在中国只要有儒家存在中华文明就不会中断,而中国的文人中,百分之九十是儒家,中华文明怎么办会中断呢?

第三,道家有“兴灭继绝”的功能。道家文化作为中华文明的根基,具有旺盛的再生能力。鲁迅先生(1881—1936)曾经断言“中国根柢全在道教”,李约瑟博士(1900—1995年)也敏锐地指出:“中国如果没有道家思想,就会像是一棵某些深根已经烂掉了的大树”。道学文化中既蕴藏着死而复生的活力,又具有包罗万象、海纳百川的品格。为什么中国文化在古代能接纳印度佛教,在近代又能接纳西方的基督教文明,这显然不是“严夷夏之防”的儒家文化的功能,而是靠道家善于融汇异质文化的博大包容的特性。在中国历史上,历代统治者也都以儒守成,以道达变,人们深知道家智慧有如“水善利万物而不争”的宽容气度,以及能生能化,善于应变的长处。

“反者,道之动。”说明道家的核心是革命的哲学。在中国历史上,凡是大的社会变革,总是由道家首先发起对旧思想、旧习惯、旧制度、旧体制的批判开路。从先秦的老子、庄子、列子,到近代的魏源、鲁迅都是旧社会的批判者,是革命的先行和旗手。

道学的策略思想是以曲求伸、以弱胜强、以柔克刚,在士人被腐化,思想被扭曲,人民失去信仰时,道家以开放的思想体系和儒家自我封闭体系有着互补作用。每逢儒学走向唯心主义,成为僵化的“官文化”时,道家便对儒学进行补救。统治阶级既无创业的历史使命和事业压力,又抛弃了儒学德治思想的约束,逐渐成为“无道”。必然形成信仰危机。儒学道统衰弱,礼崩乐坏。而儒家刚性太强,“天不变,道亦不变,”、“士可杀而不可辱。”在这种情况下,道家发挥自己的优势,“穷则变,变则通,通则久。”从而起到对中华民族兴灭继绝的作用。(见第八章第二节)

“无”和“反”是《易经》所说的“穷则变,变则通,通则久”和《道德经》所谓“大曰逝,逝曰远,远曰反”的两种不同表现形式。无中生有是创新,反其道而行之是改革。有了改革和创新就可以达到“兴灭继绝”了。道学主导的历史阶段是“国乱”(久乱)一直延续到强治周期段的前期。“国乱”(久乱)周期段,国破了,(皇)家散了——诸侯坐大,法、儒两家的招数都使绝了,不灵验了,因此导致信仰危机,出了危机怎么办?只有道学出来救驾。但救驾的方式不是助一臂之力,而是挂倒档,开倒车,返本开新,另辟蹊径,重开新路。

第一周期,当神学出现了信仰危机之后,圣哲把人、神、道德、天文和巫、卜相结合出了《易经》,这便是道学的根基。

第二周期,在“礼崩乐坏”的春秋时代,孔夫子发出“兴灭国,继绝世,举逸民”的呼喊。然而,他并未做到,真正做到的是道家。道家在批判神学、天帝、圣贤的同时,以法家的面目出现,运用“法”、“术”、“势”,推出一系列改革方案、政策和措施,最终实用武力完成统一大业。故司马迁在《史记》中特意将老子和韩非子写在一起。

第三周期,东汉末年经学地位下降,道家的何宴、王弼将道学和儒学相揉合,创立了“玄学”。

第四周期,南宋时期,儒学危机时,朱熹融合儒、道、佛创立了理学。可以说是道家一次又一次地维护了中国的“道统”。

第五周期,从启蒙运动、洋务运动、太平天国异教运动、戊戌变法、新文化运动、共产主义运动,到文化大革命运动,儒学连续受到冲击,在这信仰危机、民族危亡的日子里,是道学在批判儒学的同时返本开新,敞开思想,对世界开放,实行“拿来主义”。实证主义进来了,马克思列宁主义也进来了,新儒学复活了,古老的中国才又一次焕发生机。

道家的一个重要信条是“不为王者师,便为万世师”。在政局混乱的时期,一些有高深道学的人转而为师,如鬼谷子、文中子即是。他们是诸子百家中一流的、非常规的教育家。他们用改朝换代的帝王之术授徒课业,培养一批因缘时会、出入军机的人才,使之逐鹿中原,以求一逞。隋末天下鼎沸,文中子王通先生教出了魏征、李密、徐懋公等几个知兵领军的干才,他们都是扭转乾坤的命世之才。鬼谷子、文中子通过自己的学子达到了对国家、民族“兴灭继绝”的目的。

中华民族文化周期性的更新再造功能不是别的,就是“道”。因为它是开放型的,且具备“体”的特质,有隐性世界的力量,这也是中华文明未出现断层的一个内在原因。如自然界,月季花枝繁叶茂,月月开花,可是花农每年冬季都平一次茬。翌年生长出来的新枝条粗壮鲜嫩,开的花比上年更大、更鲜艳。

第四,具有强大生命力的原始民主制。公元前7——2世纪,为什么经济、文化相当落后的西戎小国——秦能打败政治、经济、文化相当先进的东方六国呢?13世纪,为什么经济、文化相当落后的仅有150万人口的蒙古能打平欧亚大陆,建立四大可汗国呢?为什么16世纪经济、文化相当落后仅有几十万人口的女真族能打败6000多万人口的大明王朝呢?研究发现:根本原因在于原始民主制胜过封建专制、独裁政治。而这种原始民主制与之后的专制、独裁在中华大地上长期并存,经六千年之久,历三个大周天,九个周期。每当中原地区的政权走向专制、独裁,搞得民不聊生时,底层民众或边疆的部族就祭起原始民主制的法宝,组织起一支又一支的革命大军,摧毁专制、独裁的腐败政权,改朝换代,使华夏文化走上一个新的台阶。

原始民主政治制度是原始社会普遍实行的制度。我国在夏以前实行的“禅让”制度实际就是原始民主制。原始民主制始建于父系社会,是在家族议事会的基础上形成的。最初的议事会由各父系的大家长(长老)组成,负责处理内部事务以及与其它氏族交往的事务。在母系社会民众大会观念淡薄之后,这些大家长(长老)逐渐形成氏族的贵族,是氏族酋长的辅佐兼保护人,对氏族的各种活动有参与权。

部落议事会由各氏族首领和家族族长组成。部落的重大事情,如战争、讲和、缔结盟约、推举部落首领等,都必须由部落议事会作出决定。部落议事会成员一律平等,采取民主的方式协商讨论,实行原始民主制。史载:“伏羲氏以龙纪,故龙师名官。”(《通典》卷19《职官一》)传说“黄帝置六相”,“尧有十六相”——“四岳”、“十二枚”,“官员六十名”。(同上)“少昊氏以鸟名官,风鸟为历正,玄鸟为司分,伯赵氏为司至,青鸟氏为司启,丹鸟氏为司闭,祝鸩氏为司徒,(且鸟)鸩氏为司马,(尸鸟)鸩氏为司空,爽鸩氏为司寇,(骨鸟)鸩氏为司事”。(《左传昭公十七年》)

原始民主是与之后的封建专制、特权相对的,要实现民主就势必反对特权。所谓特权是指超越任何制约、滥用国家权利的权利,必然遭到大多数人的强烈抗议,反对特权,就能取得多数人的拥护,产生极大的向心力、凝聚力和战斗力。

第一、二周期之交的春秋战国时期,东周和东方六国的封建领主专制制度已经走向穷途末路,在西南边陲的秦国,由于封建领主专制制度的基础薄弱,经过“商鞅变法”最先废除了封建领主专制制度,建立了封建地主制的生产关系。

秦原系颛顼之后,西周时是一个附庸小国,东周初年被封为诸侯国。长期活动在陕西和甘肃东部,与西戎部落杂居,非子为秦部落领袖,时因替周孝王养马有功,受封为附庸,由犬丘(今陕西兴平东南)迁至秦(今甘肃张家川东),始以秦为称号。公元前659—621年,秦穆公实行原始民主制,任用百里奚、蹇叔等,积极加强国势。插手中原国家的事务,谋求向东发展。但是晋国在晋文公的统治下迅速强大,阻碍了秦国东进的计划。尤其在崤之战中,秦军惨败。因此,秦穆公转而向西发展。先争取到西戎谋臣由余归降,然后用由余的计谋进攻戎地,短时期内兼并了十二个戎国。开拓了上千里的土地,取得了独霸西戎的地位。

秦穆公称霸西戎国。但终因僻处西方,经济文化落后,国力逊于中原华夏大国。秦孝公即位后,继续实行原始民主制,任用商鞅变法,大力招徕六国居士,迅速取得富国强兵的效果。一跃成为战国七雄中的强国,秦始皇奋六世之余烈,东并六国,建立秦帝国,结束了长达五百年的混战。

第三、四周期之交的夏、辽、金、元最初都是实行原始民主制凝聚本部各部落的力量。蒙古族的“库里勒台”就是实行原始民主制建立起来的,“库里勒台”是各部落首领举行的一种会议,它决定有关部落的重大事情,如战争、讲和、缔结盟约、推举部落首领等,都必须由部落议事会做出决定。后来演变成“宗王大会”。与会成员一律平等,采取民主的方式协商讨论,具有极大的凝聚力。一是人才选拔面宽。凡是各部落的首领及贝勒都是大汗的后选人,能够优中选优;二是即使选不上大汗,当摄政王同样可以发挥作用。多尔衮就是以摄政王的身份指挥八旗入关,消灭大明王朝的的。由于夏、辽、金、元实行原始民主制还涌现出一批女主,如西夏惠宗秉常母梁太后、辽太祖阿保机皇后述津氏、辽圣宗母承天皇太后萧绰、金熙宗皇后裴满氏、成吉思汗皇后孛尔台旭真、元文宗皇后弘吉刺氏等,临朝称制少则几年,多则十几年,其中承天皇太后萧绰“裁决国事”长达40年之久,在历史上产生了深远的影响。

综上所述,大中华文明未曾中断的根本原因有四:根深蒂固的“敬天法祖”的原始信仰衍生了宗法观念和大一统观念是思想基础;儒学是个双刃剑,坐天下治国安民是儒家的长项,打天下安邦定国也离不开儒家;道家是中国人的哲学,是中华文化的“体”,具有“返本开新”、“兴灭继绝”的功能,在吸收异质文化,推动大中华文化与时俱进中具有隐性世界的力量;原始民主制是“德文化”的根基,是改朝换代的原动力,是专制、独裁、腐败分子的克星。

下载关于51系列单片机中断嵌套[推荐阅读]word格式文档
下载关于51系列单片机中断嵌套[推荐阅读].doc
将本文档下载到自己电脑,方便修改和收藏,请勿使用迅雷等下载。
点此处下载文档

文档为doc格式


声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:645879355@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。

相关范文推荐

    VB的循环嵌套教案

    VB程序设计中循环嵌套的使用一、课题名称 VB程序设计中循环嵌套的使用 二、教学目标 1. 知识目标 了解循环结构程序设计思想,准确掌握“For -Next”循环结构的应用以及循环......

    有关51单片机中断的形式和C语言编程格式[精选5篇]

    有关51单片机中断的形式和C语言编程格式 void INT0interrupt 0 using 1 {.... ..... } interrupt 0 指明是外部中断0; interrupt 1 指明是定时器中断0; interrupt 2 指明是......

    厂用电中断演练总结报告

    高配倒闸演练总结 一、演练成果 (一)参加员工高度重视,认真组织开展 参加员工对本次事故应急演练,都认真参与、亲临实战,尤其是刚开始通知过程较为真实。 (二)演练目的明确,预案......

    Excel中IF函数的嵌套用法

    浅谈Excel中IF函数在成绩管理中的嵌套用法 易星摘要:本文以学生成绩录入为例,介绍Excel中If函数的简单使用、嵌套使用以及如何和其他函数组合使用,使用这种方法可使学生成绩处......

    复杂记叙文之嵌套式结构教师版

    江苏省泗洪中学高三语文组教案编写:费园园 投放时间: 复杂记叙文的“嵌套”式结构 【学习目标】 1.了解高考高分记叙文的特征。 2.通过分析例文学习复杂记叙文的基本构思方......

    论基本养老保险中断缴费

    浅析基本养老保险中断缴费现象 时间: 2011-10-08 万 斌 李 莉 一、中断缴费的基本情况 1.近几年江西省基本养老保险中断缴费的情况。随着市场经济结构调整和国有企业改制步......

    营业中断保险所需材料

    机损险项下营业中断保险所需材料 上海东大保险经纪有限责任公司: 关于河北建投集团的营业中断保险案件,请尽快提供以下材料。以便尽快处理相关赔案。 1. 索赔申请书 2. 报损......

    消防系统中断申请书(精选5篇)

    消防系统中断申请书 Fire Protection Impairment Application FormLocation地点: Site Impairment Coordinator消防系统中断负责人: The Following Impairment此项消防系统中......