WinCE OAL中的中斷處理

2021-06-14 23:42:50 字數 4503 閱讀 8578

這張圖想必很多人都見過,主要這張圖太經典了,所以還是貼出來嘮叨幾句,硬體中斷產生以後,會導致核心isr的執行,然後由oal中的isr來處理相應的中斷,最後導致相對應的ist執行完成真正的中斷處理。所以在wince中,中斷處理由isr和ist共同完成。isr主要完成中斷源的確定,遮蔽該中斷並返回給核心相對應的系統中斷號,isr應該盡量短小。ist則是完成真正的中斷處理,比如資料的傳輸和解析等。當然不是所有的中斷處理都需要isr和ist,看需要,比如wince的系統timer中斷就只需要isr完成。

在oal中支援中斷,需要實現以下幾個中斷處理函式:

1. bool oeminterruptenable(dword sysintr, void* pdata, dword datasize)

sysintr:要被使能的系統中斷號

pdata:傳入的資料指標,該資料由interruptinitialize函式傳入

datasize:傳入資料的大小

該函式用於使能某乙個硬體中斷。在裝置驅動呼叫interruptinitialize來初始化乙個中斷的時候,核心就會呼叫該函式來使能相應的硬體中斷。

2. void oeminterruptdisable(dword sysintr)

sysintr:要被遮蔽的系統中斷號

該函式用於遮蔽乙個硬體中斷。如果裝置驅動呼叫interruptdisable函式,則該函式會被呼叫。

3. void oeminterruptdone(dword sysintr)

sysintr:要被重新使能的系統中斷號

該函式標誌著乙個中斷處理過程的完成。當裝置驅動呼叫interruptdone函式的時候,該函式會被呼叫,重新使能相應的硬體中斷。

4. ulong oeminterrupthandler(ulong ra)

ra:指令計數,在實際應用中,沒有太大意義

當硬體中斷產生的時候,該函式就會被呼叫完成isr部分的中斷處理。一般會在該函式中讀取系統的中斷標記位,確定中斷源並返回相應的系統中斷號。

5. void oeminterrupthandlerfiq(void)

針對於arm處理器,該函式用於處理快速中斷。

上面5個函式完成了中斷的相關處理。這裡要提到兩個概念:irqsysintr。irq是指物理中斷或者叫硬體中斷,而sysintr指的是系統中斷,也有的地方稱為虛擬中斷或者邏輯中斷,我個人覺得還是叫系統中斷比較好。每乙個irq會和乙個系統中斷sysintr相對應,當硬體中斷產生時,isr實際上是處理irq中斷,然後返回相應的系統中斷sysintr給核心,核心會根據相應的sysintr觸發相應的ist來完成中斷處理。

irq和sysintr之間的對應關係稱為對映,分為靜態對映和動態對映。靜態對映是指在系統編譯時irq已經和sysintr相對應,一般通過oalintrstatictranslate函式來實現。而動態對映是指wince系統啟動後,動態關聯irq與sysintr,一般通過kerneliocontrol(ioctl_hal_request_sysintr…)來實現。

sysintr的型別在nkintr.h中定義,oeminterrupthandler函式在處理完中斷以後,會返回不同型別的sysintr給核心,核心會根據返回值進行下一步操作,分為以下幾種型別:

sysintr_nop:表示不需要進行任何處理

sysintr_resched:表示要進行一次系統排程

sysintr_rtc_alarm:表示rtc報警產生

sysintr_timing:用於iltiming測試

sysintr_profile:用於系統的profile

sysintr_firmware

:用於使用者自定義系統中斷號,所有自定義的系統中斷號都應該基於該值進行累加加1,這些自定義的系統中斷號用於和irq一一對應。

在以前,如果要實現oal中的中斷部分,我們需要自己建立乙個irq表和乙個sysintr表,然後實現前面提到的5個函式,還要實現乙個interruptinitialize的函式,該函式用於初始化中斷,會在oeminit中被呼叫,就完事了。自從wince5.0以後,微軟提出了pqoal架構,中斷的實現變得「曲折」了。要實現的函式如下:

1. bool oalintrinit()

該函式為中斷初始化函式,會在oeminit中被呼叫,用於初始化系統的中斷,以及完成一些中斷的靜態對映。

2. bool oalintrrequestirqs(device_location *pdevloc, uint32 *pcount, uint32 *pirqs)

pdevloc:乙個device_location結構指標,包含裝置資訊

pcount:作為輸入表示最大的irq數,作為輸出表示實際獲得的irq數

pirqs:指向乙個實際獲得的irq陣列

該函式用於通過裝置的實體地址來得到irq資訊,一般用於匯流排裝置。

3. bool oalintrenableirqs(uint32 count, const uint32 *pirqs)

count:要使能多少個irq

pirqs:要被使能的irq陣列

該函式用於使能irq中斷,該函式會被oeminterruptenable函式呼叫。

4. void oalintrdisableirqs(uint32 count, const uint32 *pirqs)

count:要禁用多少個irq

pirqs:要被禁用的irq陣列

該函式用於禁用irq中斷,該函式會被oeminterruptdisable函式呼叫。

5. void oalintrdoneirqs(uint32 count, const uint32 *pirqs)

count:要重新使能多少個irq

pirqs:要被重新使能的irq陣列

該函式用於重新使能irq中斷,會被oeminterruptdone函式呼叫。

除了上述5個函式以外,還要實現的乙個重要函式就是oeminterrupthandler了,這個函式前面介紹過,這裡不說了。實際上在wince5.0以後,在/platform/common/src/common/intr/base目錄下有個「map.c」檔案,該檔案實現了中斷的相關介面函式,實現了中斷的動態/靜態對映,還完成了sysintr與irq之間的轉換,我們只需要實現對硬體中斷的操作和初始化就可以了。

最後還有幾個函式要說一下,如下:

bspintrinit:被oalintrinit函式呼叫

bspintrenableirq:被oalintrenableirqs函式呼叫

bspintrdisableirq:被oalintrdisableirqs函式呼叫

bspintrdoneirq:被oalintrdoneirqs函式呼叫

bspintrrequestirqs:被oalintrrequestirqs函式呼叫

這些函式可以被稱為板級中斷處理函式,總感覺這些函式有點多餘,一般實現了oalintrinit,oalintrenableirqs,oalintrdisableirqs,oalintrdoneirqs和oalintrrequestirqs就可以了,但這是基於處理器級的實現,對於基於同一處理器的不同的板子可能中斷要做一些修改,這些修改就可以在bspintrinit,bspintrenableirq,bspintrdisableirq,bspintrdoneirq和bspintrrequestirqs裡面完成。

在這裡,oal中的中斷處理函式基本都介紹了。我想最好的理解方法就是看**了。一般在oal中只是做一些開關中斷和清中斷標記位的操作,真正的資料處理交給ist去做。但有的時候,有些特殊裝置的中斷會很頻繁,ist來不及響應,解決辦法就是在isr中將資料儲存在一塊記憶體中,然後根據需要,每隔多少個硬體中斷返回一次系統中斷,從而啟用ist將資料一次性讀走,這裡涉及乙個問題就是在isr和ist中共享資料,在config.bib中預留一塊共享記憶體就可以了。

WinCE OAL中的Memory函式介紹

在bsp開發中經常會用到實體地址與虛擬位址的轉換,一般都是基於實體地址獲得相應的虛擬位址來訪問硬體。在wince6.0中,可以在wince600 platform common src inc oal memory.h檔案中找到相關的操作函式,這些函式用來虛擬位址與實體地址之間的轉換,它們都是基於o...

WinCE OAL中的Memory函式介紹

在 bsp開發中經常會用到實體地址與虛擬位址的轉換,一般都是基於實體地址獲得相應的虛擬位址來訪問硬體。在 wince6.0 中,可以在 wince600 platform common src inc oal memory.h 檔案中找到相關的操作函式,這些函式用來虛擬位址與實體地址之間的轉換,它們...

WinCE OAL中的RAM定製函式

相關網帖 1 wince oal中的memory函式介紹 2 oemaddresstable介紹 在wince系統中,kernel是如何使用記憶體的,如何知道記憶體的大小?是通過config.bib檔案的描述,我們會在config.bib檔案中memory段定義wince核心所占用ram的起始位址和...