xdma_win驱动详解

1 Xdma Driver流程图(Interrupt mode)

xdma驱动分为三个部分,无限循环的超时检测线程,中断处理流程,处理ReadFile函数的系统调用。正常处理流程处理如下:

1、用户程序调用ReadFile函数

2、Kernel将调用Xdma DriverEvtIoRead函数来处理

3、驱动程序设置Descriptor,并设置Control寄存器使能xdma启动,同时RelaseSemaphore,唤醒超时检测线程

4、xdma处理完成之后,发送中断给CPU,CPU调用对应的中断处理函数,中断处理函数完成trasaction的处理,同时通知超时检测线程正常结束,并最终调用WdfRequestComplete,结束本次ReadFile的调用。

image

2 中断超时返回

如果在超时时间内,CPU没有收到中断,那么报time tout的错误。

image

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函数一直挂起。

image

image

3 Xdma的异常中断原因

通过分析驱动的代码以及驱动log,发现驱动在初始化的时候,会配置InterruptEnableMask,将其配置为0x00fffe3e,这会导致desc_error或者read_error等情况都会触发中断, 在驱动中加入日志之后,显示之前的异常中断都是READ_ERROR引起的。

Tags: xdma
Share: X (Twitter) Facebook LinkedIn