Member 12278335 Ответов: 1

Выиграть API-интерфейс последовательной связи


я попробовал ниже код в win32 api. перед созданием потока я использовал для ожидания данных во время цикла. это время receving работает нормально, но когда я создаю поток, как показано ниже, я получаю ошибку в setCommask и waitCommask... что это за ошибка?..

ошибка отображается в соответствии с выводом моего приложения

Ошибка! в настройке CommMask
Ошибка! в настройке WaitCommEvent()

Что я уже пробовал:

//header file
#include 
#include "Serial.h"
#include  "resource.h"
#include 


#define AMOUNT_TO_READ          512

HANDLE hComm;                          // Handle to the Serial port
char  ComPortName[] = "\\\\.\\COM5";  // Name of the Serial port(May Change) to be opened,
BOOL  Status;                          // Status of the various operations 
                    // Event mask to trigger
char  TempChar;                        // Temperory Character
char  lpBuf[AMOUNT_TO_READ];               // Buffer Containing Rxed Data
DWORD NoBytesRead;                     // Bytes read by ReadFile()
int i = 0;

BOOL flag;
HANDLE readerThread;
DWORD readThreadID;


void show(char*);

// Cpp file
#include "Main.h"

HWND windowG;
bool wirtePort()
{
	char   lpBuffer[] = "A";		       // lpBuffer should be  char or byte array, otherwise write wil fail
	DWORD  dNoOFBytestoWrite;              // No of bytes to write into the port
	DWORD  dNoOfBytesWritten = 0;          // No of bytes written to the port

	dNoOFBytestoWrite = sizeof(lpBuffer); // Calculating the no of bytes to write into the port

	Status = WriteFile(hComm,               // Handle to the Serialport
		lpBuffer,            // Data to be written to the port 
		dNoOFBytestoWrite,   // No of bytes to write into the port
		&dNoOfBytesWritten,  // No of bytes written to the port
		NULL);

	//if (Status == TRUE)
	//show("\n\n    %s - Written to %s", lpBuffer, ComPortName);
	//else
	//show("\n\n   Error %d in Writing to Serial Port", GetLastError());
	return 0;
}
void ErrorExit(LPTSTR lpszFunction)
{
	// Retrieve the system error message for the last-error code

	LPVOID lpMsgBuf;
	LPVOID lpDisplayBuf;
	DWORD dw = GetLastError();

	FormatMessage(
		FORMAT_MESSAGE_ALLOCATE_BUFFER |
		FORMAT_MESSAGE_FROM_SYSTEM |
		FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL,
		dw,
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
		(LPTSTR)&lpMsgBuf,
		0, NULL);

	// Display the error message and exit the process

	lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
		(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
	StringCchPrintf((LPTSTR)lpDisplayBuf,
		LocalSize(lpDisplayBuf) / sizeof(TCHAR),
		TEXT("%s failed with error %d: %s"),
		lpszFunction, dw, lpMsgBuf);
	MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);

	LocalFree(lpMsgBuf);
	LocalFree(lpDisplayBuf);
	ExitProcess(dw);
}
bool readPort(LPVOID lpV)
{
	HANDLE tCom = (HANDLE)lpV;
	DWORD dwEventMask;

	//Configure Windows to Monitor the serial device for Character Reception
	Status = SetCommMask(tCom, EV_RXCHAR); 

	if (Status == FALSE)
		show("\n\n    Error! in Setting CommMask");
	else
		show("\n\n    Setting CommMask successfull");

	while (true)
	{
		i = 0;
		//Setting WaitComm() Event 

		//printf("\n\n    Waiting for Data Reception");

		Status = WaitCommEvent(tCom, &dwEventMask, NULL); //Wait for the character to be received
		
		// Program will Wait here till a Character is received 

		if (Status == FALSE)
		{
			
			show("\n    Error! in Setting WaitCommEvent()");
	
			ErrorExit(TEXT("WaitCommEvent"));


			break;
		}
		else 
		{
			

			Status = ReadFile(tCom, lpBuf, sizeof(lpBuf), &NoBytesRead, NULL);

			show("\n");
			show(lpBuf);
			show("  ");
			wirtePort();
		}
	}
	return 0;
}

void setupPort()
{
	// Initializing DCB structure
	DCB dcbSerialParams = { 0 };                         
	dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
	//retreives  the current settings
	Status = GetCommState(hComm, &dcbSerialParams);      

	if (Status == FALSE)
		show("\n    Error! in GetCommState()");

	dcbSerialParams.BaudRate = CBR_9600;      // Setting BaudRate = 9600
	dcbSerialParams.ByteSize = 8;             // Setting ByteSize = 8
	dcbSerialParams.StopBits = ONESTOPBIT;    // Setting StopBits = 1
	dcbSerialParams.Parity = NOPARITY;        // Setting Parity = None 

	Status = SetCommState(hComm, &dcbSerialParams);  

	if (Status == FALSE)
	{
		show("\n    Error! in Setting DCB Structure");
	}
	else 
	{
		show("\n\n    Setting DCB Structure Successfull\n");
	}

	// Setting Timeouts

	COMMTIMEOUTS timeouts = { 0 };
	timeouts.ReadIntervalTimeout = 50;
	timeouts.ReadTotalTimeoutConstant = 50;
	timeouts.ReadTotalTimeoutMultiplier = 10;
	timeouts.WriteTotalTimeoutConstant = 50;
	timeouts.WriteTotalTimeoutMultiplier = 10;

	if (SetCommTimeouts(hComm, &timeouts) == FALSE)
		show("\n\n    Error! in Setting Time Outs");
	else
		show("\n\n    Setting Serial Port Timeouts Successfull");

}

void openPort()
{

	hComm = CreateFile(ComPortName,   // Name of the Port to be Opened
		GENERIC_READ | GENERIC_WRITE, // Read/Write Access
		0,                            // No Sharing, ports cant be shared
		NULL,                         // No Security
		OPEN_EXISTING,                // Open existing port only
		0,                            // Non Overlapped I/O
		NULL);                        // Null for Comm Devices

	if (hComm == INVALID_HANDLE_VALUE)
		show("\n    Error! - Port %s can't be opened\n");
	else
		show("\n    Port %s Opened\n ");

}

void closePort()
{
	//Closing the Serial Port
	CloseHandle(hComm);

}

void show(char* userMessage)
{

	// send message to the dialog
	HWND OutputWindow = GetDlgItem(windowG, IDC_EDIT1);
	if (OutputWindow)
	{
		SendMessageA(OutputWindow, EM_REPLACESEL, 0, (long)userMessage);
	}
}


int _stdcall handler(HWND window, UINT msg, WPARAM window_pram, LPARAM long_pram)
{
	windowG = window;
	switch (msg)
	{
	case WM_COMMAND:
	{
					   switch (window_pram)
					   {
					   case IDC_BUTTON_CONNECT:
					   {
								show("init the connect buttion");
								openPort();
								setupPort();
								readerThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)readPort,(LPVOID)hComm,0,&readThreadID); 
								closePort();

					   }break;
					   default:
						   break;
					   }
	}break;
	case WM_CLOSE:
	{
					 DestroyWindow(window);
	}break;
	default:
		return DefWindowProcA(window, msg, window_pram, long_pram);
		break;
	}
	return 0;
}

   WinMain(HINSTANCE cur_base, HINSTANCE prv_base, char* args, int display)
{
	DialogBoxA(cur_base, MAKEINTRESOURCEA(IDD_DIALOG1), 0, handler);
	return 1;
}



// отладочная информация

'PMDG_MCP.exe' (Win32): Загружено 'C:\Users\SIC-002\Documents\Visual Студия 2013\Projects\PMDG_MCP\Debug\PMDG_MCP.exe". Символы загружены.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\ntdll.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\kernel32.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\KernelBase.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\user32.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\win32u.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\gdi32.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\gdi32full.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\msvcp_win.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\ucrtbase.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\msvcr120d.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\imm32.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\uxtheme.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\msvcrt.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\combase.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\rpcrt4.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\sspicli.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\cryptbase.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\bcryptprimitives.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\sechost.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\msctf.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\oleaut32.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\advapi32.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.18362.752_none_2e6decc4278ee012\comctl32.dll'. Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\kernel.appcore.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\TextInputFramework.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\CoreUIComponents.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\CoreMessaging.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\SHCore.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\ntmarta.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\WinTypes.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\WinTypes.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\WinTypes.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Выгружено 'C:\Windows\SysWOW64\WinTypes.dll'
'PMDG_MCP.exe' (Win32): Выгружено 'C:\Windows\SysWOW64\WinTypes.dll'
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\iertutil.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): загружено 'C:\Program файлы (x86)\интернет скачать Manager\idmmkb.dll". Не удается найти или открыть файл PDB.
'PMDG_MCP.exe' (Win32): Загружено 'C:\Windows\SysWOW64\ole32.dll". Не удается найти или открыть файл PDB.

Richard MacCutchan

Эти сообщения не совсем полезны. Используйте свой отладчик, чтобы выяснить, почему они создаются.

1 Ответов

Рейтинг:
5

Richard MacCutchan

Когда системный вызов терпит неудачу вам нужно позвонить GetLastError чтобы выяснить почему. Видеть Функция SetCommMask (страницы winbase.ч) - Win32-приложений, Майкрософт документы[^] например.


CPallini

5.

Member 12278335

От ошибок показывает Ошибка 6: неверный дескриптор после вызова SetCommMask() иам получение ERROR_INVALID_HANDLE 6 (0х6) но не могу понять, почему....?

Richard MacCutchan

Проверьте точно, какое значение находится в hComm на линии:

readerThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)readPort,(LPVOID)hComm,0,&readThreadID); 


Здесь мы мало что можем сделать, так как единственный способ отследить проблему-это запустить код в отладчике.
И проверьте это еще раз в начале readPort.

Member 12278335

Значение hComm равно 0x000002b0, которое является таким же, когда оно было создано. Это проблема открытия порта в основном потоке и вызова его события из другого потока.
я проверяю пример MTTTY, который они сделали то же самое, что и я.

это и есть ссылка
https://docs.microsoft.com/en-us/previous-versions/ff802693(v=msdn.10)?redirectedfrom=MSDN

Richard MacCutchan

Извините, но у меня нет ответа на этот вопрос. И, к сожалению, у меня нет возможности проверить эти системные вызовы без какого-либо устройства для разговора.

Member 12278335

Это плата arduino uno, с которой я пытаюсь общаться. Большое вам спасибо за то, что уделили мне время.....