第一篇:關(guān)于51系列單片機(jī)中斷嵌套
說最基本的,老的51單片機(jī)(80C51系列)有5個中斷源,2個優(yōu)先級,可以實現(xiàn)二級中斷服務(wù)嵌套?,F(xiàn)在很多擴(kuò)展的51單片機(jī)已經(jīng)有4個優(yōu)先級(或更多)和更多的中斷源了。
在說到中斷之前,我先來定義一下優(yōu)先級,明白了什么是優(yōu)先級,后面的闡述就容易明白了。實際上很多人都是混淆了優(yōu)先級的含義,所以才覺得糊里糊涂。
中斷的優(yōu)先級有兩個:查詢優(yōu)先級和執(zhí)行優(yōu)先級。
什么是查詢優(yōu)級呢?我們從datasheet或書上看到的默認(rèn)(IP寄存器不做設(shè)置,上電復(fù)位后為00H)的優(yōu)先級:
外部中斷0 > 定時/計數(shù)器0 > 外部中斷1 > 定時/計數(shù)器1 > 串行中斷 或 int0,timer0,int1,timer1,serial port 或 INT0、T0、INT1、T1、UART 或 PX0>PT0>PX1>PT1>PS>......其實都是查詢優(yōu)級。首先查詢優(yōu)先級是不可以更改和設(shè)置的。這是一個中斷優(yōu)先權(quán)排隊的問題。是指多個中斷源同時產(chǎn)生中斷信號時,中斷仲裁器選擇對哪個中斷源優(yōu)先處理的順序。而這與是否發(fā)生中斷服務(wù)程序的嵌套毫不相干。當(dāng)CPU查詢各個中斷標(biāo)志位的時候,會依照上述5個查詢優(yōu)先級順序依次查詢,當(dāng)數(shù)個中斷同時請求的時候,會優(yōu)先查詢到高優(yōu)查詢先級的中斷標(biāo)志位,但并不代表高查詢優(yōu)先級的中斷可以打斷已經(jīng)并且正在執(zhí)行的低查詢優(yōu)先級的中斷服務(wù)。
例如:當(dāng)計數(shù)器0中斷和外部中斷1(按查詢優(yōu)先級,計數(shù)器0中斷>外部中斷1)同時到達(dá)時,會進(jìn)入計時器0的中斷服務(wù)函數(shù);但是在外部中斷1的中斷服務(wù)函數(shù)正在服務(wù)的情況下,這時候任何中斷都是打斷不了它的,包括邏輯優(yōu)先級比它高的外部中斷0計數(shù)器0中斷。
而中斷的執(zhí)行優(yōu)先級就是你對IP寄存器的設(shè)置了。在2個優(yōu)先級的情況下,某位為1,則相應(yīng)的中斷源為高優(yōu)先級;為0,則為低優(yōu)先級。
關(guān)于中斷的優(yōu)先級有三條原則:
1、CPU同時接收到幾個中斷時,首先響應(yīng)優(yōu)先級最高的中斷請求;
2、正在進(jìn)行的中斷過程不能被新的同級或低行優(yōu)優(yōu)先級的中斷請求所中斷;
3、正在進(jìn)行的低行優(yōu)優(yōu)先級中斷服務(wù),能被高行優(yōu)優(yōu)先級中斷請求中斷;
若:同一執(zhí)行優(yōu)先級中的中斷申請不止一個時,則有一個中斷優(yōu)先權(quán)排隊問題。同一執(zhí)行優(yōu)先級的中斷優(yōu)先權(quán)排隊,由中斷系統(tǒng)硬件確定的自然優(yōu)先級形成,優(yōu)先權(quán)自高到低的順序即: 外部中斷0>定時/計數(shù)0>外部中斷1>定時/計數(shù)1>串行接口
例如:設(shè)置IP = 0x10,即設(shè)置串口中斷為最高優(yōu)先級,則串口中斷可以打斷任何其他的中斷服務(wù)函數(shù)實現(xiàn)嵌套,且只有串口中斷能打斷其他中斷的服務(wù)函數(shù)。若串口中斷沒有觸發(fā),則其他幾個中斷之間還是保持邏輯優(yōu)先級,相互之間無法嵌套。
關(guān)于中斷嵌套。可以這樣說,當(dāng)一個中斷正在執(zhí)行的時候,如果事先設(shè)置了中斷優(yōu)先級寄存器IP,那么當(dāng)一個更高優(yōu)先級的中斷到來的時候會發(fā)生中斷嵌套,如果沒有設(shè)置則不會發(fā)
生任何嵌套;如果有同一個優(yōu)先級的中斷觸發(fā),它并不是在“不斷的申請”,而是將它相應(yīng)的中斷標(biāo)志位置即IE寄存器的某位置位,當(dāng)CPU執(zhí)行完當(dāng)前中斷之后,按照查詢優(yōu)先級重新去查詢各個中斷標(biāo)志位,進(jìn)入相應(yīng)中斷。
要記住,沒有設(shè)置IP時,單片機(jī)會按照查詢優(yōu)先級(或都說邏輯優(yōu)先級)來排隊進(jìn)入服務(wù)。如果要想讓某個中斷優(yōu)先響應(yīng),則要設(shè)置IP,更改執(zhí)行優(yōu)先級(或者說物理優(yōu)先級)。要注意的是,當(dāng)設(shè)置了IP后,當(dāng)?shù)蛨?zhí)行優(yōu)先級中斷在運行時,如果有高執(zhí)行優(yōu)先級的中斷產(chǎn)生,則會嵌套調(diào)用進(jìn)入高執(zhí)行優(yōu)先級的中斷。如果你是用C語言寫的程序,并在中斷服務(wù)時 using 了寄存組,要注意,兩個不同執(zhí)行優(yōu)先級的中斷服務(wù)程序不要 using 同一組寄存器。
看兩個問題,如下: 在各個中斷都是低優(yōu)先級的時候,如果定時器0的溢出進(jìn)入中斷。在這個中斷處理的過程中,外部中斷0也被觸發(fā)了,那么是不是要發(fā)生中斷嵌套? 如果定時器0發(fā)生中斷的時候,進(jìn)入中斷處理程序,這個時候外部中斷1條件觸發(fā)條件滿足了。因為定時器0自然優(yōu)先級比外部中斷1高,那么定時器0的中斷處理程序繼續(xù)執(zhí)行。假設(shè)定時器中斷處理程序執(zhí)行的過程中,外部中斷1的觸發(fā)。條件消失了,那么等定時器0的中斷處理完后,程序還是會進(jìn)入外部中斷1處理程序嗎?
答案1:在IP事先設(shè)置了外部中斷0的優(yōu)先級的情況下,CUP會中止定時器0的中斷服務(wù),進(jìn)入外部中斷0服務(wù)程序,執(zhí)行完以后再回到定時器0中斷服務(wù)程序。否則不會。
答案2:肯定會進(jìn)入中斷的;外部中斷1的觸發(fā)條件滿足后會置位外部1的中斷標(biāo)志,即使后來外部中斷1的觸發(fā)條件消失了,也不會清除已置位的中斷標(biāo)志,所以等定時器0的中斷處理完后,程序判斷外部中斷的中斷標(biāo)志為1后依然會進(jìn)入外部中斷1處理程序的,只有在外部中斷1處理程序中執(zhí)行reti指令才會硬件清除外部中斷1的中斷標(biāo)志(這也正是為什么中斷返回使用reti指令而不可以用ret替換的原因)...
第二篇:51單片機(jī)中斷學(xué)習(xí)
51單片機(jī)中斷學(xué)習(xí)
一、中斷的概念
CPU在處理某一事件A時,發(fā)生了另一事件B請求CPU迅速去處理(中斷發(fā)生);CPU暫時中斷當(dāng)前的工作,轉(zhuǎn)去處理事件B(中斷響應(yīng)和中斷服務(wù));
待CPU將事件B處理完畢后,再回到原來事件A被中斷的地方繼續(xù)處理事件A(中斷返回),這一過程稱為中斷
二、中斷源
在51單片機(jī)中有5個中斷源
中斷號優(yōu)先級中斷源中斷入口地址
01(最高)外部中斷00003H12定時器0000BH
23外部中斷10013H
34定時器10018H
45串口總段0023H
三、中斷寄存器
單片機(jī)有10個寄存器主要與中斷程序的書寫控制有關(guān)
1.中斷允許控制寄存器IE
2.定時器控制寄存器TCON
3.串口控制寄存器SCON
4.中斷優(yōu)先控制寄存器IP
5.定時器工作方式控制寄存器TMOD
6.定時器初值賦予寄存器(TH0/TH1,TL0/TL1)T
第三篇:親子關(guān)系中斷[范文]
“親子關(guān)系中斷”與療愈
“親子關(guān)系中斷”。通常來說,0-7歲的孩子,尤其是0-3歲之間的孩子,最好和父母在一起,受到父母的照顧。如果要和父母分開的話,分開的時間也不要太長。因為0-3歲的孩子,神經(jīng)系統(tǒng)還沒有足夠的承受力,如果跟父母分離很長時間,會產(chǎn)生極度的恐懼,對孩子來講是一個很大的情緒創(chuàng)傷。孩子長大之后,他/她內(nèi)心的安全感,他/她與人連結(jié)的能力都會受到影響。
“鐵臉實驗”,把一群一兩歲的孩子放在一個游戲室里,讓這些孩子去玩,然后讓媽媽全部出去。孩子玩了一會,發(fā)現(xiàn)媽媽不見了,就開始哭,開始叫。實驗人員規(guī)定,這種情況下,不管孩子怎么哭怎么叫,媽媽都不要理他/她,媽媽都要拒絕他/她。這樣幾輪下來之后,突然有一刻,所有的孩子都不再哭了,都安靜下來了。這時候媽媽再上來逗孩子,孩子的表情都成了“鐵臉”,沒表情了,麻木了,不理媽媽了。
實驗到了這里,無法在進(jìn)行下去,因為媽媽們投訴得很厲害。由此也可以看到,當(dāng)小孩子被媽媽拒絕,被媽媽忽略,被媽媽不理會,離開媽媽的時候,遭到的創(chuàng)傷。
當(dāng)孩子比較小的時候,你可以上班,可以出差,但是請盡量多的與孩子待在一起。你每次回家,最好多擁抱他/她一會。孩子在父母的懷抱里,感覺是最安全的。父母,尤其是媽媽,既是創(chuàng)傷的開始,也是療愈的開始。
在孩子0-3歲這段時間,誰在照顧他/她,他/她就可能把這個人當(dāng)成自己的爸爸媽媽。所以養(yǎng)育孩子,最好父母自己帶;第二給自己的父母帶,也就是爺爺奶奶、姥姥姥爺帶,再其次是給自己的兄弟姐妹帶,比如叔叔姑姑;最次是給陌生人帶,比如讓阿姨帶,讓保姆帶,而且父母也不經(jīng)常去看孩子,這對孩子會是相當(dāng)大的心理創(chuàng)傷。
問:如果創(chuàng)傷已經(jīng)發(fā)生,怎樣去彌補?
答:剛才說了,有一種方式叫“強(qiáng)抱”,緊緊地去擁抱孩子,不管孩子愿不愿意,你都去擁抱他/她。例如七八歲的孩子,調(diào)皮搗蛋,父母去抱他/她,他/她往往會把父母推開。但是你耐心一點,多抱一會兒,比如一個小時,你會發(fā)現(xiàn)孩子會軟化下來,孩子其實很需要你。
問:如果早年有親子關(guān)系的創(chuàng)傷,父母已經(jīng)去世了,該怎么辦?
答:有個方法,找個老婆回來,先當(dāng)她是媽,然后再把她當(dāng)成伴侶,也有療愈效果。
第四篇:linux中斷總結(jié)
1.Linux中斷的注冊與釋放:
在
unsigned int irq:所要注冊的中斷號
irqreturn_t(*handler)(int, void *, struct pt_regs *):中斷服務(wù)程序的入口地址。unsigned long flags:與中斷管理有關(guān)的位掩碼選項,有三組值: 1.SA_INTERRUPT :快速中斷處理程序,當(dāng)使用它的是后處理器上所有的其他中斷都被禁用。2.SA_SHIRQ :該中斷是在設(shè)備之間可共享的
3.SA_SAMPLE_RANDOM :這個位表示產(chǎn)生的中斷能夠有貢獻(xiàn)給 /dev/random 和 /dev/urandom 使用的加密池.(此處不理解)const char *dev_name:設(shè)備描述,表示那一個設(shè)備在使用這個中斷。void *dev_id:用作共享中斷線的指針.它是一個獨特的標(biāo)識, 用在當(dāng)釋放中斷線時以及可能還被驅(qū)動用來指向它自己的私有數(shù)據(jù)區(qū)(來標(biāo)識哪個設(shè)備在中斷)。這個參數(shù)在真正的驅(qū)動程序中一般是指向設(shè)備數(shù)據(jù)結(jié)構(gòu)的指針.在調(diào)用中斷處理程序的時候它就會傳遞給中斷處理程序的void *dev_id。(這是我的理解)如果中斷沒有被共享, dev_id 可以設(shè)置為 NULL, 但是使用這個項指向設(shè)備結(jié)構(gòu)不管如何是個好主意.我們將在“實現(xiàn)一個處理”一節(jié)中看到 dev_id 的一個實際應(yīng)用。
中斷號的查看可以使用下面的命令:“cat /proc/interrupts”。
/proc/stat 記錄了幾個關(guān)于系統(tǒng)活動的低級統(tǒng)計量, 包括(但是不限于)自系統(tǒng)啟動以來收到的中斷數(shù).stat 的每一行以一個文本字串開始, 是該行的關(guān)鍵詞;intr 標(biāo)志是我們在找的.第一個數(shù)是所有中斷的總數(shù), 而其他每一個代表一個單個 IRQ 線, 從中斷 0 開始.所有的計數(shù)跨系統(tǒng)中所有處理器而匯總的.這個快照顯示, 中斷號 4 已使用 1 次, 盡管當(dāng)前沒有安裝處理.如果你在測試的驅(qū)動請求并釋放中斷在每個打開和關(guān)閉循環(huán), 你可能發(fā)現(xiàn) /proc/stat 比 /proc/interrupts 更加有用.以下是一個統(tǒng)計中斷時間間隔的中斷服務(wù)程序。
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;} 這個函數(shù)實現(xiàn)的只是對兩次發(fā)生中斷的時間間隔的統(tǒng)計,時間單位是毫秒
前言
在前面分析了中斷的基本原理后,就可以寫一個內(nèi)核中斷程序來體驗以下,也可以借此程序繼續(xù)深入來了解內(nèi)核中斷的執(zhí)行過程 一.內(nèi)核中斷程序 :
我們還是來看一看成程序:
在看程序之前,要熟悉如何進(jìn)行模塊編程,和了解module_pararm()的用法。如果不熟悉的話請大家看,module_param()的學(xué)習(xí)和Linux內(nèi)核模塊編程,在此不作解釋。1.程序interrupt.c /* 2 *file name :interrupt.c 3 *atuthor : john 4 */ 5 #include
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
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(程序的調(diào)試,加載和運行,在此不進(jìn)行說明)3.首先我們來分析下內(nèi)核加載模塊
在內(nèi)核加載模塊中最重要的的action就是注冊中斷處理程序。很明顯,這一動作是通過request_irq()函數(shù)來完成的。int request_irq(unsigned int irq, irq_handler_t handler,unsigned long flags, const char *devname, void *dev_id)A.先來分析形參:
第一個參數(shù)irq: 表示要分配的中斷號。對于一些設(shè)備(系統(tǒng)時鐘或鍵盤)它的值是預(yù)先固定的,而對于大多數(shù)設(shè)備來說,這個值是動態(tài)確定的。第二個參數(shù) handler: 表示要掛入到中斷請求對列中的中斷服務(wù)例程,這個中斷服務(wù)函數(shù)的原型是static irqreturn_t handler(int , void *);中斷處理程序的前綴為static,因為它從來不會被別的文件中的代碼直接調(diào)用。第三個參數(shù)flags:為標(biāo)志位。可以取IRQF_DISABLED、IRQF_SHARED和IRQF_SAMPLE_RANDOM之一。在本實例程序中取 IRQF_SHARED,該標(biāo)志表示多個中斷處理程序共享irq中斷線。一般某個中斷線上的中斷服務(wù)程序在執(zhí)行時會屏蔽請求該線的其他中斷,如果取 IRQF_DISABLED標(biāo)志,則在執(zhí)行該中斷服務(wù)程序時會屏蔽所有其他的中斷。取IRQF_SAMPLE_RANDOM則表示設(shè)備可以被看做是事件隨見的發(fā)生源。以下是官方解釋: /* * 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 第四個參數(shù)devname:是請求中斷的設(shè)備的名稱。當(dāng)你加載模塊成功后可以在/proc/interrupts中查看到具體設(shè)備的名稱,與此同時也可以看到這個設(shè)備對應(yīng)的中斷號以及請求次數(shù)。
第五個參數(shù)dev_id:為一個指針型變量。注意該參數(shù)為void型,也就是說通過強(qiáng)制轉(zhuǎn)換可以轉(zhuǎn)換為任意類型。dev_id主要用于共享中斷線,對每個注冊的中斷處理程序來說,(Dev_id must be globally unique.Normally the address of the device data structure is used as the cookie.)dev_id參數(shù)必須唯一(指向任一設(shè)備結(jié)構(gòu)的指針就可以滿足此要求,選擇設(shè)備結(jié)構(gòu)因為它是唯一的,而且中斷處理程序可能會用到它)如果無需共享中斷線,則將該參數(shù)賦值為NULL。B:函數(shù)返回值
requset_irq()函數(shù)成功執(zhí)行后返回0。如果返回非0值,就表示錯誤發(fā)生。此時,指定的中斷處理程序不會被注冊。這里面有幾個疑問: 為什么要注冊中斷函數(shù)
共享中斷線的概念,參數(shù)dev_id的作用是什么 看一個圖進(jìn)行說明:
1>由圖可知:有16個中斷線。要使用中斷線,就要進(jìn)行中斷線的 申請,也常把申請一條中斷線稱為申請一個中斷號,這就 與request_irq()函數(shù)中的第一個形參 irq 有關(guān)系。2>Linux有256個中斷向量,而外部中中斷向量只有16個(32~47)。由于硬件上的限制,很多外部設(shè)備不得不共享中斷線。
(例如:一些PC機(jī)所用的網(wǎng)卡和圖形卡可以把它們分配到一條中斷線上)讓每個中斷源獨自占用一條中斷線是不實現(xiàn)的。3>共享中斷線的話雖然解決了中斷資源的問題,但是,此時引出了另一個問題(任何事物都有其兩面性),此時僅僅用中斷描述符并不能提供中斷產(chǎn)生的所有信息。為了解決這個問題,內(nèi)核必須對中斷線給出近一步的描述,所以在Linux設(shè)計中,為每個中斷請求IRQ設(shè)置了一個專用隊列(中斷請求隊列)。
4>中斷服例程序和中斷處理程序的區(qū)別: a.中斷服務(wù)例程(interrupt service routine):
Linux中,15條中斷線對應(yīng)15個中斷處理程序,依次命名是IRQ0x00_interrupt(),IRQ0x01_interrupt().....IRQ0X1f_interrupt().中斷處理程序相當(dāng)于某個中斷向量的總處理程序。
eg:IRQ0X05_interupt()是5號中斷(向量為37)的總處理程序。b.中斷服務(wù)例程是針對一個具體設(shè)備的中斷。5>.注冊中斷服務(wù)例程: 在IDT表完成初始化時,每個中斷服務(wù)隊列還為空。此時即使打開中斷且某個外設(shè)的中斷真的發(fā)生了,也得不到實際的服務(wù)。因為CPU雖然通過中斷門進(jìn)入了某個中斷向量的總處理程序。但是,具體的中斷服務(wù)例程還沒有掛入中斷請求隊列。所以,在設(shè)備驅(qū)動程序的初始化階段,必須通過request_irq()函數(shù)將響應(yīng)的中斷服務(wù)例程掛入中斷請求隊列,也就是進(jìn)行注冊。
6>分析一下中斷服務(wù)程序,即request_irq()函數(shù)中第二個參數(shù)所對應(yīng)的函數(shù) static irqreturn_t myirq_handler(int irq,void *dev_id){ printk(“ISR is Workingn”);return IRQ_HANDLED;} 中斷服務(wù)例程的形參: a.int irq :中斷號。
b.void *dev_id :與request_irq()的參數(shù)dev_id一致,可以根據(jù)這個設(shè)備id號得到相應(yīng)設(shè)備的數(shù)據(jù)結(jié)構(gòu),進(jìn)而得到相應(yīng)設(shè)備的信息和相關(guān)數(shù)據(jù)。
c.返回值:中斷程序的返回值是一個特殊類型 rqreturn_t。但是中斷程序的返回值卻只有兩個值IRQ_NONE和IRQ_HANDLED。
IRQ_NONE:中斷程序接收到中斷信號后發(fā)現(xiàn)這并不是注冊時指定的中斷原發(fā)出的中斷信號。IRQ_HANDLED:接收到了準(zhǔn)確的中斷信號,并且作了相應(yīng)正確的處理。一般 中斷處理程序要做什么service,主要取決于產(chǎn)生的設(shè)備和該設(shè)備為什么要發(fā)送中斷。John哥說明:
1.當(dāng)一個給定的中斷處理程序正在執(zhí)行時,這條中斷線上的其它中斷都會被屏蔽。but,所有其他中斷線上的中斷都是打開的。因此這些不同中斷線上的其他中斷都能被處理。
2.request_irq()函數(shù)可能會睡眠,所以,不能在中斷上下文或其它不允許阻塞的代碼中調(diào)用該函數(shù)。
4.在深入分析request_irq()函數(shù)之前,先來看幾個重要的數(shù)據(jù)結(jié)構(gòu)。
A.irqaction的數(shù)據(jù)結(jié)構(gòu)(用irqaction結(jié)構(gòu)體來描述一個具體的中斷服務(wù)例程)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:指向具體的一個中斷服務(wù)例程。
2>flags:表示中斷標(biāo)志位,對應(yīng)于request_irq()函數(shù)中所傳遞的第三個參數(shù),可取IRQF_DISABLED、IRQF_SAMPLE_RANDOM和IRQF_SHARED其中之一。
3>name:請求中斷的設(shè)備名稱,對應(yīng)request_irq()函數(shù)中所傳遞的第四個參數(shù)
4>dev_id: 共享中斷時有用。對應(yīng)于request_irq()函數(shù)中所傳遞的第五個參數(shù),可取任意值,但必須唯一能夠代表發(fā)出中斷請求的設(shè)備,通常取描述該設(shè)備的結(jié)構(gòu)體。5>strct irqaction *next:指向irqaction描述符的下一個元素。用一條鏈表將共享同一條中斷線上的中斷服務(wù)例程鏈接起來。
6>irq:所申請的中斷號
7>dir:指向proc/irq/NN/name entry
8>thread_fn:指向具體的一個線程化的中斷。
9>thread:指向線程中斷的指針。
10>thread_flags:線程中斷的標(biāo)志。
B.irq_desc的數(shù)據(jù)結(jié)構(gòu)體 每個中斷向量都有它自己的irq_desc 描述符。即用irq_desc來描述中斷向量。所有的這些中斷描述符組織在一起就形成了irq_desc irq_desc[NR_IRQS]數(shù)組
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:表示這個描述符所對應(yīng)的中斷號。
2>handle_irq:指向該IRQ線的公共服務(wù)程序(即該IRQ所對應(yīng)的中斷處理程序。
3>chip:它是一個struct irq_chip類型的指針,是中斷控制器的描述符。在2.6以前的版本中它是hw_irq_controller。
4>handler_data:是handler_irq的參數(shù)。5>chip_data:是指向irq_chip的指針。6>atcion:一個struct irqaction類型的指針,它指向一個單鏈表。該鏈表是由該中斷線上所有中斷服務(wù)例程鏈接起來的。7>status:表示中斷線當(dāng)前的狀態(tài)。
8>depth:中斷線被激活時,值為0;當(dāng)值為正數(shù)時,表示被禁止的次數(shù)。9>irq_count:表示該中斷線上發(fā)生中斷的次數(shù)
10>irqs_unhandled:該IRQ線上未處理中斷發(fā)生的次數(shù) 11>name:申請中斷設(shè)備的名字。
C.struct irq_chip結(jié)構(gòu)體:
struct irq_chip是一個中斷控制器的描述符。Linux支持N種可編程中斷控制器PIC(中斷控制器),通常不同的體系結(jié)構(gòu)就有一套自己的中斷處理方式。內(nèi)核為了統(tǒng)一的處理中斷,提供了底層的中斷處理抽象接口,對于每個平臺都需要實現(xiàn)底層的接口函數(shù)。這樣對于上層的中斷通用處理程序就無需任何改動。
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:關(guān)閉中斷線; Enable:允許中斷; Disable:禁止中斷;
分析了struct irq_desc,struct irq_chip和irqaction的數(shù)據(jù)結(jié)構(gòu)之后我們來看看他們之間的關(guān)系。
現(xiàn)在深入分析request_irq()內(nèi)部是如何實現(xiàn)的。
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()函數(shù)里面有封裝了request_threaded_irq(irq, handler, NULL, flags, name, dev)函數(shù)。
先看一下官方的解釋
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()函數(shù)中的各個形參 1>:irq:表示申請的中斷號。2>:handler:表示中斷服務(wù)例程
3.> thread_fn:中斷線程化,此處傳遞的是NULL。NULL表示沒有中斷線程化。此參數(shù)是最新版本中才出現(xiàn)的。為什么要提出中斷線程化? 在 Linux 中,中斷具有最高的優(yōu)先級。不論在任何時刻,只要產(chǎn)生中斷事件,內(nèi)核將立即執(zhí)行相應(yīng)的中斷 處理程序,等到所有掛起的中斷和軟中斷處理完畢后才能執(zhí)行正常的任務(wù),因此有可能造成實時任務(wù)得不
到及時的處理。中斷線程化之后,中斷將作為內(nèi)核線程運行而且被賦予不同的實時優(yōu)先級,實時任務(wù)可以
有比中斷線程更高的優(yōu)先級。這樣,具有最高優(yōu)先級的實時任務(wù)就能得到優(yōu)先處理,即使在嚴(yán)重負(fù)載下仍
有實時性保證。but,并不是所有的中斷都可以被線程化,比如時鐘中斷,主要用來維護(hù)系統(tǒng)時間以及定時器 等,其中定時器是操作系統(tǒng)的脈搏,一旦被線程化,就有可能被掛起,這樣后果將不堪設(shè)想,所以不應(yīng)當(dāng) 被線程化。
4>.irqflags:表示中斷標(biāo)志位。
5>.devname:表示請求中斷的設(shè)備的名稱。
6>.dev_id: 對應(yīng)于request_irq()函數(shù)中所傳遞的第五個參數(shù),可取任意值,但必須唯一能夠代表發(fā)出中斷請求的設(shè)備,通常取描述該設(shè)備的結(jié)構(gòu)體。共享中斷時所用。現(xiàn)在繼續(xù)迭代深入 request_threaded_irq()內(nèi)部是如何實現(xiàn)的。
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,它們分別指向了結(jié)構(gòu)體irqaction和 irq_desc。
(3)if((irqflags & IRQF_SHARED)&&!dev_id)return-EINVAL;
作用是:判斷中斷標(biāo)志位,如果是共享中斷的話就必須要有一個唯一的dev_id,否則返回一個錯誤。
(4)desc = irq_to_desc(irq);
irq_to_desc(irq):根據(jù)中斷號irq在 irq_desc[NR_IRQS]數(shù)組中 返回一個具體的irq_desc。即根據(jù)irq找到它的中斷處理程序。
(5)if(!desc)
return-EINVAL;
當(dāng)返回一個空值時返回一個錯誤。說明申請中斷號失敗。
(6)if(desc->status & IRQ_NOREQUEST)return-EINVAL;
判斷中斷線的狀態(tài),若為IRQ_NOREQUEST時(IRQ_NOREQUEST表示 IRQ 不能被申請)
(7)if(!handler){ if(!thread_fn)return-EINVAL;handler = irq_default_primary_handler;}
判斷中斷服務(wù)例程是否為空,如果handler為空,則判斷線程中斷服務(wù)例程,若線程中斷服務(wù)例程也為空,則返回一個錯誤值。否則中斷服務(wù)例程指向: 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:根據(jù)requst_irq()函數(shù)中傳遞的參數(shù)生成一個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:如果為共享中斷的話,在執(zhí)行中斷服務(wù)例程之前,要先把這條中斷線上的中斷屏蔽,讓后在執(zhí)行,執(zhí)行完之后打開中斷。
6.有注冊中斷服務(wù)函數(shù),那必然有相應(yīng)的釋放中斷函數(shù)。
可以調(diào)用void free_irq(unsigned int irq, void *dev_id)來釋放我們申請的中斷線。
函數(shù)形參:
1>unsigned int riq:表示申請的中斷號與request_irq()函數(shù)中的第一個形參對應(yīng)。
2>void *dev_id:與request_irq()函數(shù)中的最后一個形參含義和用法相同,在此不再說明。
函數(shù)功能:
如果指定的中斷線不是共享的,那么,該函數(shù)刪除處理程序的同時將禁用這條中斷線。如果中斷線是共享的,則僅刪除dev_id所對應(yīng)的處理程序,而這條中斷線本省只有在刪除了最后一個處理程序時才會被禁止。
切記:This function must not be called from interrupt context
freee_irq()函數(shù)不能在中斷上下文中被調(diào)用。
3>深入分析下free_irq()函數(shù)內(nèi)部是如何實現(xiàn)的
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()函數(shù)了封裝了_free_irq(irq,dev_id)函數(shù)。free_irq()調(diào)用_free_irq()把每一個具體的中斷服務(wù)例程()釋放。
本篇文章來源于 Linux公社網(wǎng)站(原文鏈接:
第五篇:中華文明未曾中斷
中華文化未曾中斷的原因探析
世界四大文明古國----巴比倫、埃及、印度和中國,各自都有悠久的歷史和文化。但是,古埃及文化、巴比倫文化、印度的哈拉巴文化、古希臘文化毀滅殆盡,唯有崛起于東亞大陸黃河流域的中華文化,在坎坷跌宕中延綿發(fā)展數(shù)千年,經(jīng)歷改朝換代,分分合合,卻始終未曾中斷,成為世界史上“連續(xù)性文化”的典范。那么,為什么中華文化在幾千年滄海桑田的變化中,不僅未曾中斷,而且不斷發(fā)展、豐富,形成了博大精深的獨特文化體系,被世人稱為“神秘的東方文化”呢?
第一,“敬天、法祖”的原始信仰。從地理環(huán)境看,大中華處于半封閉的大陸性地域之中:一面臨海,三面是高山險阻,由此造成了華夏人與外部世界相對隔絕的狀態(tài),自給自足的小農(nóng)經(jīng)濟(jì)也是在這個條件下形成的。人們不求對外的開拓發(fā)展,而只追求日出而作、日落而息的穩(wěn)定的生活方式,以及講究個人的自我完善的道德生活。從社會性質(zhì)看,古代華夏是宗法制的農(nóng)業(yè)社會,以家庭為單位,逐步向外輻射,形成家族、宗族為紐帶的社會網(wǎng)絡(luò)。這個網(wǎng)絡(luò)是以親情編織起來的,道德倫理就成為這個社會上每個人首先必須遵守的,也是自覺遵守的、高于一切的標(biāo)準(zhǔn),從而形成華夏人注重血緣關(guān)系的社會心理。
正是由于這種半封閉的大陸性地域、農(nóng)業(yè)經(jīng)濟(jì)格局、宗法與專制的社會組織結(jié)構(gòu)相互影響和制約,構(gòu)成了華夏族社會獨特的、穩(wěn)定的生存系統(tǒng),與此相適應(yīng),華夏文化的形成與發(fā)展顯示了鮮明的倫理型特色。它是一種具有強(qiáng)烈的重德求善的倫理價值取向的文化,正是這種獨特的地理環(huán)境和社會性質(zhì)造成了獨具一格原始信仰—— “敬天法祖”。而這種“敬天法祖”的原始信仰在六千年的歷史長河中衍生出以下觀念:
其一、宗法觀念。中華民族自從開始在黃河、長江流域繁衍生息之日起,就產(chǎn)生了自己的信仰。這種信仰以部落神、氏族英雄人物為崇拜對象,相傳燧人發(fā)明用火,伏羲發(fā)明家畜馴化,炎帝、神農(nóng)發(fā)明種植、醫(yī)藥,黃帝是發(fā)明舟車、宮室、衣服等器物制造的神,還創(chuàng)制了文字。他們是人,也是神,中國古代民族信仰,往往是氏族領(lǐng)袖死后被尊為神,受到本部族的祀奉。
在古代祖先祭祀與天帝信奉相伴相隨,糾結(jié)在一起。隨著部落組織形式的日趨完備,上帝的輪廓、形象逐漸形成,也日趨完整。祭祖先,敬天神,二者緊密糾結(jié)膠固,凝為一體,構(gòu)成中華民族傳統(tǒng)的宗祖觀念。
宗祖觀念的核心是“孝”,它是從血緣而產(chǎn)生的“親親”之情,并且通過宗祖神的崇拜和祈求保佑家族繁榮而表達(dá)出來,以此維護(hù)家族內(nèi)部的團(tuán)結(jié)。
家庭或家族成員在經(jīng)濟(jì)上相互依賴,父母有撫養(yǎng)子女的義務(wù),并有要求子女贍養(yǎng)的權(quán)利,子女有贍養(yǎng)父母的義務(wù)。作為家長的父親,享有絕對的權(quán)威,有權(quán)支配子女,子女對其有尊敬和服從的義務(wù)。《尚書.酒誥》云:“肇率牛車,遠(yuǎn)服賈,用孝養(yǎng)厥父母?!薄对姡⊙拧芬嘣疲骸案纲馍遥纲饩衔?,拊我畜我,長我育我,顧我復(fù)我,出入腹我,欲報之德,昊天罔報?!薄靶ⅰ边@一道德觀念,主要是用來維系宗法制度的,周代奉行嫡長子繼承制,并在此基礎(chǔ)上確立了“大宗”、“小宗”的宗法制。由此看來,“孝”就不僅限于家庭倫理范疇,子女贍養(yǎng)父母的義務(wù)已擴(kuò)大到“小宗”對“大宗”的義務(wù),并在政治上延伸為卿大夫?qū)χT侯、諸侯對天子的義務(wù)。血緣上“追孝”、“尊祖”觀念成為維系統(tǒng)治階級內(nèi)部的紐帶。于是,由家族到國家達(dá)到了倫理與政治的統(tǒng)一。之后,孔子又在《孝經(jīng)》中提出“不孝有三,無后為大?!边@就把人放在了一個立體坐標(biāo)中,一個人不僅要對當(dāng)代家族的人負(fù)責(zé),而且要上對得起列祖列宗,下對得起子孫后代。在老百姓心里,“忘本”、“沒良心”、“敗家子”、“數(shù)祖忘典”是最大的恥辱,而“光宗耀祖”、“德高望重”、“封妻蔭子”、“流芳百世”又成為有志者的畢生追求,正是這種宗法觀念對中華民族的文化起到了非常深遠(yuǎn)的影響。
其二、大一統(tǒng)的國家觀念。在秦漢以后,“敬天法祖”的原始信仰具體化為“忠孝節(jié)義”、“三綱五常”。它使“敬天法祖”的原始信仰內(nèi)容更趨完善化,它是宗教信仰,又是政治思想,更能適應(yīng)大一統(tǒng)國家的生存要求。
數(shù)千年來,中華民族遭受到內(nèi)憂外患,政權(quán)經(jīng)過多次更迭,社會經(jīng)過無數(shù)動蕩,民族之間以融合為基調(diào),也有過暫時的戰(zhàn)爭??傊貪h以后的中國,人民已習(xí)慣于在中央高度統(tǒng)一的政權(quán)下生活,因為大一統(tǒng)國家與國與民都具有重大利益:
(1)、大一統(tǒng)國家可以給人民帶來實際利益。比如說,國家統(tǒng)一,老百姓可以不見兵戈,安居樂業(yè)地過日子;國家統(tǒng)一,可以借助強(qiáng)大的國力抵御各種自然災(zāi)害,調(diào)劑各地歲收豐歉,從而避免人民流離失所。
(2)、大一統(tǒng)國家可以充分發(fā)揮大國的綜合國力辦成大事。古代中國是個自然經(jīng)濟(jì)結(jié)構(gòu)的小農(nóng)經(jīng)濟(jì)之國,一家一戶為生產(chǎn)單位,生產(chǎn)的產(chǎn)品除了供全家消費,所余無幾。正是借助統(tǒng)一大國的高度集中,把分散、零星的少量財富集中起來,聚沙成塔,集腋成裘,集中全國人力、物力進(jìn)行大規(guī)模的物質(zhì)建設(shè)和文化建設(shè),如修長城、開運河、整治大河河道,進(jìn)行重大項目的文化建設(shè),修纂大的文化典籍,如《永樂大典》、《四庫全書》等。戰(zhàn)時還可以調(diào)動全國人力抵御外來侵略勢力。
(3)、大一統(tǒng)國家吸引力強(qiáng),便于光大中華文明。第二周期秦漢帝國把大中華文明光大于西域,乃至中亞、西亞;第三周期的隋唐帝國把大中華文明光大于朝鮮、日本,乃至東南亞;第四周期元明清帝國把大中華文明光大于歐亞大陸,乃至非洲。
(4)、大一統(tǒng)國家影響力大,即便分裂時期大中華文化仍占主導(dǎo)地位。第一周期春秋戰(zhàn)國時期,東周和東方六國都是華夏文化,逼迫西戎秦國首先把自己“華”化;第二周期三國兩晉南北朝時期,盡管出現(xiàn)了許多政權(quán),華夏文化始終保持占主導(dǎo)地位的態(tài)勢。魏、蜀、吳、兩晉、南朝都是華夏文化,北方16國,更是以炎黃子孫的身份自居,不失時機(jī)地進(jìn)行漢化改革;第三周期宋代出了程朱理學(xué),遼、夏、金、元無不爭奪漢族儒家名士,接受道教;第四周期清朝相對于元、明仍是分裂時期大中華文明圈內(nèi)的一個大國,盡管其曾推行“剃頭令”,搞“圈地運動”,但是,之后它也極力奉行程朱理學(xué),搞“華、夷之辯”,以證明自己是正宗的大中華文明。
中華民族接受、支持、維護(hù)這個大一統(tǒng)的國家制度,從諸子百家到佛、道、儒三教分別站在自己的宗教立場論證其合理性。從“三綱”、“五?!钡难孕兄畜w現(xiàn)天理,宣揚忠孝是出自人的本性,不忠、不孝是違背人的天性,不但不能成佛、成仙、成圣賢,甚至也不足以為人。從孝敬父母作起,推及到孝忠祖上、祖先、祖國,形成中華民族的價值觀:以尊祖、愛國、報恩、報國為榮,以竊國、賣國、篡國為恥。在老百姓心里,最臭的莫過于“漢奸”、“賣國賊”,可以說比罵祖宗八代還厲害。這類人不光個人被判了“死刑”,就連子孫后代也抬不起頭來。
就這樣,大一統(tǒng)觀念促進(jìn)大一統(tǒng)國家的形成,大一統(tǒng)國家又進(jìn)一步光大了大中華文明,形成滾雪球式的良性運轉(zhuǎn),使大中華文明不僅未曾中斷,而且不斷發(fā)展、豐富,形成了博大精深的獨特文化體系。
第二,?;实氖侨寮?,造反的也是儒家。在原始社會和奴隸制社會,敬天法祖的原始信仰,與當(dāng)時中央政權(quán)的統(tǒng)治不太集中、中央統(tǒng)攝力還不夠強(qiáng)大的政治形勢相適應(yīng)。秦漢以后,封建王朝勢力強(qiáng)大了,上帝的統(tǒng)攝范圍也擴(kuò)大了,不但山川、日月,連人們的內(nèi)心活動、意念善惡也要受宗教神學(xué)的管束。由皇帝直接管理天下的郡縣,參與管理的有丞相、三公。但皇帝經(jīng)常受到諸侯、后黨、權(quán)臣的干擾,甚至發(fā)生宮廷政變,皇權(quán)遭到篡奪。為了加強(qiáng)中央集權(quán),鞏固社會秩序,漢朝以后,加強(qiáng)了儒學(xué)的教化作用。特別是隋唐兩代,以科舉取士,官方用考試制度強(qiáng)力推行儒教思想,凡是走這條路的士人都要系統(tǒng)地接受儒教思想培訓(xùn),這對儒教的普及起了有力的作用。宋朝以后,儒教以教化力量鞏固了中央集權(quán),使它更趨穩(wěn)定,故有權(quán)臣而沒有篡臣。曹操在唐以前有能臣的形象,宋以后,曹操成為奸臣;唐以前,揚雄在思想界有較好的聲望,宋以后,由于揚雄做過王莽的官,聲望下降。
中國的儒教有一個顯著的特點,即高度的政教合一,政教不分,政教一體,皇帝兼任教皇,或稱教皇兼皇帝。神權(quán)、政權(quán)融為一體,儒教的教義得以以政府政令的方式下達(dá)。朝廷的“圣諭廣訓(xùn)”是圣旨,等同于教皇的手諭。中世紀(jì)歐洲的國王即位,要教皇加冕,才算取得上帝的認(rèn)可。中國皇帝即位,只要自己向天下發(fā)布詔書就行了。詔書必以“奉天承運,皇帝詔曰”開始,皇帝的詔書同時具有教皇敕令的權(quán)威。
儒教是中華民族特有的準(zhǔn)宗教,凡是生活在中國這塊古老土地上的各民族,包括各少數(shù)民族,如北方的遼、金、元、西夏及清,歷代王朝都以儒教為國教,尊孔子為教主。儒、佛、道三教同為古代傳統(tǒng)宗教。唯有儒教利用政教結(jié)合的優(yōu)勢得以成為國教,儒教的神權(quán)與皇權(quán)融為一體,不可分割。然而,一旦皇權(quán)制度被廢除,儒教也隨著皇權(quán)制度一同凋謝。
歷史證明,行政命令打不倒信仰,但政權(quán)是可以更迭的,儒教與皇權(quán)融為一體,所以才隨著皇權(quán)的廢除而暫時銷聲匿跡,這便出現(xiàn)了另一種現(xiàn)象:?;实氖侨寮遥旆吹囊彩侨寮?。孔子是思想家、教育家,但不能算政治家。儒學(xué)被后人宗教化后,既是學(xué)術(shù),又是準(zhǔn)宗教。它不僅能為統(tǒng)治階級服務(wù),也能為被統(tǒng)治階級反抗剝削壓迫提供思想武器。
均平原則構(gòu)成中國古代經(jīng)濟(jì)改革和農(nóng)民起義的指導(dǎo)思想。均平原則是針對財富占有行為的一種分配理論,孔子對此有過經(jīng)典闡述:“丘也聞有國有家者,不患寡而患不均,不患貧而患不安。蓋均無貧,和無寡,安無傾?!敝袊糯骄髁x蓋源于此。其實孔子的均平思想是對古代社會大同理想的描摹,也是體現(xiàn)其本人確立的“仁”學(xué)風(fēng)格?!叭省笔且环N以普遍情感為基調(diào)的理論原則,它在分配行為上必然體現(xiàn)出和諧溫馨,而不是巧取豪奪、毫不利人、專門利已。但孔子講的并非絕對平均,他將“仁”、“禮”相互貫通,將平均原則寄于“禮運”之中,禮的實質(zhì)是區(qū)分上下尊卑等級秩序,在分配行為上應(yīng)該體現(xiàn)不同等級對財富的不同占有,超越或低于起碼的標(biāo)準(zhǔn),那也是不允許的,是對禮制的踐踏。因此分配行為應(yīng)該是依禮而行,均衡有序,使貧富、貴賤之間差距不至于無限擴(kuò)大。荀子也指出“制禮儀以分之”的目的,就在于“皆使人載其事而各得其宜,然后使殼祿多少厚簿之稱。使夫群居合一之道也?!敝鲝垺耙远Y分施,均遍而不偏”,“非禮不進(jìn),非義不受”。因此均平思想成為民族意識和分配標(biāo)準(zhǔn),成為歷次改革和農(nóng)民起義的重要目標(biāo)和理論武器。從北魏孝文帝的“均田制”,王安石提的“方田均稅法”,張居正的“一條鞭法”都是以均平為指導(dǎo)思想提出來的。
農(nóng)民起義、騷動、**更是如此,“均平”始終是農(nóng)民起義軍最感親切、最得人心、最有號召力的戰(zhàn)斗旗幟。綠林、赤眉起義是因為“力作所得,不足以給賦稅?!秉S巾軍的原發(fā)組織“太平道”宣稱“人無貴賤,皆天所生。”隋末農(nóng)民起義首先在山東發(fā)難,是由于山東地主是土地兼并及其嚴(yán)重的“狹鄉(xiāng)”地區(qū)。唐未農(nóng)民起義軍第一次打出了“均平”的旗幟,王仙芝自稱“天補平均大將軍”。南唐諸佑起義提出了“使富者貧,貧者富”的口號,宋代王小波、李順起義明確提出“均貧富”。明末李自成提出“均田免糧”的綱領(lǐng)。
儒家不僅為造反大軍提供行動綱領(lǐng)和鮮明的旗幟,還為造反大軍提供了領(lǐng)袖人物和骨干力量。秦末農(nóng)民起義的隊伍中,范增、張良、蕭何、陳平、陸賈、酈食其、曹參皆飽學(xué)之士。
《明史?儒林傳序》說:“明太祖起布衣,定天下。當(dāng)干戈搶攘之時,所至征召耆儒,講論道德,修明治術(shù),興起教化,煥乎成一代之宏規(guī)。雖天亶英姿,而諸儒之功不為無助也?!币馑际侵煸半m然是個馬上皇帝,但是在他的高級幕僚中諸儒占主要成分,在他興兵造反、奪取天下的過程中諸儒功不可沒。
朱元璋一開始就注重網(wǎng)羅儒者文士。早在渡江前,他即已征用馮國用及其弟國勝、李善長等人,馮氏兄弟“俱喜讀書,通兵法,元末結(jié)寨自?!保ā睹魇贰肪?29《馮勝傳》)。朱元璋進(jìn)軍滁陽,途經(jīng)妙山時,馮氏兄弟“著儒服”來見,朱元璋謂:“若書生耶?試為我計安出?”國用曰:“建康,龍蟠虎踞,帝王都會,自古記之。幸而近我,其帥懦弱不任兵,宜急擊下其城,踞以號召四方。事仿仁義,勿貪子女玉帛若群豎子者,天下不難定也”(焦竑編:《國朝獻(xiàn)征錄》卷六王世貞《宋國公馮勝傳》)。朱元璋遂令其為幕府參謀,計議大事。不久,定遠(yuǎn)人李善長也到軍營求見。他“少讀書,有智計,習(xí)法家言,策事多中”(《明史》卷127《李善長傳》)。初謁朱元璋,即曰:“秦亂,漢高起布衣,豁達(dá)大度,知人善任,五載成帝業(yè)。今元綱既紊,天下土崩瓦解。公,濠產(chǎn),距沛不遠(yuǎn),山川王氣,公當(dāng)受之。法其所為,天下不足定也”(同上),殷殷期其成為當(dāng)今的漢高祖劉邦。朱元璋對他甚為信任,留在幕府掌書記。
渡江后,朱元璋更是大力羅致人才,“所克城池,得元朝官吏及儒士盡用之”(劉辰:《國初事跡》)。至正十一年(1355),兵克太平,儒士陶安、李習(xí)、潘庭堅、梁貞等出城迎接。陶安,博涉經(jīng)史,尤深于《易》,與朱元璋語,甚合其意,遂留參幕府,拜左司員外郎,從克金陵,升左司郎中;李習(xí),自幼老成持重,治《尚書》,又旁通群經(jīng),攻性理之學(xué),被朱元璋用為太平府知府;潘庭堅,元末用薦為富陽縣學(xué)教諭,朱元璋任之為太平府儒學(xué)教授,次年取金陵后改為中書博士;梁貞,元至正中為國子監(jiān)生,后由國子伴讀授太平路儒學(xué)教授,見朱元璋時,所言輒援《詩》、《書》,被命為江南行省都事。至正十六年(1356),朱元璋率軍取金陵,得儒士夏煜、孫炎、楊憲等十余人,各授官職。又因秦元薦而以書聘陳遇。陳遇,博通經(jīng)史,尤邃于先天之學(xué),元末為江東明道書院山長。朱元璋稱其“學(xué)貫三史六經(jīng),博覽兵書百技,才兼文武,實我良輔”(《國朝獻(xiàn)征錄》卷116陳鎬《陳靜誠先生遇傳》)。他與朱元璋相見后,希望其“以不嗜殺人,薄斂任賢,復(fù)先王禮樂為首務(wù)”(《明史》卷135《陳遇傳》),被命籌帷幄,諸計劃多秘不傳。至正十八年(1358),朱元璋下徽州,召儒士唐仲實,問:“漢高帝、光武、唐太祖太宗、元世祖一平天下,其道何由?”對曰:“此數(shù)君者,皆以不嗜殺人,故能定天下于一。今公英明神武,驅(qū)除禍亂,未嘗妄殺。然以今日觀之,民雖得歸而未遂生息”,元璋深以為然(《明通鑒》“前編”卷一)。又素聞儒士朱升之名,遂“潛就訪之。升因進(jìn)三策曰:‘高筑墻,廣積糧,緩稱王。’”朱元璋大悅,命預(yù)帷幄密議,“大抵禮樂征伐之議,贊畫居多”(《朱楓林集》卷九《學(xué)士朱升傳》)。
在建置百官的同時,又遣起居注吳林、魏觀待訪求遺賢于四方,以期使更多的儒者文士聚集在自己周圍。這樣便逐漸形成了一個以劉基、宋濂等出自浙東的儒家學(xué)者為核心的幕僚集團(tuán),這對朱元璋的思想及他的帝業(yè)之成功均有重大影響。
近代更是如此,洪秀全、石達(dá)開、康有為、梁啟超、孫中山、陳獨秀、章太炎、毛澤東本身就是儒家,而且是大儒、鴻儒、通儒。毛澤東曾經(jīng)崇拜過孔子、陳獨秀。他的許多政略出自《論語》,其革命理想也是孔子說的大同世界。
治世治國安民靠儒家,亂時打天下也靠儒家,也就是說在中國歷史上,無論治亂興亡,哪一個階段都離不開儒家,這本身就是文明的繼承。換句話說,在中國只要有儒家存在中華文明就不會中斷,而中國的文人中,百分之九十是儒家,中華文明怎么辦會中斷呢?
第三,道家有“興滅繼絕”的功能。道家文化作為中華文明的根基,具有旺盛的再生能力。魯迅先生(1881—1936)曾經(jīng)斷言“中國根柢全在道教”,李約瑟博士(1900—1995年)也敏銳地指出:“中國如果沒有道家思想,就會像是一棵某些深根已經(jīng)爛掉了的大樹”。道學(xué)文化中既蘊藏著死而復(fù)生的活力,又具有包羅萬象、海納百川的品格。為什么中國文化在古代能接納印度佛教,在近代又能接納西方的基督教文明,這顯然不是“嚴(yán)夷夏之防”的儒家文化的功能,而是靠道家善于融匯異質(zhì)文化的博大包容的特性。在中國歷史上,歷代統(tǒng)治者也都以儒守成,以道達(dá)變,人們深知道家智慧有如“水善利萬物而不爭”的寬容氣度,以及能生能化,善于應(yīng)變的長處。
“反者,道之動?!闭f明道家的核心是革命的哲學(xué)。在中國歷史上,凡是大的社會變革,總是由道家首先發(fā)起對舊思想、舊習(xí)慣、舊制度、舊體制的批判開路。從先秦的老子、莊子、列子,到近代的魏源、魯迅都是舊社會的批判者,是革命的先行和旗手。
道學(xué)的策略思想是以曲求伸、以弱勝強(qiáng)、以柔克剛,在士人被腐化,思想被扭曲,人民失去信仰時,道家以開放的思想體系和儒家自我封閉體系有著互補作用。每逢儒學(xué)走向唯心主義,成為僵化的“官文化”時,道家便對儒學(xué)進(jìn)行補救。統(tǒng)治階級既無創(chuàng)業(yè)的歷史使命和事業(yè)壓力,又拋棄了儒學(xué)德治思想的約束,逐漸成為“無道”。必然形成信仰危機(jī)。儒學(xué)道統(tǒng)衰弱,禮崩樂壞。而儒家剛性太強(qiáng),“天不變,道亦不變,”、“士可殺而不可辱?!痹谶@種情況下,道家發(fā)揮自己的優(yōu)勢,“窮則變,變則通,通則久?!睆亩鸬綄χ腥A民族興滅繼絕的作用。(見第八章第二節(jié))
“無”和“反”是《易經(jīng)》所說的“窮則變,變則通,通則久”和《道德經(jīng)》所謂“大曰逝,逝曰遠(yuǎn),遠(yuǎn)曰反”的兩種不同表現(xiàn)形式。無中生有是創(chuàng)新,反其道而行之是改革。有了改革和創(chuàng)新就可以達(dá)到“興滅繼絕”了。道學(xué)主導(dǎo)的歷史階段是“國亂”(久亂)一直延續(xù)到強(qiáng)治周期段的前期?!皣鴣y”(久亂)周期段,國破了,(皇)家散了——諸侯坐大,法、儒兩家的招數(shù)都使絕了,不靈驗了,因此導(dǎo)致信仰危機(jī),出了危機(jī)怎么辦?只有道學(xué)出來救駕。但救駕的方式不是助一臂之力,而是掛倒檔,開倒車,返本開新,另辟蹊徑,重開新路。
第一周期,當(dāng)神學(xué)出現(xiàn)了信仰危機(jī)之后,圣哲把人、神、道德、天文和巫、卜相結(jié)合出了《易經(jīng)》,這便是道學(xué)的根基。
第二周期,在“禮崩樂壞”的春秋時代,孔夫子發(fā)出“興滅國,繼絕世,舉逸民”的呼喊。然而,他并未做到,真正做到的是道家。道家在批判神學(xué)、天帝、圣賢的同時,以法家的面目出現(xiàn),運用“法”、“術(shù)”、“勢”,推出一系列改革方案、政策和措施,最終實用武力完成統(tǒng)一大業(yè)。故司馬遷在《史記》中特意將老子和韓非子寫在一起。
第三周期,東漢末年經(jīng)學(xué)地位下降,道家的何宴、王弼將道學(xué)和儒學(xué)相揉合,創(chuàng)立了“玄學(xué)”。
第四周期,南宋時期,儒學(xué)危機(jī)時,朱熹融合儒、道、佛創(chuàng)立了理學(xué)??梢哉f是道家一次又一次地維護(hù)了中國的“道統(tǒng)”。
第五周期,從啟蒙運動、洋務(wù)運動、太平天國異教運動、戊戌變法、新文化運動、共產(chǎn)主義運動,到文化大革命運動,儒學(xué)連續(xù)受到?jīng)_擊,在這信仰危機(jī)、民族危亡的日子里,是道學(xué)在批判儒學(xué)的同時返本開新,敞開思想,對世界開放,實行“拿來主義”。實證主義進(jìn)來了,馬克思列寧主義也進(jìn)來了,新儒學(xué)復(fù)活了,古老的中國才又一次煥發(fā)生機(jī)。
道家的一個重要信條是“不為王者師,便為萬世師”。在政局混亂的時期,一些有高深道學(xué)的人轉(zhuǎn)而為師,如鬼谷子、文中子即是。他們是諸子百家中一流的、非常規(guī)的教育家。他們用改朝換代的帝王之術(shù)授徒課業(yè),培養(yǎng)一批因緣時會、出入軍機(jī)的人才,使之逐鹿中原,以求一逞。隋末天下鼎沸,文中子王通先生教出了魏征、李密、徐懋公等幾個知兵領(lǐng)軍的干才,他們都是扭轉(zhuǎn)乾坤的命世之才。鬼谷子、文中子通過自己的學(xué)子達(dá)到了對國家、民族“興滅繼絕”的目的。
中華民族文化周期性的更新再造功能不是別的,就是“道”。因為它是開放型的,且具備“體”的特質(zhì),有隱性世界的力量,這也是中華文明未出現(xiàn)斷層的一個內(nèi)在原因。如自然界,月季花枝繁葉茂,月月開花,可是花農(nóng)每年冬季都平一次茬。翌年生長出來的新枝條粗壯鮮嫩,開的花比上年更大、更鮮艷。
第四,具有強(qiáng)大生命力的原始民主制。公元前7——2世紀(jì),為什么經(jīng)濟(jì)、文化相當(dāng)落后的西戎小國——秦能打敗政治、經(jīng)濟(jì)、文化相當(dāng)先進(jìn)的東方六國呢?13世紀(jì),為什么經(jīng)濟(jì)、文化相當(dāng)落后的僅有150萬人口的蒙古能打平歐亞大陸,建立四大可汗國呢?為什么16世紀(jì)經(jīng)濟(jì)、文化相當(dāng)落后僅有幾十萬人口的女真族能打敗6000多萬人口的大明王朝呢?研究發(fā)現(xiàn):根本原因在于原始民主制勝過封建專制、獨裁政治。而這種原始民主制與之后的專制、獨裁在中華大地上長期并存,經(jīng)六千年之久,歷三個大周天,九個周期。每當(dāng)中原地區(qū)的政權(quán)走向?qū)V?、獨裁,搞得民不聊生時,底層民眾或邊疆的部族就祭起原始民主制的法寶,組織起一支又一支的革命大軍,摧毀專制、獨裁的腐敗政權(quán),改朝換代,使華夏文化走上一個新的臺階。
原始民主政治制度是原始社會普遍實行的制度。我國在夏以前實行的“禪讓”制度實際就是原始民主制。原始民主制始建于父系社會,是在家族議事會的基礎(chǔ)上形成的。最初的議事會由各父系的大家長(長老)組成,負(fù)責(zé)處理內(nèi)部事務(wù)以及與其它氏族交往的事務(wù)。在母系社會民眾大會觀念淡薄之后,這些大家長(長老)逐漸形成氏族的貴族,是氏族酋長的輔佐兼保護(hù)人,對氏族的各種活動有參與權(quán)。
部落議事會由各氏族首領(lǐng)和家族族長組成。部落的重大事情,如戰(zhàn)爭、講和、締結(jié)盟約、推舉部落首領(lǐng)等,都必須由部落議事會作出決定。部落議事會成員一律平等,采取民主的方式協(xié)商討論,實行原始民主制。史載:“伏羲氏以龍紀(jì),故龍師名官。”(《通典》卷19《職官一》)傳說“黃帝置六相”,“堯有十六相”——“四岳”、“十二枚”,“官員六十名”。(同上)“少昊氏以鳥名官,風(fēng)鳥為歷正,玄鳥為司分,伯趙氏為司至,青鳥氏為司啟,丹鳥氏為司閉,祝鴆氏為司徒,(且鳥)鴆氏為司馬,(尸鳥)鴆氏為司空,爽鴆氏為司寇,(骨鳥)鴆氏為司事”。(《左傳昭公十七年》)
原始民主是與之后的封建專制、特權(quán)相對的,要實現(xiàn)民主就勢必反對特權(quán)。所謂特權(quán)是指超越任何制約、濫用國家權(quán)利的權(quán)利,必然遭到大多數(shù)人的強(qiáng)烈抗議,反對特權(quán),就能取得多數(shù)人的擁護(hù),產(chǎn)生極大的向心力、凝聚力和戰(zhàn)斗力。
第一、二周期之交的春秋戰(zhàn)國時期,東周和東方六國的封建領(lǐng)主專制制度已經(jīng)走向窮途末路,在西南邊陲的秦國,由于封建領(lǐng)主專制制度的基礎(chǔ)薄弱,經(jīng)過“商鞅變法”最先廢除了封建領(lǐng)主專制制度,建立了封建地主制的生產(chǎn)關(guān)系。
秦原系顓頊之后,西周時是一個附庸小國,東周初年被封為諸侯國。長期活動在陜西和甘肅東部,與西戎部落雜居,非子為秦部落領(lǐng)袖,時因替周孝王養(yǎng)馬有功,受封為附庸,由犬丘(今陜西興平東南)遷至秦(今甘肅張家川東),始以秦為稱號。公元前659—621年,秦穆公實行原始民主制,任用百里奚、蹇叔等,積極加強(qiáng)國勢。插手中原國家的事務(wù),謀求向東發(fā)展。但是晉國在晉文公的統(tǒng)治下迅速強(qiáng)大,阻礙了秦國東進(jìn)的計劃。尤其在崤之戰(zhàn)中,秦軍慘敗。因此,秦穆公轉(zhuǎn)而向西發(fā)展。先爭取到西戎謀臣由余歸降,然后用由余的計謀進(jìn)攻戎地,短時期內(nèi)兼并了十二個戎國。開拓了上千里的土地,取得了獨霸西戎的地位。
秦穆公稱霸西戎國。但終因僻處西方,經(jīng)濟(jì)文化落后,國力遜于中原華夏大國。秦孝公即位后,繼續(xù)實行原始民主制,任用商鞅變法,大力招徠六國居士,迅速取得富國強(qiáng)兵的效果。一躍成為戰(zhàn)國七雄中的強(qiáng)國,秦始皇奮六世之余烈,東并六國,建立秦帝國,結(jié)束了長達(dá)五百年的混戰(zhàn)。
第三、四周期之交的夏、遼、金、元最初都是實行原始民主制凝聚本部各部落的力量。蒙古族的“庫里勒臺”就是實行原始民主制建立起來的,“庫里勒臺”是各部落首領(lǐng)舉行的一種會議,它決定有關(guān)部落的重大事情,如戰(zhàn)爭、講和、締結(jié)盟約、推舉部落首領(lǐng)等,都必須由部落議事會做出決定。后來演變成“宗王大會”。與會成員一律平等,采取民主的方式協(xié)商討論,具有極大的凝聚力。一是人才選拔面寬。凡是各部落的首領(lǐng)及貝勒都是大汗的后選人,能夠優(yōu)中選優(yōu);二是即使選不上大汗,當(dāng)攝政王同樣可以發(fā)揮作用。多爾袞就是以攝政王的身份指揮八旗入關(guān),消滅大明王朝的的。由于夏、遼、金、元實行原始民主制還涌現(xiàn)出一批女主,如西夏惠宗秉常母梁太后、遼太祖阿保機(jī)皇后述津氏、遼圣宗母承天皇太后蕭綽、金熙宗皇后裴滿氏、成吉思汗皇后孛爾臺旭真、元文宗皇后弘吉刺氏等,臨朝稱制少則幾年,多則十幾年,其中承天皇太后蕭綽“裁決國事”長達(dá)40年之久,在歷史上產(chǎn)生了深遠(yuǎn)的影響。
綜上所述,大中華文明未曾中斷的根本原因有四:根深蒂固的“敬天法祖”的原始信仰衍生了宗法觀念和大一統(tǒng)觀念是思想基礎(chǔ);儒學(xué)是個雙刃劍,坐天下治國安民是儒家的長項,打天下安邦定國也離不開儒家;道家是中國人的哲學(xué),是中華文化的“體”,具有“返本開新”、“興滅繼絕”的功能,在吸收異質(zhì)文化,推動大中華文化與時俱進(jìn)中具有隱性世界的力量;原始民主制是“德文化”的根基,是改朝換代的原動力,是專制、獨裁、腐敗分子的克星。