沁恒技術(shù)支持,請教關(guān)于CH365偽中斷頻率太高的問題

這個問題電話聯(lián)系過你們,但沒有回音,我這里詳細描述一下,望幫助分析原因:

現(xiàn)在PCI卡驅(qū)動程序里中斷為1.5ms,原來應(yīng)用程序直接偽中斷回調(diào)函數(shù),理論上也是1.5ms進入一次(偽中斷里需要讀寫數(shù)據(jù),而且不能太慢),試驗下來,在直接安裝的windows上運行都沒問題,不死機,但在ghost系統(tǒng)的機子上,某些機子也永遠不會死,但某些機子上必然死機,后來將偽中斷屏蔽掉(不設(shè)置偽中斷例程),只試驅(qū)動程序里的中斷,原來肯定死機的不會死機。 后來咨詢貴單位技術(shù)人員,認(rèn)為可能是偽中斷頻率太高,說是小于5ms容易死機,現(xiàn)在我將連接驅(qū)動程序和應(yīng)用程序的那個動態(tài)庫文件CH365DLL.DLL里處理中斷的線程進行處理,每成功讀取10次中斷才執(zhí)行一次偽中斷例程,這樣驅(qū)動程序?qū)嶋H中斷還是1.5ms,但偽中斷實際上是1.5*10=15ms執(zhí)行一次,但原來肯定死的機器上,有些機器還是出現(xiàn)死機情況,有時是出現(xiàn)藍屏,顯示IRQL_NOT_LESS_OR EQUAL,機器重裝系統(tǒng)了也沒用。 懇請貴公司技術(shù)人員分析一下可能的原因。 注明: 1、中斷預(yù)處理命令我一直是屏蔽掉的,包括驅(qū)動原代碼里中斷處理里for ( mByte = 0; mByte < 2; ++mByte ) { // 檢查兩個中斷命令緩沖區(qū),這一段代碼全部屏蔽了) 2、偽中斷里處理時間很短,遠遠小于1ms。

附代碼: 1、中間CH365DLL.DLL文件里中斷線程處理,原代碼經(jīng)過修改 ULONG WINAPI dllInterruptThread( // 中斷模擬線程,每個需要中斷功能的CH365設(shè)備都具有一個線程 LPVOID iParameter ) { HANDLE dllHandleOverlap; // CH365設(shè)備句柄,可以執(zhí)行重疊操作 HANDLE mEvent; BOOL mResult; ULONG mIndex, mLength; ULONG mInterruptCount;//中斷次數(shù)計數(shù):決定應(yīng)用程序級偽中斷的間隔時間(不能小于5ms,否則在某些計算機上容易死機) mWIN32_COMMAND mCommand; OVERLAPPED mOverlapped; mIndex = (ULONG)iParameter; // CH365設(shè)備序號 dllHandleOverlap = CreateFile( dllDeviceName[ mIndex ], GENERIC_READ | GENERIC_WRITE, // 打開設(shè)備,支持重疊操作 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL ); if ( dllHandleOverlap != INVALID_HANDLE_VALUE ) { // 打開設(shè)備成功 mEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); // 初始化完成事件 mInterruptCount=0;//初始化計數(shù) while ( dllIntRoutine[ mIndex ] ) { // 等待中斷直到取消 mLength = sizeof( mWIN32_COMMAND ); mCommand.mFunction = mFuncWaitInterrupt; // 等待中斷事件 mCommand.mAddress = NULL; mCommand.mLength = 0; mOverlapped.Internal = 0; mOverlapped.InternalHigh = 0; mOverlapped.Offset = 0; mOverlapped.OffsetHigh = 0; mOverlapped.hEvent = mEvent; ResetEvent( mEvent ); // 初始化完成事件 mResult = DeviceIoControl( dllHandleOverlap, IOCTL_CH365_COMMAND, &mCommand, mLength, &mCommand, mLength, &mLength, &mOverlapped ); if ( mResult == FALSE && GetLastError() == ERROR_IO_PENDING ) // 操作未完成,即暫時無中斷 mResult = GetOverlappedResult( dllHandleOverlap, &mOverlapped, &mLength, TRUE ); // 等待中斷 if ( mResult && dllIntRoutine[ mIndex ] ) { mInterruptCount++; if(mInterruptCount>=10)//本應(yīng)用驅(qū)動程序級中斷間隔時間1.5ms,則偽中斷間隔1.5*10=15ms { mInterruptCount=0; dllIntRoutine[ mIndex ](); // 發(fā)生中斷事件則調(diào)用中斷服務(wù)程序 } } if ( mResult == FALSE && dllIntRoutine[ mIndex ] ) Sleep( 5 ); // 出錯則延時5毫秒 } CloseHandle( mEvent ); CloseHandle( dllHandleOverlap ); // 關(guān)閉句柄 } dllIntThreadId[ mIndex ] = 0; ExitThread( 0 ); // 退出 return( 0 ); }

2、應(yīng)用程序CH365初始化(屏蔽了中斷預(yù)處理命令) void InitCH365() { UCHAR cByte;

//1) 先加載DLL if ( LoadLibrary( "CH365DLL.DLL" ) == NULL )//FreeLibrary { AfxMessageBox("加載CH365DLL.DLL失敗,可能未安裝到系統(tǒng)中,\r\n\r\n請重新安裝軟件!",16,0);// 加載DLL失敗,可能未安裝到系統(tǒng)中 exit(0); }

//2) 選擇打開CH365設(shè)備0,打開存儲器和中斷 Device_Number=0; if ( CH365mOpenDevice(Device_Number, TRUE, TRUE ) == INVALID_HANDLE_VALUE ) { AfxMessageBox("打開板卡設(shè)備失敗,\r\n\r\n請確認(rèn)板卡正確并連接可靠!",16,0); exit(0); }

//3) 通過DLL來調(diào)用版本號 //printf( "= %02X \n", CH365GetDrvVersion() );

//4) 通過DLL來調(diào)用系統(tǒng)自動分配的I/O基地址 if ( CH365mGetIoBaseAddr( Device_Number,&mIoBase ) == FALSE ) { AfxMessageBox("系統(tǒng)自動分配I/O基地址失敗,\r\n\r\n請重新安裝板卡驅(qū)動程序!",16,0); exit(0); }

//5) 通過DLL來調(diào)用系統(tǒng)自動分配的存儲器基地址 if (CH365mGetMemBaseAddr(Device_Number,&mMemBase) ==FALSE) { AfxMessageBox("系統(tǒng)自動分配Memory基地址失敗,\r\n\r\n請重新安裝板卡驅(qū)動程序!",16,0); exit(0); }

//6) 選擇A15作為SCL if ( CH365mReadIoByte(Device_Number,&mIoBase->mCh365IoCtrl,&cByte) == FALSE ) // 檢查A15的狀態(tài),因為當(dāng)A15為高電平時I2C不工作 { AfxMessageBox("檢查A15的狀態(tài)失敗,\r\n\r\n請重新安裝板卡驅(qū)動程序!",16,0); exit(0); } if ( cByte & 0x01 ) CH365mWriteIoByte(Device_Number,&mIoBase->mCh365IoCtrl,(UCHAR)(cByte & 0xFE)); // 設(shè)置A15=0,也可由數(shù)據(jù)線D0下拉電阻進行模式設(shè)置

if ( CH365mWriteIoByte(Device_Number,&mIoBase->mCh365I2cCtrl,0) == FALSE ) // 選擇A15作為SCL,默認(rèn)值 { AfxMessageBox("選擇SCL失敗,\r\n\r\n請重新安裝板卡驅(qū)動程序!",16,0); exit(0); } //CH365mWriteIoByte(Device_Number,&mBaseAddr->mCh365I2cCtrl,0x80); // 選擇SYS_EX作為SCL

//7) 自動檢測CH365所用的中斷號 if ( CH365mSetIntLine(Device_Number, mCH365_INT_LINE_AUTO ) == FALSE ) { AfxMessageBox("打開板卡中斷失敗,\r\n\r\n請重新安裝板卡驅(qū)動程序!",16,0); exit(0); }

//8) 調(diào)用中斷號 if ( CH365mGetIntLine(Device_Number, &mIntLine ) == FALSE ) { AfxMessageBox("系統(tǒng)調(diào)用板卡中斷號失敗,\r\n\r\n請重新安裝板卡驅(qū)動程序!",16,0); exit(0); }

//9) 中斷命令設(shè)定,CH365的WDM驅(qū)動程序中支持兩條中斷預(yù)處理命令 //通過使用CH365mWriteIntCommand( // 寫入中斷命令緩沖區(qū) // ULONG iIndex, // 指定CH365設(shè)備序號 // mPWIN32_COMMAND iCommand, // 指向作為中斷命令的命令結(jié)構(gòu) // ULONG iCmdIndex ) // 中斷命令序號,為1或者2 // 假定在系統(tǒng)響應(yīng)中斷時設(shè)定A0-A15的狀態(tài)為0x08000,可以撤消外部電路的中斷請求 if (mIntLine )// 已經(jīng)啟用中斷 { // mWIN32_COMMAND mCommand; // mCommand.mFunction = mFuncWriteIoWord;//發(fā)送I/O口寫字命令,命令代碼,該命令在硬件中斷時由驅(qū)動程序執(zhí)行 // mCommand.mAddress = & mIoBase ->mCh365IoPort[0x00]; //設(shè)定A0-A15的地址寄存器,操作地址 // mCommand.mLength = 1; //數(shù)據(jù)長度設(shè)定,操作數(shù)據(jù)長度,以字節(jié)計算 // mCommand.mBuffer[0] = 0x00; //要寫的數(shù)據(jù) // mCommand.mBuffer[1] = 0x00; // A15=1,假定:在外部電路的中斷邏輯上,將A15置為高電平可以撤消中斷 // if ( CH365mWriteIntCommand(Device_Number, &mCommand, 1 ) == FALSE ) // { // AfxMessageBox("設(shè)置中斷預(yù)處理命令失敗,請重新安裝板卡驅(qū)動程序!",16,0); // //exit(0); // } if ( CH365mSetIntRoutine(Device_Number, InterruptEvent ) == FALSE ) { AfxMessageBox("設(shè)置中斷服務(wù)子程序失敗,\r\n\r\n請重新安裝板卡驅(qū)動程序!",16,0); exit(0); } }

}

偽中斷服務(wù)例程 //中斷服務(wù)子程序(一幀數(shù)據(jù)來一個中斷) void CALLBACK InterruptEvent( void ) {

...向驅(qū)動程序讀寫數(shù)據(jù)

}


熱門產(chǎn)品 : USB3.0 HUB控制器:CH634

出現(xiàn)藍屏很可能是你改的驅(qū)動造成的,一般驅(qū)動里面有BUG就會藍屏,所以驅(qū)動的代碼不建議隨便改動!中斷服務(wù)InterruptEvent調(diào)用的哪些函數(shù)?回調(diào)函數(shù)里面最好不要調(diào)用阻塞的函數(shù)!你有源代碼的話,你可以這樣試試,在你的應(yīng)用程序里去創(chuàng)建dllInterruptThread,而不是DLL里面。


藍屏不應(yīng)該是驅(qū)動修改造成,因為偽中斷只做一個狀態(tài)監(jiān)視(讀取驅(qū)動里的一組數(shù)據(jù)),屏蔽掉就不出現(xiàn)死機/藍屏情況了;至于dllInterruptThread倒是可以放到應(yīng)用程序級試試,但我們認(rèn)為不應(yīng)該是因為偽中斷處理阻塞問題,因為我們將偽中斷里所有處理都屏蔽掉(只留一個空殼),還是會死機,因此我們懷疑會不會是dll里的dllInterruptThread線程處理問題,我看你們把它設(shè)為最高級別TIME_CRITICAL級,里面是一死循環(huán),每個循環(huán)檢測一次中斷狀態(tài),如果出現(xiàn)錯誤延時5ms處理,這方面在中斷頻率較高時是不是可能有問題。 因為我們還一款硬件,中斷是5ms,不容易死(至少目前沒有發(fā)現(xiàn)過)。


驅(qū)動里面的函數(shù)調(diào)用是跟IRQL有關(guān)的,有的函數(shù)要求IRQL <= DISPATCH_LEVEL等等,不然就會出現(xiàn)IRQL_NOT_LESS_OR EQUAL的藍屏錯誤。dllInterruptThread放到應(yīng)用程序里面,可以省了回調(diào)函數(shù),或者不設(shè)置線程的優(yōu)先級,我個人覺得可以解決你的問題。你說的最高級別TIME_CRITICAL級有可能會出現(xiàn)這種現(xiàn)象,在任務(wù)管理器中任意改變優(yōu)先級會提示“導(dǎo)致不希望發(fā)生的結(jié)果,包括系統(tǒng)不穩(wěn)定”!


建議不要在BBS 上詢問涉及有權(quán)限的源碼問題,如有相關(guān)問題請發(fā) tech@wch.cn 會有專人處理。


只有登錄才能回復(fù),可以選擇微信賬號登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频