<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>
"); //-->

博客專(zhuān)欄

EEPW首頁(yè) > 博客 > PCIe接口驅動(dòng) 中斷寄存器被覆蓋問(wèn)題的發(fā)現與解決

PCIe接口驅動(dòng) 中斷寄存器被覆蓋問(wèn)題的發(fā)現與解決

發(fā)布人:FPGA小師兄 時(shí)間:2023-01-16 來(lái)源:工程師 發(fā)布文章

最近調試Windows平臺下的PCIe網(wǎng)絡(luò )驅動(dòng)程序時(shí),發(fā)現了中斷不被處理的情況,懷疑中斷丟失。隨后在調試過(guò)程中將問(wèn)題定位在如下兩個(gè)方面。

DMA寫(xiě)重復啟動(dòng)

我們在Windows下使用WDF框架開(kāi)發(fā)PCIe驅動(dòng)的DMA讀寫(xiě)功能。驅動(dòng)要啟動(dòng)一次DMA傳輸包括兩個(gè)步驟

  • 初始化DMA傳輸對象

  • 執行DMA傳輸

初始化DMA傳輸對象時(shí),應將本次DMA要傳輸的數據緩沖區的地址和長(cháng)度寫(xiě)入該對象,并向其注冊用于配置并啟動(dòng)DMA傳輸的回調函數PCIeEvtProgramWriteDma。該回調函數會(huì )獲取緩沖區地址和長(cháng)度,通過(guò)PIO方式配置PCIe Bar空間上的寄存器,以通知硬件啟動(dòng)DMA傳輸。

執行DMA傳輸時(shí),驅動(dòng)僅需調用WDF框架的WdfDmaTransactionExecute函數,操作系統就會(huì )調用上一步注冊的回調函數對硬件進(jìn)行配置并啟動(dòng)DMA傳輸。

正常來(lái)講,驅動(dòng)調用一次WdfDmaTransactionExecute函數,相應地操作系統應調用一次回調函數進(jìn)行硬件配置。但我們更換硬件平臺(CPU+FPGA)后,DMA寫(xiě)流程出現了嚴重問(wèn)題,具體表現為:前者的一次調用可能會(huì )對應著(zhù)后者的多次調用,且每次回調函數都會(huì )完整執行并觸發(fā)DMA寫(xiě)完成中斷,從而造成了驅動(dòng)的中斷狀態(tài)機被打亂,直接表現是后續的DMA寫(xiě)開(kāi)始中斷丟失,無(wú)法正常啟動(dòng)DMA寫(xiě)。

如下,圖1是驅動(dòng)調用WdfDmaTransactionExecute函數的次數與操作系統調用回調函數的次數不一致的截圖。

圖1 DebugMonito監測

其中,5658(5576+82+0)為驅動(dòng)調用WdfDmaTransactionExecute函數的次數,5664為操作系統調用回調函數的次數。二者之間差6就是操作系統重復調用的次數。

我們嘗試將操作系統多出來(lái)的調用回調函數的次數跳過(guò),即僅保留第一次調用。硬件側可以正常完成這次DMA傳輸,并觸發(fā)DMA寫(xiě)完成中斷。但驅動(dòng)去查詢(xún)DMA傳輸對象時(shí),發(fā)現此次DMA傳輸并未處于完成狀態(tài),即無(wú)法正常接收數據。至此,我們猜測,操作系統多次調用回調函數的原因是其認為配置過(guò)程出錯才重新進(jìn)行配置,直至最后一次成功。而硬件側并不會(huì )感知到這種錯誤,每次都正常啟動(dòng)DMA寫(xiě)并觸發(fā)DMA寫(xiě)完成中斷,導致驅動(dòng)的中斷狀態(tài)機跑飛。

問(wèn)題排查到這里,我們無(wú)法深入到閉源的Windows操作系統內部去探究錯誤原因了。所以思路一轉,我們嘗試能否為中斷狀態(tài)機提供一些保障機制。

驅動(dòng)的中斷狀態(tài)機

為了方便調試,我們在中斷處理程序中添加了許多關(guān)鍵的調試日志信息,結果在其中發(fā)現了端倪。

圖2 日志打印記錄

觀(guān)察圖2中的日志,發(fā)現兩個(gè)中斷延遲處理函數MPHandleInterrupt在并行執行。在這個(gè)過(guò)程中,用于臨時(shí)拷貝中斷寄存的變量Adapter->IsrCode_dpc被覆蓋重寫(xiě)。覆蓋的直接后果是,前者已讀取到的寄存的中斷,后者覆蓋后就無(wú)法由中斷延遲處理程序進(jìn)行處理。

這種現象顯然是不合理的。為了解決這個(gè)問(wèn)題,我們?yōu)镸PHandleInterrupt函數內部加鎖,防止MPHandleInterrupt并行執行。通過(guò)這種方式,中斷寄存被覆蓋的現象不再發(fā)生。

全文完。


*博客內容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀(guān)點(diǎn),如有侵權請聯(lián)系工作人員刪除。

高通濾波器相關(guān)文章:高通濾波器原理


關(guān)鍵詞: PCIe接口 中斷寄存器

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>