日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

中断处理

發(fā)布時(shí)間:2023/12/20 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 中断处理 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

首先在獲得PCI配置空間資源的時(shí)候,就要獲得中斷資源,根據(jù)CM_PARTIAL_RESOURCE_DESCRIPTOR 結(jié)構(gòu)的 Type 域來區(qū)分需要獲得什么樣的中斷資源的時(shí)候,如果Type類型為:CmResourceTypeInterrupt,此時(shí)需要將中斷資源從CM_PARTIAL_RESOURCE_DESCRIPTOR中取出:

irql = (KIRQL) resource->u.Interrupt.Level;????????????? //中斷級(jí)別

??????????????????????????? vector = resource->u.Interrupt.Vector;???????????????????? // 中斷向量

??????????????????????????? affinity = resource->u.Interrupt.Affinity;

??????????????????????????? mode = (resource->Flags == CM_RESOURCE_INTERRUPT_LATCHED)

???????????????????????????????????? ? Latched : LevelSensitive;

??????????????????????????? irqshare = resource->ShareDisposition == CmResourceShareShared;

??????????????????????????? gotinterrupt = TRUE;

?

獲取以上這些信心之后我們就可以注冊(cè)中斷,通過IoConnectInterrupt()函數(shù)來實(shí)現(xiàn):

函數(shù)定義如下:

IoConnectInterrupt

OUT PKINTERRUPT *InterruptObject,//指向驅(qū)動(dòng)程序提供的中斷對(duì)象存儲(chǔ)地址,該參數(shù)隨后

//要傳遞給KeSynchronizeExecution。

OUT PKSERVICE_ROUTINE ServiceRoutine,//中斷服務(wù)例程的入口

IN PVOID ServiceContext,//指向驅(qū)動(dòng)指定的即將傳遞給ISR的參數(shù),ServiceContext必須在

//常駐內(nèi)存中,可以是驅(qū)動(dòng)程序創(chuàng)建的設(shè)備驅(qū)動(dòng)的設(shè)備擴(kuò)展,也可

//以是驅(qū)動(dòng)創(chuàng)建的控制對(duì)象的控制拓展,還可以是設(shè)備驅(qū)動(dòng)分配的

//非分頁(yè)內(nèi)存。

IN PKSPIN_LOCK SpinLock OPTIONAL,//指向已經(jīng)初始化的自旋所,驅(qū)動(dòng)程序負(fù)責(zé)自旋所的存

//儲(chǔ),并且該自旋所將用來同步被驅(qū)動(dòng)程序其它例程共

//享的數(shù)據(jù)的訪問,該參數(shù)在ISR處理多個(gè)中斷向量或

//者驅(qū)動(dòng)程序包含不止一個(gè)ISR時(shí)需要設(shè)置,否則,驅(qū)

//動(dòng)程序不需要為中斷自旋所分配存儲(chǔ)空間,參數(shù)設(shè)置

//為NULL。

IN ULONG Vector,??????????????? //輸入獲取的中斷向量

IN KIRQL Irql,??????????????????? //輸入獲取的中斷優(yōu)先級(jí)DIRQL

IN KIRQL SynchronizeIrql,???????? //指明ISR執(zhí)行所在的DIRQL,當(dāng)ISR需要處理多個(gè)中斷

//向量或者驅(qū)動(dòng)程序有多個(gè)ISR的時(shí)候,該值選擇全部中

//斷資源的u.Interrupt.Level中的最高值,否則和上面的

//Irql變量相等。

IN KINTERRUPT_MODE InterruptMode,//電平觸發(fā)或者邊沿觸發(fā)

IN BOOLEAN ShareVector,?????????? //指明中斷向量是否是可共享的。

IN KAFFINITY ProcessorEnableMask,//指定一個(gè)KAFFINITY值,用來說明設(shè)備中斷可以在什

//么樣的處理器平臺(tái)上發(fā)生。

IN BOOLEAN FloatingSave???????? ?//指明是否需要保存設(shè)備中斷時(shí)的浮點(diǎn)堆棧,在X86平

//臺(tái)下,該值必須是FALSE。

);

實(shí)際使用時(shí):

status = IoConnectInterrupt(&pdx->InterruptObject, (PKSERVICE_ROUTINE) ISRInterrupt,

?????????????????? (PVOID) pdx, NULL, vector, irql, irql, mode, irqshare, affinity, FALSE);

第二個(gè)參數(shù)為我們自定義的中斷服務(wù)例程,當(dāng)驅(qū)動(dòng)通過這個(gè)函數(shù)接收中斷,之后調(diào)用相應(yīng)的DPC(deferred procedure calls,延遲過程調(diào)用)處理函數(shù),DPC的使用主要是為了提高處理效率。但是首先要注冊(cè)DPC處理函數(shù),通過:

VOID KeInitializeDpc(

? __out???? PRKDPC Dpc,

? __in????? PKDEFERRED_ROUTINE DeferredRoutine,

? __in_opt? PVOID DeferredContext

);

來實(shí)現(xiàn)注冊(cè)DPC處理函數(shù)。

實(shí)際應(yīng)用:

KeInitializeDpc(&pdx->fdo->Dpc,DPCForISR,NULL);

?

BOOLEAN ISRInterrupt(PKINTERRUPT InterruptObject, PDEVICE_EXTENSION pdx)

{???????????????????????????????????????????????????????????????

???????? //中斷響應(yīng),通知硬件該中斷已經(jīng)處理,不用再發(fā)該中斷

???????? WRITE_REGISTER_ULONG((PULONG) &pdx->pHBARegs->IntrMask,0x00000001);

???????? pdx->inthw_cnt++;

???????? KeInsertQueueDpc(&pdx->fdo->Dpc,pdx->fdo,pdx->fdo->CurrentIrp );

???????? return TRUE;

}

在該函數(shù)中,將中斷請(qǐng)求插入到中斷處理隊(duì)列中,交由DPC來處理

BOOLEAN KeInsertQueueDpc(

? __inout?? PRKDPC Dpc,

? __in_opt? PVOID SystemArgument1,

? __in_opt? PVOID SystemArgument2

);

?

DPC的標(biāo)準(zhǔn)格式為:

KDEFERRED_ROUTINE CustomDpc;

?

VOID CustomDpc(

? __in????? struct _KDPC *Dpc,

? __in_opt? PVOID DeferredContext,

? __in_opt? PVOID SystemArgument1,

? __in_opt? PVOID SystemArgument2

)

{ ... }

其中參數(shù)(注意來源):

Dpc [in]

Caller-supplied pointer to a KDPC structure, which represents the DPC object that is associated with this CustomDpc routine.

DeferredContext [in, optional]

Caller-supplied pointer to driver-defined context information that was specified in a previous call to KeInitializeDpc.

SystemArgument1 [in, optional]

Caller-supplied pointer to driver-supplied information that was specified in a previous call to KeInsertQueueDpc.

SystemArgument2 [in, optional]

Caller-supplied pointer to driver-supplied information that was specified in a previous call to KeInsertQueueDpc.

?

?

?

這里DPC可以這樣設(shè)計(jì):

VOID DPCForISR(IN PKDPC Dpc,IN PVOID Context,IN? PVOID fdo,IN PVOID pIrp)

{

???????? PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)

((PDEVICE_OBJECT)fdo)->DeviceExtension;

????????

???????? KeAcquireSpinLock(&pdx->spinLock,&pdx->oldIrql);

//Int_stat 寄存器由硬件填寫的

???????? int_status = READ_REGISTER_ULONG((PULONG) &pdx->pHBARegs->Int_stat);

???????? KdPrint(("interrupt!int status is 0x%0x\n",int_status));

???????? while(int_status) //循環(huán)處理中斷,直到處理完

???????? {

??????????????????

?????????????????? if(int_status >= INT_RECV_0 && int_status <= INT_RECV_23)

?????????????????? {

??????????????????????????? RecvTask(pdx,int_status-1);

??????????????????????????? pdx->recint_cnt[int_status-1]++;

?????????????????? }

?????????????????? if(int_status >= INT_LINK0_BUILD && int_status <= INT_LINK3_BUILD)

?????????????????? {

??????????????????????????? pdx->rx_fc_desc_buf_virt[int_status-25]->link_state=1;

??????????????????????????? pdx->bldint_cnt[int_status-25]++;

??????????????????????????? KdPrint(("Build!int status is 0x%0x\n",int_status));

?????????????????? }

??????????????????

?????????????????? if(int_status >= INT_LINK0_BREAK && int_status <= INT_LINK3_BREAK)

?????????????????? {

??????????????????????????? pdx->rx_fc_desc_buf_virt[int_status-29]->link_state=0;

??????????????????????????? pdx->brkint_cnt[int_status-29]++;

?????????????????? }

?????????????????? pdx->intsw_cnt++;

?????????????????? int_status = READ_REGISTER_ULONG((PULONG) &pdx->pHBARegs->Int_stat);

?????????????????? KdPrint(("interrupt!int status is 0x%0x\n",int_status));

???????? }

????????

???????? return ;?????????????

}

在DPC中完成具體的操作,這樣中斷處理就結(jié)束了。

?

轉(zhuǎn)載于:https://www.cnblogs.com/zhuyp1015/archive/2012/03/14/2396630.html

總結(jié)

以上是生活随笔為你收集整理的中断处理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。