博客專(zhuān)欄

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

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

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

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

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

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

  • 初始化DMA傳輸對(duì)象

  • 執(zhí)行DMA傳輸

初始化DMA傳輸對(duì)象時(shí),應(yīng)將本次DMA要傳輸?shù)臄?shù)據(jù)緩沖區(qū)的地址和長(zhǎng)度寫(xiě)入該對(duì)象,并向其注冊(cè)用于配置并啟動(dòng)DMA傳輸?shù)幕卣{(diào)函數(shù)PCIeEvtProgramWriteDma。該回調(diào)函數(shù)會(huì)獲取緩沖區(qū)地址和長(zhǎng)度,通過(guò)PIO方式配置PCIe Bar空間上的寄存器,以通知硬件啟動(dòng)DMA傳輸。

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

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

如下,圖1是驅(qū)動(dòng)調(diào)用WdfDmaTransactionExecute函數(shù)的次數(shù)與操作系統(tǒng)調(diào)用回調(diào)函數(shù)的次數(shù)不一致的截圖。

圖1 DebugMonito監(jiān)測(cè)

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

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

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

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

為了方便調(diào)試,我們?cè)谥袛嗵幚沓绦蛑刑砑恿嗽S多關(guān)鍵的調(diào)試日志信息,結(jié)果在其中發(fā)現(xiàn)了端倪。

圖2 日志打印記錄

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

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

全文完。


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

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


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

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

關(guān)閉