李紅波,李 盛,王 洋,陳 恒
(西京學院理學院,陜西西安 710123)
電子計數器是最為常見的測量時間間隔的電子測量儀器之一[1-3],常被部署在可編程器件中,具有良好的應用效果[4-5]。尤其是嵌在MCU中的可編程計數器與捕獲電路相結合來測量時間間隔,特別適用于信號脈寬、信號周期等測量的嵌入式應用系統(tǒng)中[6-7]。然而,計數器的固有二進制位數少(16位計數器最為常見),捕獲測時的最大時長有限,不能滿足長時甚至超長時間間隔的測量。相比硬件擴展計數器位數的方法[8],采用軟件方法來擴展計數器的位數則更適合基于MCU的系統(tǒng)[9],但是軟件擴展中又存在計數器捕獲中斷和溢出中斷協(xié)作不良問題,會導致捕獲時長數據出現致命性錯誤。本文在分析計數器位數擴展的方法基礎上,首次明確了安全問題的根源,指出計數器位數擴展中存在著新的工作態(tài)——競爭態(tài),并利用工作態(tài)檢測法和RTOS系統(tǒng)的多任務事件同步機制防范和解決中斷事件的時序問題,糾正了數據錯誤問題。
可編程計數器的捕獲結構如圖1(a)所示。計數器工作時,16位加1計數器CNT一直在統(tǒng)計內部時鐘源fosc脈沖數,當捕獲信號EXS先后到來時,或上升沿或下降沿,依次順序觸發(fā),并記錄事件時刻的CNT計數值到捕獲寄存器CAPREG,通過相鄰兩次的捕獲值做差來獲得事件間隔的計數值,如圖1(b)中,在時刻tn-1和tn先后出現了捕獲事件ICPS,捕獲值分別是CapRegn-1和CapRegn,那么間隔計數值就等于CapRegn減去CapRegn-1。由于計數器統(tǒng)計的數字信號為固定周期信號,所以通過間隔計數值乘以信號周期Tosc,可計算獲得間隔時長。這種計數器因具有事件的及時捕獲記錄和時長檢測功能,在數字傳感和數字控制等嵌入式應用系統(tǒng)中被廣泛使用,以滿足各種對時間間隔的測量需求[10]。
(a)計數器捕獲結構
(b)捕獲測時原理圖1 計數器捕獲測量原理
計數器的捕獲測時功能是在捕獲事件的中斷服務程序中通過計算捕獲計數值Yn和間隔時長Δtn完成的,具體見式(1)和式(2)。
Yn=Cn×65 536+CapRegn
(1)
Δtn=(Yn-Yn-1)×Tosc
(2)
式中:Yn為捕獲計數值;Δtn為間隔時長;Tosc為時鐘周期;Cn為軟件計數器。
由于16位計數器的間隔計數值最大為65 536,最大的間隔時長為65 536×Tosc。所以,增設軟件計數器就能計算超出1個計數器周期的時間間隔,如圖1(b)中時刻tn+1和tn間的時長。為了滿足長時測量需求,采用中斷的軟件接力方法是實現軟件擴展位數的常用做法,即通過軟件計數器Cn對硬件計數器溢出次數的統(tǒng)計來完成計數位數的擴展,常用于嵌入式微控制器系統(tǒng)中。
軟件接力方法需要通過計數器的溢出事件來完成,時長捕獲計算需要捕獲事件來完成的。溢出事件負責處理軟件計數器加1功能,捕獲事件負責處理捕獲計數值和時長計算。由圖2模型知,兩事件的中斷服務程序都對Cn計數器進行了操作:溢出事件對Cn寫操作,捕獲事件對Cn讀操作,出現了Cn計數器被兩中斷服務程序共享的新情況。根據操作系統(tǒng)原理,該共享協(xié)作問題可以看成經典的兩線程讀-寫者同步問題[11],需要通過正確的互斥方法和協(xié)作方法來解決同步讀寫問題,僅靠中斷機制是不能解決的。
圖2 捕獲測量的讀-寫者模型
否則,若Cn對共享變量處理不當,數據計算結果Yn往往隨機性的出現65 536的錯誤問題,時長Δtn也相應會出現差整數倍計數器周期時長錯誤。如先讀取Cn并完成結果計算,后Cn++,可能帶來少計算1次65 536;若先寫Cn++,后進行讀取和結果計算,則可能帶來多計算1次65 536。
該數據安全問題是與中斷系統(tǒng)響應中斷的順序密切相關的。因為中斷系統(tǒng)只會提交級別最高的中斷源給CPU進行處理。但事實上,受指令延時和嵌套延時造成的CPU不能及時響應中斷,使得實際響應情況變得復雜。如兩中斷事件不同時刻到來,但是仍然可能因為響應延時(程序嵌套或指令周期)被中斷系統(tǒng)視為同時到來的。再如即使同時到來,系統(tǒng)仍然按照預先設定的中斷次序進行響應,造成響應順序出錯,如圖3所示。計數器溢出TF事件優(yōu)先級高于捕獲EXF事件優(yōu)先級,不論TF和EXF中斷發(fā)生的先后時間情況如何,因為響應延時,致使中斷控制器判優(yōu)時發(fā)現兩者都進行了中斷請求,于是根據判優(yōu)規(guī)則,總是把高優(yōu)先級的TF事件提交給CPU來先處理。事實上,當EXF事件先于TF事件發(fā)生時,CPU將先錯誤選擇執(zhí)行(SW=0)TF溢出服務程序計算Cn,后再執(zhí)行(SW=1)EXF捕獲服務程序計算捕獲結果Yn和Δtn。由于執(zhí)行順序出現錯誤,導致本次Yn計算結果多計算出65 536的計數錯誤,從而造成Δtn多計算出1個計數器周期時長錯誤。可見,中斷系統(tǒng)難以解決這種協(xié)作問題。
圖3 中斷控制器結構原理
對于被視為同時到來的情況具體存在3種情況。第一,捕獲事件先于溢出事件,但由于指令或嵌套延時,當CPU發(fā)出INTA信號回應中斷請求信號INTR時,存在2個事件同時出現的狀態(tài),即被視為同時到來。第二,捕獲事件滯后于溢出事件,但由于指令或嵌套延時,同樣被視為同時到來。第三,捕獲事件和溢出事件真正意義上的同時到來。這3種情況和單獨到來的情況交織在一起,隨機出現,僅靠中斷系統(tǒng)難以辨認。由于這3種情況存在兩事件復雜的仲裁競爭關系,為了和普通單個事件響應進行區(qū)分,把這種被視為同時到來事件的計數器狀態(tài)稱作競爭態(tài),把上述3種情況分別稱作超前競爭態(tài)(如圖4中①),滯后競爭態(tài)(如圖4中③)和同時競爭態(tài)(如圖4中②)。把單獨事件的非同時到來情況稱作常態(tài)(如圖4中④)。
圖4 計數器工作態(tài)
判明競爭態(tài)類型是解決問題的關鍵。為了獲得3種競爭態(tài)區(qū)別特征,把計數器工作時序從邊界0和65 535處切開成小段時序,對齊相應邊界平鋪層疊到二維平面上以便觀察,然后在圖中用點標注出競爭態(tài)發(fā)生時捕獲寄存器值,不需要標注出常態(tài)下捕獲事件發(fā)生時捕獲寄存器值,如圖5所示。計數區(qū)間具有較為明顯的數據聚合分布特征。對于超前競爭態(tài),捕獲寄存器值小于等于65 535,且靠近于65 535值一側分布,分布在超前區(qū)間[x2,65 535];對于滯后競爭態(tài),捕獲寄存器值大于0,且靠近于0值一側分布,分布在滯后區(qū)間(0,x1];對于同時競爭態(tài),捕獲寄存器值為0,位于0點上。若考慮程序搶占嵌套,那么發(fā)生計數器溢出事件時,由于CPU被高優(yōu)先級程序搶占,導致溢出中斷響應在指令延時的基礎上再推遲一個嵌套延時時長,從而滯后區(qū)向高位擴展,x1變大。若考慮程序搶占嵌套,那么發(fā)生捕獲事件時,由于CPU被高優(yōu)先級程序搶占,導致捕獲中斷響應在指令延時的基礎上再推遲一個嵌套延時時長,則超前區(qū)向低位擴展,x2變小。嵌套延時的存在,使得超前競爭態(tài)的捕獲值和滯后競爭態(tài)的捕獲值有趨于中間值的趨勢。事實上,基于嵌套和指令隨機發(fā)生概率的均等原則,兩側嵌套延時和指令延時寬度均可取一致,那么有x1=x2。同時,考慮嵌套程序的延時最大化,取x1=x2=計數上限/2,對整個計數區(qū)間進行二分類。如16位計數器,取x1=x2=216/2=32 768作為閥值來劃分整個計數區(qū)間,如圖5所示。從而,計數器工作態(tài)的具體判別方法用決策樹表示如圖6所示。
圖5 競爭態(tài)捕獲值分布圖
圖6 計數器工作態(tài)決策樹
捕獲測時處理的基本原則和要求是:先發(fā)生的事件,CPU對其先處理;同時發(fā)生的事件,CPU先處理溢出事件,后再處理捕獲事件。對于競爭態(tài),協(xié)作順序應按照如圖7(a)~圖7(c)所示進行處理。如圖7(a)所示發(fā)生了超前態(tài),說明捕獲事件先于計數器溢出事件發(fā)生,則先處理捕獲事件(計算結果yn和Δtn),再處理溢出事件(軟件計數器Cn自加1);如圖7(b)所示發(fā)生了滯后態(tài),說明捕獲事件滯后于計數器溢出事件發(fā)生,則先處理溢出事件,再處理捕獲事件;如圖7(c)所示發(fā)生了同時態(tài),則先處理溢出事件,再處理捕獲事件。按照正確流程進行順序處理,實質上是對共享的軟件計數器進行正確讀寫訪問,這樣捕獲時長計算結果才能正確。
圖7 同步協(xié)作要求
利用RTOS實時操作系統(tǒng)的事件驅動方法將有助于安全方便地設計任務間同步和互斥,可以有效地利用操作系統(tǒng)對事件的支持解決多任務同步和管理多任務的需求。為了實現事件任務同步要求,設計了如圖8所示的任務交互協(xié)作圖。
圖8 任務交互協(xié)作圖
系統(tǒng)建立了3個任務:識別任務CheckT,捕獲任務ICT和溢出任務OVT。識別任務用于狀態(tài)檢測,捕獲任務用于實現捕獲結果計算,而溢出任務用于軟件計數器功能。當任一中斷事件到來,先在中斷服務程序中保存寄存器CapReg和IntReg數據,并發(fā)送事件Event BIT_0給識別任務CheckT;識別任務然后檢測狀態(tài),生成狀態(tài)識別碼,再同時發(fā)送事件Event BIT_1和Event BIT_2;捕獲任務和溢出任務根據狀態(tài)識別碼,再做出合理的執(zhí)行順序。狀態(tài)識別碼共4種,分別為:常態(tài)0,超前競爭態(tài)1,滯后競爭態(tài)2,同時競爭態(tài)3。具體執(zhí)行順序是按照圖7的同步要求進行設計的。如若當前態(tài)為超前競爭態(tài)1時,溢出任務OVT轉入等待狀態(tài),捕獲任務ICT轉入就緒運行態(tài),當捕獲任務執(zhí)行完后,發(fā)送事件Event BIT_3給溢出任務,溢出任務退出等待繼續(xù)執(zhí)行,實現同步和協(xié)作。
實驗是在符合CMSIS軟件接口標準架構系統(tǒng)[12]上,通過單芯片STM32(ARM Cortex-M3核心)硬件基礎上搭載有開源實時操作系統(tǒng)FreeRTOS和用于系統(tǒng)運行參數采集工具Tracealyzer。軟件方面,用戶只須在配置文件中設置就能完成對FreeRTOS操作系統(tǒng)和Tracealyzer分析儀的自定義移植[13-14]。硬件方面,采用計數器TIM3的捕獲通道CH1(PA6引腳)作為EXS輸入端,上升沿捕獲,TCLK設定70 MHz,使能計數器溢出中斷和捕獲中斷。通過Tracealyzer軟件工具,完成對“3.3 V,1 kHz”的方波信號進行實時捕獲采集,并進行定性和定量分析。
加載數據到上位機的Tracealyzer應用軟件中,通過可視化時序分析功能,調整視窗尺寸,可觀察到圖9(a)~圖9(d)所示的4種捕獲時序。根據圖8和圖9知,當計數器中斷事件到來時,中斷服務程序先通過Tmr_SVC定時器守護進程把事件先發(fā)給識別任務CheckT進行狀態(tài)識別,之后根據識別碼給捕獲任務ICT和就緒溢出任務OVT發(fā)送同步事件信號。如圖9(a)超前態(tài)時序圖所示,雖然溢出任務OVT先獲得運行,但是在執(zhí)行時序中要求先執(zhí)行捕獲任務,于是出現了捕獲任務ICT得到運行后,再次投入運行,從而完整地完成正確的執(zhí)行時序。如圖9(b)滯后態(tài)和同時態(tài)時序圖所示,時序順序是按照執(zhí)行時序要求進行的,即先執(zhí)行溢出任務OVT,后再執(zhí)行捕獲任務ICT,也完成了正確的執(zhí)行時序。對于常態(tài)而言,由于不存在任務間的競爭協(xié)作,只有單個ICT任務執(zhí)行,時序也是正常的。
圖9 捕獲時序圖
編寫程序,對1 kHz的高精度信號進行上升沿捕獲測周期,分別采用傳統(tǒng)方法和新方法統(tǒng)計常態(tài)和各個競爭態(tài)出現時刻的前一捕獲點(B)、當前捕獲點(C)和后一捕獲點(N)的數據,包括捕獲寄存器值CapReg、軟件計數器Cn和工作狀態(tài)。從中抽取12組代表性數據,并以十六進制數表示,具體如表1所示。根據數據和式(1)分別計算新方法和傳統(tǒng)方法的數據,包括捕獲計數Yn,周期計數值和計數誤差,其中周期計數值為相鄰2次的捕獲計數Yn的差值,計數誤差=周期計數值-標準值。標準值為70 000D=1 1170H,是1 kHz信號在70 MHz的參考時鐘下的周期理想計數值。周期計數值是1 kHz信號在70 MHz的參考時鐘下的周期實際計數值。通過計數誤差值比對知,常態(tài)下,傳統(tǒng)方法和新方法都存在計數誤差為±1,是正常的計數誤差,實際上捕獲輸入的時鐘同步也會產生計數誤差。競爭態(tài)下,傳統(tǒng)方法的6組數據,包括軟件計數器Cn、捕獲計數Yn、周期計數值和計數誤差均出現了明顯的變化,而新方法的計數誤差在允許的范圍內,數據均正常。其中,超前態(tài)下,對比新方法,傳統(tǒng)方法的軟件計數器Cn增加了1,周期計數值和計數誤差均增加了65 536,而Next捕獲點周期計數值減少了65 536,計數誤差變?yōu)?65 536;而滯后態(tài)下,相比新方法,傳統(tǒng)方法的軟件計數器減少了1,周期計數值和計數誤差均減少65 536,計數誤差變?yōu)?65 536,而Next捕獲點周期計數值和計數誤差均增加了65 536;同時態(tài)下,對比新方法,傳統(tǒng)方法的軟件計數器Cn減少了1,周期計數值和計數誤差均減少65 536,而后一捕獲點周期計數值和計數誤差均增加了65 536。
表1 捕獲測周期實驗數據表
通過比較分析,傳統(tǒng)方法在常態(tài)下捕獲結果是正確的,但是在競爭態(tài)時會出現65 536的周期計數值結果錯誤,原因是因為在競爭態(tài)時傳統(tǒng)方法存在軟件計數器Cn數據更新錯誤,從而導致周期計數值以及被測信號周期都出現錯誤的問題。采用新方法后,發(fā)現新方法的周期計數值與新方法常態(tài)以及傳統(tǒng)方法常態(tài)均一致,說明新方法,不論計數器工作在何種工作狀態(tài)時,由于采用了協(xié)作機制和同步方法,軟件計數器Cn和捕獲計數Yn每次都能得到正確的結果,所以后期的周期計數值和信號周期均能得到正確的捕獲結果。
實驗證明了提出計數器在捕獲測量時間間隔時存在2類4種工作態(tài)是正確可行的,并結合創(chuàng)新性的工作狀態(tài)檢測和基于RTOS的任務事件同步法,有效地完成計數器溢出事件和捕獲事件的協(xié)作處理,得到了正確可靠的測量數據和捕獲時長,使之在時長捕獲或中低頻信號數據捕獲上有了安全保證。傳統(tǒng)方法是僅通過中斷系統(tǒng)機制來進行捕獲測量的,忽略了競爭態(tài)的存在,難免出現傳統(tǒng)捕獲測時帶來的數據錯誤隱患。同時,由于采用RTOS系統(tǒng),使得該方法做到與硬件中斷類型無關,可統(tǒng)一按照共享中斷向量來處理,極大地簡化了程序設計的難度和增強了移植性。另外,本方法提供了一種單芯片低成本片上系統(tǒng)方案,可方便移植到多種基于MCU或SOPC的嵌入式系統(tǒng)中,具有一定的普適性。