Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Serial coms worker thread not working

Serial coms worker thread not working

Scheduled Pinned Locked Moved C / C++ / MFC
helpquestioncomdebugging
3 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    jimjim733
    wrote on last edited by
    #1

    Hi All, I wondered if someone can shed some light on what might be going on here. I have created the worker thread (code below) and when my system first boots up and I run through debug I find that the thread doesn't fire off the PostMessage(UWM_DATA_READ) until the buffer is full up....what I want it to do is fire it off when ever it reads in something. The interesting part is that if I stop the application and open Hyperterminal on the same com port then close it and then rerun the application it works as I intended???? Does anyone have any ideas what is going on?????? Cheers Jim

    UINT CMyDlg::monitorThread(LPVOID pParam)
    {
    DWORD dwRead;
    DWORD dwRes;
    BOOL fWaitingOnRead = FALSE;
    OVERLAPPED osReader = {0};
    struct PTZCommStruct *pPTZStruct = (struct PTZCommStruct *)pParam;

    // Create the overlapped event.
    osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    
    if(osReader.hEvent == NULL)
    {
    	// Error creatiing overlapped event, abort.
    	DWORD err = ::GetLastError();
    	pPTZStruct->pWnd->PostMessage(UWM\_READER\_SHUTTING\_DOWN, (WPARAM)err);
    	return 0;
    } 
    
    
    while(pPTZStruct->nPTZCommTerminate == 0)
    {
    	if(!fWaitingOnRead)
    	{
    		// Issue read Operation.
    		BOOL tmp = ReadFile(m\_hPTZCtrlPort, PTZbuffer, MAX\_BUFFER\_SIZE, &dwRead, &osReader);
    		if(!tmp)
    		{
    			if(GetLastError() != ERROR\_IO\_PENDING) // read not delayed
    			{
    				// Error in comms - report!!!
    				return 0;
    			}
    			else
    			{
    				fWaitingOnRead = TRUE;
    			}
    		}
    		else
    		{
    			// \*\*\*Read the data
    			pPTZStruct->pWnd->PostMessage(UWM\_DATA\_READ);
    		}
    	}
    	else
    	{
    		dwRes = WaitForSingleObject(osReader.hEvent, READ\_TIMEOUT);
    		switch(dwRes)
    		{
    			// Read Completed
    		case WAIT\_OBJECT\_0:
    			if(!GetOverlappedResult(m\_hPTZCtrlPort, &osReader, &dwRead, FALSE))
    			{
    				DWORD dwError = GetLastError();
    				switch(dwError)
    				{
    					case ERROR\_HANDLE\_EOF:
    						return 0;
    						break;
    					case ERROR\_IO\_PENDING:
    						return 0;
    						break;
    					case ERROR\_IO\_INCOMPLETE:
    						return 0;
    						break;
    					case ERROR\_OPERATION\_ABORTED:
    						return 0;
    						break;
    					default:
    						// error in comms - report
    						Dump1("Serial Read Error %d\\r\\n", ::GetLastError());
    						return 0;
    						break;
    				}
    			}
    			else
    			{
    				// \*\*\*Read the Data 
    		        pPTZStruct->pWnd->PostMessage(UWM\_DATA\_READ);
    			}
    			fWaitingOnRead = FALSE;
    			break;
    
    		case WAIT\_TIMEOUT:
    
    C 1 Reply Last reply
    0
    • J jimjim733

      Hi All, I wondered if someone can shed some light on what might be going on here. I have created the worker thread (code below) and when my system first boots up and I run through debug I find that the thread doesn't fire off the PostMessage(UWM_DATA_READ) until the buffer is full up....what I want it to do is fire it off when ever it reads in something. The interesting part is that if I stop the application and open Hyperterminal on the same com port then close it and then rerun the application it works as I intended???? Does anyone have any ideas what is going on?????? Cheers Jim

      UINT CMyDlg::monitorThread(LPVOID pParam)
      {
      DWORD dwRead;
      DWORD dwRes;
      BOOL fWaitingOnRead = FALSE;
      OVERLAPPED osReader = {0};
      struct PTZCommStruct *pPTZStruct = (struct PTZCommStruct *)pParam;

      // Create the overlapped event.
      osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
      
      if(osReader.hEvent == NULL)
      {
      	// Error creatiing overlapped event, abort.
      	DWORD err = ::GetLastError();
      	pPTZStruct->pWnd->PostMessage(UWM\_READER\_SHUTTING\_DOWN, (WPARAM)err);
      	return 0;
      } 
      
      
      while(pPTZStruct->nPTZCommTerminate == 0)
      {
      	if(!fWaitingOnRead)
      	{
      		// Issue read Operation.
      		BOOL tmp = ReadFile(m\_hPTZCtrlPort, PTZbuffer, MAX\_BUFFER\_SIZE, &dwRead, &osReader);
      		if(!tmp)
      		{
      			if(GetLastError() != ERROR\_IO\_PENDING) // read not delayed
      			{
      				// Error in comms - report!!!
      				return 0;
      			}
      			else
      			{
      				fWaitingOnRead = TRUE;
      			}
      		}
      		else
      		{
      			// \*\*\*Read the data
      			pPTZStruct->pWnd->PostMessage(UWM\_DATA\_READ);
      		}
      	}
      	else
      	{
      		dwRes = WaitForSingleObject(osReader.hEvent, READ\_TIMEOUT);
      		switch(dwRes)
      		{
      			// Read Completed
      		case WAIT\_OBJECT\_0:
      			if(!GetOverlappedResult(m\_hPTZCtrlPort, &osReader, &dwRead, FALSE))
      			{
      				DWORD dwError = GetLastError();
      				switch(dwError)
      				{
      					case ERROR\_HANDLE\_EOF:
      						return 0;
      						break;
      					case ERROR\_IO\_PENDING:
      						return 0;
      						break;
      					case ERROR\_IO\_INCOMPLETE:
      						return 0;
      						break;
      					case ERROR\_OPERATION\_ABORTED:
      						return 0;
      						break;
      					default:
      						// error in comms - report
      						Dump1("Serial Read Error %d\\r\\n", ::GetLastError());
      						return 0;
      						break;
      				}
      			}
      			else
      			{
      				// \*\*\*Read the Data 
      		        pPTZStruct->pWnd->PostMessage(UWM\_DATA\_READ);
      			}
      			fWaitingOnRead = FALSE;
      			break;
      
      		case WAIT\_TIMEOUT:
      
      C Offline
      C Offline
      Cedric Moonen
      wrote on last edited by
      #2

      Wow, it really seems that you like to complicate your life. If you are doing that in a separate thread, why are you using OverlappedIO ? You could simply use a blocking read that returns when data is available. Anyway, that's not the source of your problem. From your description, it really sounds like you didn't set the comm timeouts. Thus, when you start hyperterminal, the timeout settings are changed and that's why the behavior is different afterwards. To change the comm timeouts, you can use the SetCommTimeouts[^] function.

      Cédric Moonen Software developer
      Charting control [v1.5] OpenGL game tutorial in C++

      J 1 Reply Last reply
      0
      • C Cedric Moonen

        Wow, it really seems that you like to complicate your life. If you are doing that in a separate thread, why are you using OverlappedIO ? You could simply use a blocking read that returns when data is available. Anyway, that's not the source of your problem. From your description, it really sounds like you didn't set the comm timeouts. Thus, when you start hyperterminal, the timeout settings are changed and that's why the behavior is different afterwards. To change the comm timeouts, you can use the SetCommTimeouts[^] function.

        Cédric Moonen Software developer
        Charting control [v1.5] OpenGL game tutorial in C++

        J Offline
        J Offline
        jimjim733
        wrote on last edited by
        #3

        Hi Cedric, Thanks for your help, that worked straight away.....I realised I had not set the timeouts :doh: Jim

        1 Reply Last reply
        0
        Reply
        • Reply as topic
        Log in to reply
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes


        • Login

        • Don't have an account? Register

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • World
        • Users
        • Groups