1 Xdma Driver
流程图(Interrupt mode
)
xdma驱动分为三个部分,无限循环的超时检测线程,中断处理流程,处理ReadFile函数的系统调用。正常处理流程处理如下:
1、用户程序调用ReadFile
函数
2、Kernel将调用Xdma Driver
的EvtIoRead
函数来处理
3、驱动程序设置Descriptor,并设置Control寄存器使能xdma启动,同时RelaseSemaphore,唤醒超时检测线程
4、xdma处理完成之后,发送中断给CPU,CPU调用对应的中断处理函数,中断处理函数完成trasaction的处理,同时通知超时检测线程正常结束,并最终调用WdfRequestComplete,结束本次ReadFile的调用。
2 中断超时返回
如果在超时时间内,CPU没有收到中断,那么报time tout的错误。
3 中断提前到达
如果中断提前到达,中断处理函数会读status的寄存器,此时寄存器XDMA_BUSY_BIT为1中断处理函数会提前结束传输,并报告win32 error code: 1359
的错误。
4 连续不断的中断引起了驱动地卡死
Xdma的中断异常,持续不断地发送中断给CPU,但是因为isReqPending为false,因此中断函数直接返回,但是当用户恰好请求一次xdma后,就会发生异常。
1、用户恰好开始一次Xdma的C2H请求,并设置Descriptor
2、CPU恰好收到一个中断信号
3-4、设置ReqPending=true
,且写寄存器使能Xdma
5、Release Semaphore
,但是由于Kernel处理中断繁忙,超时检测线程暂时没有被唤醒
6-9、由于ReqPending被设置,中断处理函数可以走到里面的流程,设置ReqPending=false
, 调用WdfRequestComplete,但是因为是Busy,所以报错。同时设置Evt。
10-11、此时超时检测线程才被唤醒,但是因为ReqPending=false
,所以直接返回,Evt没有被处理
12、当下一次Xdma的C2H请求开始的时候,但是此时中断已经没有发送了,但是因为上一次的Evt没有被处理,超时检测线程认为被Signal了,因此重新进入Wait状态。但是由于中断一直没有过来,导致ReadFile函数一直挂起。
3 Xdma的异常中断原因
通过分析驱动的代码以及驱动log,发现驱动在初始化的时候,会配置InterruptEnableMask
,将其配置为0x00fffe3e
,这会导致desc_error
或者read_error
等情况都会触发中断,
在驱动中加入日志之后,显示之前的异常中断都是READ_ERROR
引起的。