掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
非同期シリアル通信について (ID:66235)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
参考として、ソースを載せておきます //*** 受信監視処理 //*** COMポートからのメッセージの受信を監視する VOID CSerial::WatchComProc() { COMSTAT ltComState ; DWORD ldwWaitTime = 1 ; DWORD ldwEvtMask = 0 ; BOOL lblResult = FALSE ; if( SetCommMask( m_tComCtrlInf.hComDev, m_tComCtrlInf.dwEventMode | EV_CTS | EV_DSR | EV_RLSD ) == FALSE ) { TRACE0( "[WatchComProc]SetCommMask Failure!!\n" ) ; return ; } while( m_tComCtrlInf.blConnect == TRUE ) { ldwEvtMask = 0; if( WaitForSingleObject( m_pExitEventRxWatch -> m_hObject, ldwWaitTime ) == WAIT_OBJECT_0 ) { break ; } // ETXを受信したらイベントを発行する WaitCommEvent( m_tComCtrlInf.hComDev, &ldwEvtMask, &m_tComCtrlInf.tOverLappedRead ) ; ClearCommError( m_tComCtrlInf.hComDev, &m_tComCtrlInf.dwError, <ComState ); if( ltComState.cbInQue ) { if( ( ldwEvtMask & m_tComCtrlInf.dwEventMode ) == 0 ) { // イベントが発生していない場合 continue ; } // バッファに溜まっているだけ取得する do { lblResult = ReadData() ; }while( lblResult == TRUE ) ; } } } //*** COMポートより受信メッセージの取得 BOOL CSerial::ReadData() { COMSTAT ltComState ; CWnd* lpMainWnd = NULL; DWORD ldwSize = 0; TCHAR sError[100]; BOOL lblReadState = FALSE ; BOOL lblRetyrFlg = FALSE; lpMainWnd = AfxGetApp()->m_pMainWnd; do { // COMポートの状態をチェックする ClearCommError( m_tComCtrlInf.hComDev, &m_tComCtrlInf.dwError, <ComState ); if( m_tComCtrlInf.dwError > 0 ) { // エラーが発生した場合 wsprintf( &sError[0], "ClearCommError1:%d", m_tComCtrlInf.dwError ); lpMainWnd->MessageBox( sError, "Comm Error" ); break ; } ldwSize = ltComState.cbInQue ; if( ldwSize <= 0 ) { // バッファに溜まっていない場合 break ; } // 溜まっているデータサイズをチェックする if( ldwSize > ( DWORD )m_iRxBuffSize ) { // 確保してあるバッファサイズより多い場合 ldwSize = m_iRxBuffSize ; lblRetyrFlg = TRUE; } // 非同期読み込み lblReadState = ReadFileEx( m_tComCtrlInf.hComDev, ( LPVOID )m_bpRxBuff, ldwSize, &m_tComCtrlInf.tOverLappedRead, FileIOCompletionRoutine ) ; // 失敗した場合 if( ( lblReadState != TRUE ) || // 戻り値自体は成功だがエラーがある場合 // ※MSDN参照 ( ( lblReadState == TRUE ) && ( GetLastError() != ERROR_SUCCESS ) ) ) { // その他のエラーの場合 ClearCommError( m_tComCtrlInf.hComDev, &m_tComCtrlInf.dwError, <ComState ) ; wsprintf( &sError[0], "ReadFileEx ClearCommError:%d", m_tComCtrlInf.dwError ); lpMainWnd->MessageBox( sError, "Comm Error" ); lblRetyrFlg = FALSE; break; } // I/O 完了コールバック関数が呼び出されるまで停止する SleepEx( INFINITE, TRUE ); }while( 0 ) ; return( lblRetyrFlg ) ; //*** 読み込み込み用CALLBACK関数 VOID CALLBACK FileIOCompletionRoutine( DWORD dwErrorCode, // 完了コード DWORD dwNumberOfBytesTransfered, // 転送バイト数 LPOVERLAPPED lpOverlapped // I/O 情報がある // 構造体へのポインタ ) { CSerial* lpSerial = NULL; TRACE0( "FileIOCompletionRoutine\n" ); do { // ReadFileEx 関数がファイルの終端よりも後ろを読み取ろうとした場合 if( dwErrorCode == ERROR_HANDLE_EOF ) { break; } // エラーが発生した場合 if( dwNumberOfBytesTransfered <= 0 ) { break; } if( ( lpOverlapped == NULL ) || (lpOverlapped -> Pointer == NULL ) ) { break; } lpSerial = ( CSerial* )lpOverlapped -> Pointer; if( lpSerial -> GetReceiveMode() == TRUE ) { // 受信したメッセージをとりあえず、キューへセットする // 受信処理 // lpSerial -> SetData( dwNumberOfBytesTransfered ) ; } }while( 0 ); TRACE0( "FileIOCompletionRoutine Complete\n" ); }
←解決時は質問者本人がここをチェックしてください。
更新する
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.