serial port : interrupt reading operation ?
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4

Thread: serial port : interrupt reading operation ?

  1. #1
    Join Date
    Apr 2000
    Posts
    128

    Question serial port : interrupt reading operation ?

    Hello,

    I have a dialog box with 2 buttons : 'START' and 'STOP'.

    Pressing 'start' will create a serial port connection, and start a thread that will read characters from the connection.

    Pressing 'stop' must end the reading thread.
    This can be necessary in the case where the port is opened successfully, but no characters come in because of a disconnected device. (--> so, I must be able to interrupt the WaitCommEvent command)

    Code:
    void CMyDlg::OnStart()
    {
       // open serial connection
       m_hPort = OpenSerialPort();
    
       // start thread
       m_ThreadFinished = ::CreateEvent(NULL, TRUE, FALSE, NULL);
       ::ResetEvent(m_ThreadFinished);
    	
       AfxBeginThread(ExecThreadProc2, &hPort);
    
       DWORD dwRet;
       do
       {
          dwRet = ::WaitForSingleObject(m_ThreadFinished, 100);
          if (dwRet != WAIT_OBJECT_0)
          {
             MSG msg;
             while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
             {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
             }
          }	
       } while ((dwRet != WAIT_OBJECT_0) && (dwRet != WAIT_FAILED));
    
       CloseHandle(m_ThreadFinished);
    }
    
    
    void CMyDlg::OnStop()
    {
       ??????
    }
    
    
    
    HANDLE CDomeControlDlg::OpenSerialPort()
    {
       HANDLE hPort = NULL;
       // 1) Open the port.
       // ------------------
       hPort = CreateFile("COM2", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
       if (hPort == INVALID_HANDLE_VALUE) 
       {
          CloseHandle(hPort);
          AfxMessageBox("Error occured while opening serial port !");
          return NULL;
       }
       // 2) Configure the port.
       // ----------------------
       DCB dcb;
       GetCommState(hPort, &dcb);
       dcb.BaudRate = 9600;
       dcb.ByteSize = 8;
       dcb.Parity = NOPARITY;
       dcb.StopBits = ONESTOPBIT;
       if (!SetCommState(hPort, &dcb))
       {
          CloseHandle(hPort);
          AfxMessageBox("Unable to configure the serial port");
          return NULL;
       }
       // 3) Manage timeout settings.
       // ---------------------------
       COMMTIMEOUTS CommTimeouts;
       GetCommTimeouts(hPort, &CommTimeouts);
       CommTimeouts.ReadIntervalTimeout = MAXDWORD;  
       CommTimeouts.ReadTotalTimeoutMultiplier = 0;  
       CommTimeouts.ReadTotalTimeoutConstant = 0;    
       CommTimeouts.WriteTotalTimeoutMultiplier = 0;  
       CommTimeouts.WriteTotalTimeoutConstant = 0; 
       if (!SetCommTimeouts(hPort, &CommTimeouts))
       {
          CloseHandle(hPort);
          AfxMessageBox("Error setting time-outs ...");
          return NULL;
       }
    
       return hPort;
    }
    
    
    
    UINT ExecThreadProc2(LPVOID pParam)
    {	
       HANDLE used_port = *((HANDLE*)pParam);
       
       if (used_port == NULL)
          return 1;
    	
       DWORD dwCommEvent;
       bool bContinue = true;
    
       SetCommMask(used_port, EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING | EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY);
    
       while (bContinue)
       {
          if (WaitCommEvent(used_port, &dwCommEvent, 0))
             bContinue = false;			
       }
    
       ::SetEvent(m_ThreadFinished);
    
       return 0;
    }
    What's wrong with the code above, and what do I have to put in the OnStop()-function ?

    I tried to add to following routines to OnStop() :
    Code:
    if (!SetCommBreak(m_hPort))
       AfxMessageBox("SetCommBreak : error");
    else      	
       AfxMessageBox("SetCommBreak : ok");
    -- or --
    Code:
    if (!PurgeComm(m_hPort, PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR))
       AfxMessageBox("PurgeComm : error");
    else      	
       AfxMessageBox("PurgeComm : ok");
    Both systems fail : they seem to hang on the SetCommBreak or PurgeComm functions.

  2. #2
    Join Date
    Mar 2004
    Posts
    235
    afxBeginThread returns a usefull value in which will allow you to terminate the thread. This value is the handle to the thread. Use GetExitCodeThread to get the exit code of the thread and use that to terminate the thread using afxEndThread.

    If that doesn't work create a variable shared by 2 threads when you start the second thread have it set the variable with the handle to the thread using GetCurrentThread(). Use GetExitCodeThread() to get the exit code and then afxEndThread() to endit.

    Hope this helps!

  3. #3
    Join Date
    Apr 2000
    Posts
    128
    In the help files, you can find :

    ---------------------------------------------------------------------------------
    To end the thread, call AfxEndThread from within the thread, or return from the controlling function of the worker thread.
    ---------------------------------------------------------------------------------

    But that isn't possible if the thread is locked by the WaitCommEvent()-function ...

  4. #4
    Join Date
    Mar 2004
    Posts
    235
    Sorry I missed that. Reference what I said in the above post. Close the thread by calling TerminateThread(handle to thread, exit code);.
    Last edited by answer; March 16th, 2004 at 03:17 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center