王 婷,王麗娟
(中國空空導彈研究院 11所,河南洛陽 471009)
單片機是一種集成電路芯片,采用超大規(guī)模集成電路技術將處理器CPU、隨機存儲器RAM、只讀存儲器ROM、多種I/O口和中斷系統(tǒng)、定時器/計數(shù)器等功能集成到同一芯片上,構成了一個小且完善的計算機系統(tǒng)[1-2]。由于其功能靈活、集成度高、可靠性好,因此在工業(yè)控制領域有廣泛的應用。在使用某型微控制器對電源進行控制和檢測時發(fā)現(xiàn),軟件中斷處理算法中存在的問題,本文對這些問題進行分析,并提出解決方法,為今后深入應用提供參考。
文中采用NXP的LPC2132單片機完成電源控制、檢測、通訊等功能,該單片機基于ARM7核心,具有運行速度快、外設豐富、使用簡單等優(yōu)點。
在該電源系統(tǒng)中,該單片機主要完成以下工作:利用UART串口接受控制指令輸入并輸出狀態(tài)信號和測試數(shù)據(jù)、對電壓進行 A/D采樣、完成控制算法、用PWM脈寬調制技術控制穩(wěn)壓電源的變換和輸出,接收其他外部控制指令完成點火控制、故障處理等功能。
為實現(xiàn)上述功能,采用如下中斷算法:
(1)開啟串口接收和發(fā)送中斷,在中斷服務程序中完成串行數(shù)據(jù)的收發(fā),數(shù)據(jù)包的整合、校驗、拆解。
(2)開啟定時器0周期中斷,在定時器周期中斷中完成控制指令的獲取、數(shù)據(jù)分析、完成控制算法和控制信號的輸出。
(3)開啟4路外部事件中斷,用于獲得外部脈沖控制信號和故障處理。
(4)開啟A/D采樣中斷,自動完成各通道信號的采集,并將數(shù)據(jù)存入內(nèi)存緩沖區(qū),供控制算法調用。
在以上程序中,定時器0中斷作為主任務完成整個系統(tǒng)的任務調度,其他外部中斷不斷觸發(fā)各種任務,完成指令和數(shù)據(jù)的更新,供主任務調度。
最初上述中斷算法能夠滿足要求,隨著功能的增加,如要求電源能夠對外部控制信號做出快速反應;更高要求的串行通訊的可靠性;更加精確快速要求的電源控制算法的實現(xiàn)使得上述中斷算法的不足逐漸突現(xiàn),需進行改進。
由于采用LPC2132主頻較低,沒有DSP核,運算能力較弱,進行功能、串行通信和算法的增加和擴充后,原算法越來越無法滿足要求。
在上述的中斷算法中,LPC2132處理器輪流執(zhí)行定時器、A/D、串口、外部中斷等任務程序。與其他大多數(shù)處理器一樣,在響應一個中斷任務的同時,處理器自動屏蔽中斷使能,只在完成當前中斷服務程序后,才響應另一個中斷。由于定時器0周期中斷程序需完成各種任務和控制算法,其執(zhí)行周期較長,在其運行時間內(nèi),處理器無法響應串行數(shù)據(jù)中斷,如果在定時器0周期中斷程序執(zhí)行的時間內(nèi)收到2 Byte以上UART數(shù)據(jù),則可能造成通訊數(shù)據(jù)的丟失。同樣當系統(tǒng)執(zhí)行定時器0周期中斷和串行通訊中斷時,也無法響應外部中斷事件,使得外部控制信號的響應時間被延遲,系統(tǒng)功能以及算法越復雜,延遲時間越長。當有緊急外部事件時將不能響應,如故障處理。這些是不允許的,在程序執(zhí)行中需確保這類緊急事件能得到及時響應。
上述問題主要是由于某個任務中斷服務程序執(zhí)行時間過長,此期間關閉了其他中斷,導致其他緊急任務的中斷無法被觸發(fā)執(zhí)行。要該問題,除更換更快速的DSP處理器外,還應優(yōu)化軟件結構。
軟件上考慮采用以下方法[3-5]:
(1)盡量縮短每個中斷服務程序的執(zhí)行時間。在中斷中僅通知系統(tǒng)事件發(fā)生,而事件的處理交給一個獨立的任務處理,在該任務處理中,中斷系統(tǒng)是打開的,不會阻塞其他外設響應。但當任務較多時,如何管理、組織這些任務,使系統(tǒng)盡快執(zhí)行緊急的任務,則需要引入嵌入式實時操作系統(tǒng)來調度任務。而對于電源這類簡單的系統(tǒng),引入操作系統(tǒng)顯得過于復雜。
(2)使中斷可重入,即在一個執(zhí)行較長的中斷處理程序中,再次打開中斷,使處理器能夠在該中斷服務程序中,隨時被更緊急的中斷事件打斷,優(yōu)先執(zhí)行緊急的中斷服務程序,執(zhí)行完畢后,再繼續(xù)本中斷服務程序。某些處理器能夠硬件處理中斷的重入,而LPC2132是基于ARM7結構,其硬件不具備中斷重入功能,因此只能靠軟件實現(xiàn)。
軟件可以使用嵌入式實時操作系統(tǒng)完成中斷的重入,但該方法過于復雜,所以這里采用一種簡單的方法實現(xiàn):
當進入中斷服務時,系統(tǒng)自動將全局中斷使能屏蔽,導致無法響應新的中斷,那么在某個中斷服務程序中,清除當前中斷源、重新使能全局中斷就可以使系統(tǒng)響應其他中斷,初步代碼如下:
VICIntEnClr=1?14;//清除當前中斷源VICVectAddr=0x00;//通知系統(tǒng)中斷變化IRQEnable();//使能IRQ中斷
在實際的操作中,該方法能夠在中斷服務中,重新打開系統(tǒng)中斷,使CPU能響應新的中斷。但有時軟件會跑飛,沒有正常完成中斷嵌套和返回,需進一步改進。
中斷服務程序要想不破壞主程序狀態(tài)并能正確返回,必需正確進行現(xiàn)場的保護和恢復。在匯編語言中,這些任務由編程者手動實現(xiàn),在C語言中,這些任務由編譯器自動完成。
C語言編程中,一個典型中斷服務程序如下:
_irq聲明該函數(shù)為中斷服務程序,keil編譯器自動在函數(shù)內(nèi)部增加了中斷現(xiàn)場保護的代碼,編譯器增加的中斷現(xiàn)場保護和恢復的代碼如下:
但在這部分代碼中,并沒有完整的保護現(xiàn)場,程序的返回地址并沒有保存。
一般的單片機如AVR,中斷時C語言將下一條指令地址PC+1保存入堆棧SP中,返回時將彈出地址彈出到PC,只要堆棧足夠大這樣的嵌套中斷不會有問題,但LPC2132不同。
ARM7處理器在進入IRQ異常處理時,內(nèi)核硬件自動執(zhí)行以下工作:
(1)將返回地址保存到r14_irq。中斷處理程序可以利用r14_irq-4寫入PC來返回。
(2)將CPSR當前值存入SPSR_irq。返回時可以通過SPSR_irq恢復CPSR。
(3)設置CPSR為irq模式,同時置位中斷禁止控制位。
(4)設置PC為相應中斷處理程序入口地址,跳轉到中斷處理程序。
因此在中斷處理程序中,軟件應當執(zhí)行:1)將r14_irq-4寫入PC來返回;2)將SPSR值復制回CPSR,同時清零中斷禁止控制位。
可以看出,由硬件完成了部分現(xiàn)場保存工作,但__irq聲明中斷服務程序時編譯器不對R14_irq進行保護,因此當再次打開中斷時,R14_irq會被新發(fā)生中斷的斷點值覆蓋,這時被打斷的中斷服務程序將會出錯。假設有下面一種情況:
在上述程序,IRQ處理函數(shù)IRQ_Handler()中調用了函數(shù)Fun1(),若在IRQ_Handler()里中斷可重入,則當新中斷請求恰好在“BL Fun1”指令執(zhí)行完成后發(fā)生時,LR寄存器的值將調整為BL指令的下一條指令(ADD)地址,這樣程序能從Fun1()正確返回;但這時發(fā)生了新的中斷請求,需要進行新中斷的響應,此時處理器為了能使新中斷處理完成后正確返回,也將進行LR_irq保存。這兩次對LR_irq的操作將發(fā)生沖突,當新中斷返回后執(zhí)行STMFD指令時,壓棧里的LR不是原ADD指令地址,子程序Fun1()將無法正確返回。
由上述分析可知,僅靠_irq聲明中斷服務程序不能完成嵌套下的中斷服務程序,需手動完成相應的保護。由于中斷時刻LR_irq的保護是硬件實現(xiàn)的,所以可以在重新使能中斷之前改變處理器的模式,使程序中的“BL Fun1”指令不在IRQ模式下運行。這樣當新中斷發(fā)生時就不會對LR寄存器重復操作[1-2]。
手動完成中斷現(xiàn)場的保存和恢復,無需編譯器自行生成保護代碼和_irq聲明,中斷服務程序用C語言的普通函數(shù)實現(xiàn)中斷嵌套。
用這種方法改進后,經(jīng)調試程序可以實現(xiàn)中斷的嵌套運行,但程序會死機、出錯。需進一步分析解決。
當某個中斷發(fā)生時,LPC2132的CPU會自動地去取對應的中斷向量,并檢查對應的中斷是否使能并掛起,這個過程和一般CPU對中斷的處理過程類似,由硬件自動進行。但LPC2132不同的是:CPU除完成以上工作外,還要檢查這個中斷在這么短的時間里,中斷條件是否滿足,若不滿足,則認為是偽中斷。以上造成了程序的死機和出錯。
控制器LPC2132采用的是ARM7處理器,該處理器為3級流水線設計,內(nèi)核沒有配備外設中斷處理器,且向量中斷控制器(VIC)集成在內(nèi)核外,造成中斷處理有異步特性。當中斷源發(fā)出請求后,流水線上還有兩條指令未執(zhí)行,要等這兩條指令執(zhí)行完后,才能處理中斷的請求,若這兩條指令中有關于中斷處理的,例如關中斷,或在執(zhí)行這兩條指令時中斷源被清除、VIC的狀態(tài)發(fā)生改變,這就會觸發(fā)偽中斷。
以上整個過程可能經(jīng)過以下步驟:(1)VIC判斷是否有IRQ中斷。若有,則向內(nèi)核發(fā)送IRQ信號。(2)內(nèi)核保存IRQ狀態(tài)。(3)執(zhí)行流水線的多個周期的處理。(4)內(nèi)核從VIC中裝入IRQ地址。
若在執(zhí)行到步驟(3)時,向量中斷控制器的狀態(tài)改變,那么就將發(fā)生偽中斷。筆者碰到兩種偽中斷情況:
情況1 在步驟(3)時執(zhí)行了關中斷指令。這將導致中斷服務程序入口處CPSR中的中斷是禁止的,并被保存到SPSR。這樣當中斷返回恢復SPSR,中斷還是禁止的,造成此后的程序不正常。
情況2 向向量中斷控制器發(fā)送IRQ信號的中斷標志丟失。當進入偽中斷,VIC將不能裝載到VICVectaddr中的中斷服務程序入口地址,裝載到的是VICDefVectAddr里的默認地址,而這個默認地址在復位后會被置為0x00000000,導致出現(xiàn)假復位。
為防止上述情況的出現(xiàn),需要采取以下兩種方法來預防偽中斷的產(chǎn)生:1)編寫程序來防止偽中斷的產(chǎn)生;2)正確設置和檢測VIC的默認處理程序。
在之前采用修改后的周立功uc/os-2在LPC2000上的移植代碼解決中斷嵌套和重入問題程序的基礎上,對于情況1,擬采用在中斷服務程序入口處判斷中斷發(fā)生時中斷標志位是否被禁止來解決。若被禁止則說明出現(xiàn)情況1,應立刻離開此中斷服務程序,此時不進行中斷標志的清除,中斷將會在下一次中斷使能時處理。在程序中加入如下代碼:
該方法簡單地解決了情況1遇到的偽中斷問題。
對于情況2,在本控制器程序中,在串行通訊當中,當UART0/UART1的RDA/CTI中斷允許時就可能發(fā)生。在UART0中,當UART0 Rx的FIFO到達寄存器U0FCR7∶6所定義的觸發(fā)點(比如接收4 bit)時,將發(fā)生RDA中斷。當UART0 Rx FIFO的深度低于觸發(fā)點時,RDA中斷標志被清除。當UART0 Rx FIFO包含至少1 bit,且在接收3.5~4.5 bit的時間內(nèi)沒有發(fā)生UART0 Rx FIFO動作時,將發(fā)生CTI中斷。若此時UART0 Rx FIFO有任何動作(讀或寫UART0 RSR),有字符進來,CTI中斷標志被清除,此時向量中斷控制器無法識別是誰產(chǎn)生了中斷,CTI偽中斷發(fā)生。
同樣,RDA偽中斷也是這樣發(fā)生的。以接收4 bit發(fā)生RDA中斷為例,當UART0 Rx FIFO已接收3 bit,且超過了3.5~4.5 bit的時間,發(fā)生CTI中斷。在系統(tǒng)正確處理CTI中斷時,恰好有一個字符進來,使得UART0 Rx FIFO中的字符數(shù)正好為4,于是發(fā)生RDA中斷。但是由于先處理CTI中斷,CTI中斷程序先讀取了其中的字符,使UART0 Rx FIFO內(nèi)的字符數(shù)小于4,因此RDA中斷標志就被清除了,等到系統(tǒng)處理RDA中斷時,偽中斷就發(fā)生了。
為解決CTI/RDA偽中斷,在本程序中,采用修改默認中斷處理程序VicDefVectAddr的方法解決。在程序跳轉到默認中斷處理程序時,盡快讀出UART0的接收數(shù)據(jù),解決串行通訊中的偽中斷問題。這種方法簡單易行,效果良好。
經(jīng)過上述分析,本控制程序已經(jīng)基本解決了中斷嵌入和偽中斷問題,在實際應用中發(fā)現(xiàn)仍有問題需進一步改進。
在上述簡單的重新打開中斷允許位的方法中,有可能會使能全部中斷,從而導致一個正在運行的中斷被任何其他中斷打斷。此時可以采用中斷優(yōu)先級管理的方法,只允許更緊要的任務中斷打斷當前中斷。由于LPC2132不具備中斷優(yōu)先級管理功能,無法直接為各中斷設置優(yōu)先級。本程序中通過中斷管理器對32個中斷源進行優(yōu)先級的管理。每個中斷都有一個單獨的使能位,在中斷服務程序中手動將更低優(yōu)先級的中斷使能位清除,以避免打擾當前中斷,服務程序結束時再將其恢復,就可以實現(xiàn)只允許更高優(yōu)先級的中斷重入,達到優(yōu)先級管理。該方法在硬件無法實現(xiàn)的情況下,由軟件實現(xiàn)了中斷優(yōu)先級管理,完善了中斷嵌套算法。本程序的示例代碼如下:
另外在軟件的編寫中發(fā)現(xiàn),由于采用了中斷嵌套,A/D中斷和定時器0周期中斷可能同時調用一個函數(shù),該函數(shù)第一遍尚未執(zhí)行完,所占用的變量還未釋放,就被再次執(zhí)行。若該函數(shù)中使用了全局變量,兩次調用同時改變了全局變量的內(nèi)容,將導致程序出錯。故在考慮中斷嵌套使用時,要考慮可重入性的設置,對于一段可能會被同時訪問的程序或者變量,應按照可重入的要求編寫可重入性以避免此類問題。
本文對電源所用控制器LPC2132中斷程序設計中的中斷算法問題進行了分析,提出了簡單易行的改進方法,并分析了ARM處理器中斷的特點,同時給出了中斷程序設計中中斷嵌套問題、偽中斷問題和中斷優(yōu)先級等中斷算法問題的有效地解決方法及簡單的代碼,進一步完善和優(yōu)化中斷控制算法。
[1]周立功.ARM嵌入式系統(tǒng)基礎教程[M].2版.北京:北京航空航天大學出版社,2008.
[2]周立功.深入淺出 ARM7-LPC213x/214x[M].北京:北京航空航天大學出版社,2006.
[3]JEAN J L.嵌入式實時操作系統(tǒng)μcos-Ⅱ[M].2版.邵貝貝,譯.北京航空航天大學出版社,2003.
[4]LI Qing.Real-time concepts for embedded systems[M].USA:CMP Books,2003.
[5]任哲.嵌入式實時操作系統(tǒng)μcos-Ⅱ原理 及應用[M].北京:北京航空航天大學出版社,2005.