博客專欄

        EEPW首頁 > 博客 > PCIe接口驅動 中斷寄存器被覆蓋問題的發現與解決

        PCIe接口驅動 中斷寄存器被覆蓋問題的發現與解決

        發布人:FPGA小師兄 時間:2023-01-16 來源:工程師 發布文章

        最近調試Windows平臺下的PCIe網絡驅動程序時,發現了中斷不被處理的情況,懷疑中斷丟失。隨后在調試過程中將問題定位在如下兩個方面。

        DMA寫重復啟動

        我們在Windows下使用WDF框架開發PCIe驅動的DMA讀寫功能。驅動要啟動一次DMA傳輸包括兩個步驟

        • 初始化DMA傳輸對象

        • 執行DMA傳輸

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

        執行DMA傳輸時,驅動僅需調用WDF框架的WdfDmaTransactionExecute函數,操作系統就會調用上一步注冊的回調函數對硬件進行配置并啟動DMA傳輸。

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

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

        圖1 DebugMonito監測

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

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

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

        驅動的中斷狀態機

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

        圖2 日志打印記錄

        觀察圖2中的日志,發現兩個中斷延遲處理函數MPHandleInterrupt在并行執行。在這個過程中,用于臨時拷貝中斷寄存的變量Adapter->IsrCode_dpc被覆蓋重寫。覆蓋的直接后果是,前者已讀取到的寄存的中斷,后者覆蓋后就無法由中斷延遲處理程序進行處理。

        這種現象顯然是不合理的。為了解決這個問題,我們為MPHandleInterrupt函數內部加鎖,防止MPHandleInterrupt并行執行。通過這種方式,中斷寄存被覆蓋的現象不再發生。

        全文完。


        *博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。

        高通濾波器相關文章:高通濾波器原理



        技術專區

        關閉
        主站蜘蛛池模板: 弥勒县| 新巴尔虎右旗| 彰武县| 定南县| 潜江市| 张家港市| 邹平县| 大同市| 镇安县| 大邑县| 厦门市| 新龙县| 南康市| 嘉义市| 兴化市| 县级市| 左贡县| 额敏县| 库车县| 丰宁| 芦山县| 双峰县| 冷水江市| 江津市| 南康市| 布尔津县| 泾川县| 青河县| 伊宁市| 道孚县| 孝感市| 黎川县| 宽甸| 淮滨县| 专栏| 上林县| 大连市| 都江堰市| 汾阳市| 晋江市| 仁化县|