473,395 Members | 1,694 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Problems with Serial Comm Handle

Hi All,

I wrote a code to do serial communication with an equipament.
When i use the code outside of threaded class it seens work properly,
but when i put inside a class and execute a thread in the first seconds the
communication is ok, later i receive read/write error.
I?ve been in MSDN site and there i discover that the read/write error is a
INVALID_HANDLE problem. But why??? I just create the serial communication
file and use it.
Anyone can help me?

Here is the code
/* cut */
/*--------------------------------------------------------------------*/
/* Main Class */

#ifndef _IGERENCIADOREQUIPAMENTO_H
#define _IGERENCIADOREQUIPAMENTO_H

#include <stdio.h>
#include <windows.h>

#define SERIAL_PARITY_NONE 0
#define SERIAL_PARITY_ODD 1
#define SERIAL_PARITY_EVEN 2

#define SERIAL_MAX_RX 256 // Input buffer max size
#define SERIAL_MAX_TX 256 // output buffer max size
#define SERIAL_CONNECTED 0
#define SERIAL_DISCONNECTED 1
#define SERIAL_DATA_SENT 2
#define SERIAL_DATA_ARRIVAL 3
#define SERIAL_RING 4
#define SERIAL_CD_ON 5
#define SERIAL_CD_OFF 6
#define SERIAL_DATA_RECV 7

#define SERIAL_SIGNAL_NBR 7

class IGerenciadorEquipamento;

typedef struct
{
HANDLE serialFD;
IGerenciadorEquipamento* pIGE;
}_SERIALCOM_IONICS;
class IGerenciadorEquipamento: public IThread
{

private:
HANDLE hSerial;
char *cPortaSerial;
DWORD dwBaudRate;
BYTE byByteSize;
BYTE byTipoParidade;
bool conectado;
bool bRX_In_Progress; // BOOL indicating if a
ReadFile is
// in progress
bool bTX_In_Progress; // BOOL indicating if a
WriteFile is
// in progress

unsigned char pacoteIN[256];
unsigned char pacoteOUT[256];

bool bConectado;

int ConfigTimeouts(COMMTIMEOUTS mCommtimeout);
int ConfigDCB(DCB mDCB);

public:
IGerenciadorEquipamento(char *mcPortaSerial, DWORD mdwBaudRate,
BYTE mbyByteSize, BYTE mbyiTipoParidade);
~IGerenciadorEquipamento();

int AtivaEquipamento(BOOL mbIniciaThread = true);
int DesativaEquipamento(BOOL mbFinalizaThread = true);
int EscreveMensagem(HANDLE hSerialCOM,unsigned char* mcMensagem, int
miTamanho);
int LeMensagem(HANDLE hSerialCOM,unsigned char* mcMensagem, int
miTamanho);
void PurgeSerial(void);
bool VerificaEstado(void);
int Run(void);
HANDLE GetSerialHND(void);
void OnSendRecv(void);
unsigned char *GetDadosRecebidos(void);
unsigned char *GetDadosEnviados(void);

int EnviaPOLLING(HANDLE hSerialCOM);
int ConcedePrivilegio(HANDLE hSerialCOM, BYTE byEndereco);
void TraduzMens(unsigned char *ucPacote, DWORD miTamanho);
DWORD IGerenciadorEquipamento::ExtraiCMD(unsigned char *ucPacoteIN,
DWORD dStartpos,
DWORD dQtdebytes,
unsigned char* ucPacoteOUT);
};

//DWORD WINAPI ComSendRecv(LPVOID p);
int ComSendRecv(LPVOID p);

#endif

/*--------------------------------------------------------------------*/
/* until here */
/* cut */
/*--------------------------------------------------------------------*/
/* Main Class Code */

//#define STRICT
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <conio.h>
#include <windows.h>
#include <iostream>
#include <math.h>
#include "IGerenciadorEquipamento.hpp"
#include "StringMethods.hpp"
#include "Consts.hpp"
#include "TipoProtocolo.hpp"

#define SIG_POWER_DOWN 0
#define SIG_READER 1
#define SIG_READ_DONE 2 // data received has been read
#define SIG_WRITER 3
#define SIG_DATA_TO_TX 4 // data waiting to be sent
#define SIG_MODEM_EVENTS 5
#define SIG_MODEM_CHECKED 6


using namespace std;
typedef struct
{
BYTE controladora;
BYTE tentativas;
bool detectaprot;
}STRU_CONFCONTROL;
STRU_CONFCONTROL ConfControl;

unsigned char *IGerenciadorEquipamento::GetDadosRecebidos(void)
{
return pacoteOUT;
}

unsigned char *IGerenciadorEquipamento::GetDadosEnviados(void)
{
return pacoteIN;
}

int IGerenciadorEquipamento::EnviaPOLLING(HANDLE hSerialCOM)
{
unsigned char ucPacoteIN[256];
unsigned char ucPacoteOUT[256];
int iTotalLido;

ZeroMemory(ucPacoteIN,3);

ucPacoteIN[0] = SYN;
ucPacoteIN[1] = '1';
ucPacoteIN[2] = 0x55;

EscreveMensagem(hSerialCOM ,ucPacoteIN,3);
iTotalLido=LeMensagem(hSerialCOM ,ucPacoteOUT,30);
if (iTotalLido)
{
if ((ucPacoteOUT[0] == SYN) && (ucPacoteOUT[1] == '1') &&
(ucPacoteOUT[2] == 0xAA))
ConfControl.detectaprot = false;
}
return iTotalLido;
}

int IGerenciadorEquipamento::ConcedePrivilegio(HANDLE hSerialCOM, BYTE
byEndereco)
{
unsigned char ucPacoteIN[256];
int iTotalEscrito;

ZeroMemory(ucPacoteIN,3);

// privilegio
ucPacoteIN[0] = SYN;
ucPacoteIN[1] = byEndereco+48;
ucPacoteIN[2] = ACK;

iTotalEscrito=EscreveMensagem(hSerialCOM ,ucPacoteIN,3);
return iTotalEscrito;
}

void IGerenciadorEquipamento::TraduzMens(unsigned char *ucPacote, DWORD
miTamanho)
{
int iCanal;
double dLitros;
char cPulsos[8];
double dPulsos;
char parcelaPacote;
char cInd;
int iInd;
int k;

dLitros = 0;
iCanal = ((((BYTE)ucPacote[1])-49)*8);
iInd = ucPacote[3] & 0x0F;

switch(iInd)
{
case 0:
iCanal += ((((BYTE)ucPacote[4])-47)+100);
printf("Bomba %i ligada\n",iCanal-100);
break;
case 1:
iCanal += ((((BYTE)ucPacote[4])-47)+100);
printf("Bomba %i desligada\n",iCanal-100);

dPulsos = 0;
k=0;
ZeroMemory(cPulsos,8);
for (int i=5;i<13;i++)
{
cPulsos[k] = ucPacote[i];
k++;
}
dPulsos = atof(cPulsos);

dLitros = round(dPulsos/1*100)/100;

if ((iCanal > 100) && (iCanal < 133))
{
printf("Bomba %i abasteceu %4.2f litros \n",iCanal-100, dLitros);
}
else
printf("Bomba %i abasteceu %4.2f litros \n",iCanal-100, 0.00);

break;
case 7:
printf("APM Reenergizado\n");
break;
}
}

DWORD IGerenciadorEquipamento::ExtraiCMD(unsigned char *ucPacoteIN,
DWORD dStartpos,
DWORD dQtdebytes,
unsigned char* ucPacoteOUT)
{
int i;
DWORD dPosETX = 0;
DWORD dPosSTX = 0;
DWORD dPosDC2 = 0;
bool bOneMoreSYN;
bool bMensTexto;
bool bContinuar = true;
DWORD dBytesToSYN;
int iTotalBytes;

iTotalBytes = 0;
dBytesToSYN = 0;
bMensTexto = false;
bOneMoreSYN = true;
dPosETX = 0;
dPosSTX = 0;
dPosDC2 = 0;

for(i=dQtdebytes-1;(i>=0);i--)
{

if (bOneMoreSYN)
dBytesToSYN++;

switch(ucPacoteIN[i])
{
case SYN:
if ((dPosETX) && (dPosSTX) && ((dPosSTX-i) == 2) && (dQtdebytes
dPosETX))

{
bMensTexto = true;
bContinuar = false;
break;
}
else
{
if ((dPosDC2) && (dPosDC2-i) == 2)
{
if ((!bOneMoreSYN) && (dBytesToSYN > 0))
{
return iTotalBytes;
}
else
{
bContinuar = false;
break;
}
}
else
{
if (!bOneMoreSYN) { return 0; }
bOneMoreSYN = false;
dPosDC2 = 0;
dPosETX = 0;
dPosSTX = 0;
}

}
break;

case DC2: dPosDC2 = i; break;
case STX: dPosSTX = i; break;
case ETX: dPosETX = i; break;
}
if (!bContinuar) break;
}

if ((i != 0xFFFF) && (ucPacoteIN[i] == SYN))
{
if (bMensTexto)
dPosETX++;
else
dPosETX = dPosDC2;

for(int j=i;j<=dPosETX;j++)
{
ucPacoteOUT[iTotalBytes] = ucPacoteIN[j];
iTotalBytes++;
}
}
return iTotalBytes;
}
IGerenciadorEquipamento::IGerenciadorEquipamento(c har *mcPortaSerial,
DWORD mdwBaudRate,
BYTE mbyByteSize,
BYTE mbyTipoParidade)
{
cPortaSerial = mcPortaSerial;
dwBaudRate = mdwBaudRate;
mbyTipoParidade = mbyTipoParidade;
mbyByteSize = mbyByteSize;
hSerial = INVALID_HANDLE_VALUE;
conectado = false;
bRX_In_Progress = false;
bTX_In_Progress = false;
ConfControl.detectaprot = true;
ConfControl.tentativas = 0;
ConfControl.controladora = 0;

}

IGerenciadorEquipamento::~IGerenciadorEquipamento( )
{
conectado = false;
cPortaSerial = "";
dwBaudRate = 0;
byTipoParidade = SERIAL_PARITY_NONE;
byByteSize = 0;

if (GetThreadHND()!=0)
WaitForSingleObject(GetThreadHND(), 2000);

bRX_In_Progress = false;
bTX_In_Progress = false;
if (hSerial != INVALID_HANDLE_VALUE)
CloseHandle(hSerial);
hSerial = INVALID_HANDLE_VALUE;
}

int IGerenciadorEquipamento::ConfigTimeouts(COMMTIMEOU TS mCommtimeout)
{

// configura os timeouts da Porta Serial
mCommtimeout.ReadIntervalTimeout = 20;
mCommtimeout.ReadTotalTimeoutMultiplier = 1;
mCommtimeout.ReadTotalTimeoutConstant = 20;
mCommtimeout.WriteTotalTimeoutMultiplier = 5;
mCommtimeout.WriteTotalTimeoutConstant = 5;

return SetCommTimeouts(hSerial,&mCommtimeout);
}

int IGerenciadorEquipamento::ConfigDCB(DCB mDCB)
{
// recupera as informa??es do DCB
if (!GetCommState(hSerial,&mDCB))
{
CloseHandle(hSerial);
return ERROR_INVALID_HANDLE;
}
// set DCB to configure the serial port
mDCB.DCBlength = sizeof(mDCB);

/* ---------- Serial Port Config ------- */
mDCB.BaudRate = dwBaudRate;

switch(byTipoParidade)
{
case SERIAL_PARITY_NONE:
mDCB.Parity = NOPARITY;
mDCB.fParity = 0;
break;
case SERIAL_PARITY_EVEN:
mDCB.Parity = EVENPARITY;
mDCB.fParity = 1;
break;
case SERIAL_PARITY_ODD:
mDCB.Parity = ODDPARITY;
mDCB.fParity = 1;
break;
}
mDCB.StopBits = ONESTOPBIT;
mDCB.ByteSize = 8;
mDCB.fBinary = 0;
mDCB.fAbortOnError = 0;
mDCB.wReserved = 0;
mDCB.XonLim = 100;
mDCB.XoffLim = 100;
mDCB.XonChar = 0x0D;
mDCB.XoffChar = 0x0A;
mDCB.ErrorChar = 0;
mDCB.EofChar = 0;
mDCB.EvtChar = 0;
mDCB.wReserved1 = 0;

return SetCommState(hSerial,&mDCB);

}
int IGerenciadorEquipamento::AtivaEquipamento(BOOL mbIniciaThread)
{
int iErro;
DCB dcb;
int i;

COMMTIMEOUTS cto;
if (hSerial != INVALID_HANDLE_VALUE)
CloseHandle(hSerial);
hSerial = INVALID_HANDLE_VALUE;

if (cPortaSerial != "")
{
iErro = 0;

hSerial = CreateFile(cPortaSerial, // filename
GENERIC_READ | GENERIC_WRITE, // acesso
desejado
0, // modo de
compartilhamento
NULL, // atributos
de seguran?a
OPEN_EXISTING, // disposi??o
da cria??o do arquivo
FILE_FLAG_NO_BUFFERING,
// flag de cria??o
NULL); // indica se
pode ou n?o copiar os
// atributos do
arquivo atual para outro
// arquivo
if (hSerial != INVALID_HANDLE_VALUE)
{
bConectado = true;

// aplica os timeous
if (!ConfigTimeouts(cto))
iErro = 2;

// aplica o DCB
if (!ConfigDCB(dcb))
iErro = 4;

}
}
else
iErro = -2;
/* --------------------------------------------- */
if (iErro > 0)
{
CloseHandle(hSerial);
hSerial = INVALID_HANDLE_VALUE;
}
else
{

HANDLE hThread1;
DWORD dThreadID1;
if(mbIniciaThread)
{
printf("Connected ! \n");

hThread1 = CreateThread(NULL, // default
security attributes
0, // use default
stack size
(DWORD (_stdcall *)(void *))ComSendRecv,
// thread function
(void*)this, // argument to thread
function
0, // use default
creation flags
&dThreadID1); // returns the
thread identifier

*/

}
}

/* --------------------------------------------- */
return iErro;

}
int IGerenciadorEquipamento::DesativaEquipamento(BOOL mbFinalizaThread)
{
conectado = false;

if(mbFinalizaThread)
{

}
if (hSerial != INVALID_HANDLE_VALUE)
CloseHandle(hSerial);
hSerial = INVALID_HANDLE_VALUE;
if (this->GetThreadHND())
{
if (WaitForSingleObject (this->GetThreadHND(), 2000) == WAIT_TIMEOUT)
{
TerminateThread (this->GetThreadHND(), 1);
CloseHandle (this->GetThreadHND());
}
else CloseHandle (this->GetThreadHND());
}
CloseHandle(this->GetThreadHND());

printf("Disconnected ! \n");

}

int IGerenciadorEquipamento::EscreveMensagem(HANDLE hSerialCOM,unsigned
char* mcMensagem, int miTamanho)

{
char cTXBuffer[SERIAL_MAX_RX];
DWORD iQtdebytesEscritos;
int iTamanhoBuffer = 0;
int iSuccess = 0;
int Error = 0;
HANDLE hCom;


if (!bTX_In_Progress)
{
PurgeComm(hSerialCOM,PURGE_TXCLEAR | PURGE_RXCLEAR);
//hCom = hSerialCOM;

iSuccess = WriteFile(hSerialCOM,
mcMensagem,
miTamanho,
&iQtdebytesEscritos,
NULL);

if (!iSuccess)
{
// failure
if((Error = GetLastError()) != ERROR_IO_PENDING )
printf("erro: %i , qtde: %i => WriteFile error (not pending)\
n", Error,iQtdebytesEscritos & 0xFFFF);
}

bTX_In_Progress = false;

}

return iQtdebytesEscritos;
}
int IGerenciadorEquipamento::LeMensagem(HANDLE hSerialCOM,unsigned char*
mcMensagem, int miTamanho)
{
DWORD iQtdebytesLidos;
DWORD iLenMensagem = 0;
int iSuccess = 0;
int Error = 0;
HANDLE hCom;

ZeroMemory(mcMensagem,SERIAL_MAX_RX);

if (!bRX_In_Progress)
{
// locking reading
bRX_In_Progress = true;
//hCom = hSerialCOM;

// starting a new read
iSuccess = ReadFile(hSerialCOM, // handle do arquivo
mcMensagem, // buffer de leitura
miTamanho, // n?mero de bytes a serem lidos
&iQtdebytesLidos, // n?mero de bytes realmente
lidos
NULL); // usado para leitura
concorrente
// da serial

if (!iSuccess)
{
// failure
if((Error = GetLastError()) != ERROR_IO_PENDING)
{
printf("erro: %i , qtde: %i => Readfile error (not pending)\
n", Error,iQtdebytesLidos & 0xFFFF);
}
}
bRX_In_Progress = false;
}

return iQtdebytesLidos;
}

void IGerenciadorEquipamento::PurgeSerial(void)
{
PurgeComm(hSerial,PURGE_TXCLEAR | PURGE_RXCLEAR);
}

bool IGerenciadorEquipamento::VerificaEstado(void)
{
// return (bRX_In_Progress || bTX_In_Progress);
}

int ComSendRecv(LPVOID p)
{
IGerenciadorEquipamento* pIGE;

pIGE = (IGerenciadorEquipamento*)p;

if (pIGE !=0)
return pIGE->Run();

}

BYTE CalculaCRC(unsigned char *msg, int qtdeBytes)
{
BYTE valor_crc = 0;

for (int i=0; i<=qtdeBytes-1;i++)
{
valor_crc += msg[i];
}
return valor_crc;
}

int IGerenciadorEquipamento::Run(void)
{
bool bDone;
unsigned char ucPacoteIN[256];
unsigned char ucPacoteOUT[256];
unsigned char ucPacoteCMD[256];
int iRetry;
BYTE byPacoteCRC, byPacoteCalcCRC;
// char *lista[3];

int iTotalLido = 0;
int iTamPacoteCMD = 0;

bDone = false;
bRX_In_Progress = false;
bTX_In_Progress = false;

GetLastError(); // just to clear any pending error

HANDLE hComm = hSerial;

char cmd[5];

while(!bDone)
{

Sleep(1000);

if (ConfControl.detectaprot)
EnviaPOLLING(hSerial);

if (ConfControl.controladora)
{
iTotalLido = LeMensagem(hSerial ,pacoteOUT,30);
if (iTotalLido)
{
ConcedePrivilegio(hSerial,ConfControl.controladora );
ConfControl.tentativas = 5;
}
ConfControl.tentativas--;
if (ConfControl.tentativas <= 0)
{
ConfControl.tentativas = 0;
ConfControl.controladora = 0;
}
}

ConcedePrivilegio(hSerial,0);

iRetry = 1;

while (iRetry >0)
{

iRetry--;

iTotalLido = LeMensagem(hSerial,ucPacoteOUT,30);
if (iTotalLido)
{
ZeroMemory(ucPacoteCMD,SERIAL_MAX_RX);

iTamPacoteCMD = ExtraiCMD
(ucPacoteOUT,1,iTotalLido,ucPacoteCMD);
if (iTamPacoteCMD > 0)
{

ZeroMemory(ucPacoteIN,SERIAL_MAX_RX);

switch(ucPacoteCMD[2])
{
case DC2:
if (isdigit(ucPacoteCMD[1]))
{
iRetry = 1;
ConcedePrivilegio(hSerial,((BYTE)ucPacoteCMD[1]
-48));
}
break;

case STX:
byPacoteCalcCRC = CalculaCRC
(ucPacoteCMD,iTamPacoteCMD-1);
byPacoteCRC = (BYTE)ucPacoteCMD[iTamPacoteCMD-1];
if (byPacoteCRC == byPacoteCalcCRC)
{
iRetry = 0;
if (isdigit(ucPacoteCMD[1]))
{

ConfControl.controladora = (BYTE)(
(ucPacoteCMD[1])- 48);
ConfControl.tentativas = 5;
ConcedePrivilegio(hSerial,((BYTE)ucPacoteCMD
[1]-48));
PurgeComm(hSerial, PURGE_RXCLEAR);
}
TraduzMens(ucPacoteCMD,iTamPacoteCMD);

/* teste do comando pede abastecimento
if (gets(cmd) != NULL)
{
y = dividePorCaractere(cmd," ",lista);

if (y > 1)
{
if (strcmp(lista[0],"abast") == 0)
{
PedeAbastecimentoManual(atoi(lista[1])
+100);
}
}
if (strcmp(cmd,"quit") == 0)
{
break;
}
}
*/
}
break;
}
}
}

}

}
DesativaEquipamento(true);
}

/*--------------------------------------------------------------------*/
/* until here */
/* cut */
/*--------------------------------------------------------------------*/
/* Main Exec Code */

/************************************************** *********************
main.cpp - The main() routine for all the "Basic Winsock" suite of
programs from the Winsock Programmer's FAQ. This function parses
the command line, starts up Winsock, and calls an external function
called DoWinsock to do the actual work.

This program is hereby released into the public domain. There is
ABSOLUTELY NO WARRANTY WHATSOEVER for this product. Caveat hacker.
************************************************** *********************/

#include "IThreadConnect.hpp"
#include "IGerenciadorEquipamento.hpp"
#include <windows.h>
#include <vector>
#include <algorithm>

using namespace std;

BOOL CtrlHandler(DWORD fdwCtrlType)
{
switch( fdwCtrlType )
{
// Handle the CTRL+C signal.
case CTRL_C_EVENT:
//printf( "Ctrl-C event\n\n" );
Beep( 750, 300 );
return( TRUE );

// CTRL+CLOSE: confirm that the user wants to exit.
case CTRL_CLOSE_EVENT:
Beep( 600, 200 );
//printf( "Ctrl-Close event\n\n" );
return( TRUE );

// Pass other signals to the next handler.
case CTRL_BREAK_EVENT:
Beep( 900, 200 );
//printf( "Ctrl-Break event\n\n" );
return FALSE;

case CTRL_LOGOFF_EVENT:
Beep( 1000, 200 );
//printf( "Ctrl-Logoff event\n\n" );
return FALSE;

case CTRL_SHUTDOWN_EVENT:
Beep( 750, 500 );
//printf( "Ctrl-Shutdown event\n\n" );
return FALSE;

default:
return FALSE;
}
system("PAUSE");
}

//// main //////////////////////////////////////////////////////////////
int main(int argc, char* argv[])
{
IThreadConnect threadConnect(0);
IGerenciadorEquipamento gerente1("COM1", 9600, 8, SERIAL_PARITY_NONE);
// IGerenciadorEquipamento gerente2("COM3", 9600, 8, SERIAL_PARITY_NONE);
// IGerenciadorEquipamento gerente3("COM3", 9600, 8, SERIAL_PARITY_NONE);

vector<IGerenciadorEquipamento> vEquipamento;

if( SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE))
{

gerente1.AtivaEquipamento();
printf("1 - Connected ! \n");

}
else
printf( "\nERROR: Could not set control handler");
//system("PAUSE");
// exit(1);
}

/*--------------------------------------------------------------------*/
/* until here */
Best Regards,
Leandro

--
Message posted via http://www.dotnetmonster.com
Nov 17 '05 #1
6 2814
"Leandro Berti via DotNetMonster.com" <fo***@nospam.DotNetMonster.com> wrote in message news:<01******************************@DotNetMonst er.com>...
Hi All,

I wrote a code to do serial communication with an equipament.
When i use the code outside of threaded class it seens work properly,
but when i put inside a class and execute a thread in the first seconds the
communication is ok, later i receive read/write error.
I?ve been in MSDN site and there i discover that the read/write error is a
INVALID_HANDLE problem. But why??? I just create the serial communication
file and use it.
Anyone can help me?

Here is the code
/* cut */
/*--------------------------------------------------------------------*/
/* Main Class */

#ifndef _IGERENCIADOREQUIPAMENTO_H
#define _IGERENCIADOREQUIPAMENTO_H

#include <stdio.h>
#include <windows.h>

#define SERIAL_PARITY_NONE 0
#define SERIAL_PARITY_ODD 1
#define SERIAL_PARITY_EVEN 2

#define SERIAL_MAX_RX 256 // Input buffer max size
#define SERIAL_MAX_TX 256 // output buffer max size
#define SERIAL_CONNECTED 0
#define SERIAL_DISCONNECTED 1
#define SERIAL_DATA_SENT 2
#define SERIAL_DATA_ARRIVAL 3
#define SERIAL_RING 4
#define SERIAL_CD_ON 5
#define SERIAL_CD_OFF 6
#define SERIAL_DATA_RECV 7

#define SERIAL_SIGNAL_NBR 7

class IGerenciadorEquipamento;

typedef struct
{
HANDLE serialFD;
IGerenciadorEquipamento* pIGE;
}_SERIALCOM_IONICS;
class IGerenciadorEquipamento: public IThread
{

private:
HANDLE hSerial;
char *cPortaSerial;
DWORD dwBaudRate;
BYTE byByteSize;
BYTE byTipoParidade;
bool conectado;
bool bRX_In_Progress; // BOOL indicating if a
ReadFile is
// in progress
bool bTX_In_Progress; // BOOL indicating if a
WriteFile is
// in progress

unsigned char pacoteIN[256];
unsigned char pacoteOUT[256];

bool bConectado;

int ConfigTimeouts(COMMTIMEOUTS mCommtimeout);
int ConfigDCB(DCB mDCB);

public:
IGerenciadorEquipamento(char *mcPortaSerial, DWORD mdwBaudRate,
BYTE mbyByteSize, BYTE mbyiTipoParidade);
~IGerenciadorEquipamento();

int AtivaEquipamento(BOOL mbIniciaThread = true);
int DesativaEquipamento(BOOL mbFinalizaThread = true);
int EscreveMensagem(HANDLE hSerialCOM,unsigned char* mcMensagem, int
miTamanho);
int LeMensagem(HANDLE hSerialCOM,unsigned char* mcMensagem, int
miTamanho);
void PurgeSerial(void);
bool VerificaEstado(void);
int Run(void);
HANDLE GetSerialHND(void);
void OnSendRecv(void);
unsigned char *GetDadosRecebidos(void);
unsigned char *GetDadosEnviados(void);

int EnviaPOLLING(HANDLE hSerialCOM);
int ConcedePrivilegio(HANDLE hSerialCOM, BYTE byEndereco);
void TraduzMens(unsigned char *ucPacote, DWORD miTamanho);
DWORD IGerenciadorEquipamento::ExtraiCMD(unsigned char *ucPacoteIN,
DWORD dStartpos,
DWORD dQtdebytes,
unsigned char* ucPacoteOUT);
};

//DWORD WINAPI ComSendRecv(LPVOID p);
int ComSendRecv(LPVOID p);

#endif

/*--------------------------------------------------------------------*/
/* until here */
/* cut */
/*--------------------------------------------------------------------*/
/* Main Class Code */

//#define STRICT
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <conio.h>
#include <windows.h>
#include <iostream>
#include <math.h>
#include "IGerenciadorEquipamento.hpp"
#include "StringMethods.hpp"
#include "Consts.hpp"
#include "TipoProtocolo.hpp"

#define SIG_POWER_DOWN 0
#define SIG_READER 1
#define SIG_READ_DONE 2 // data received has been read
#define SIG_WRITER 3
#define SIG_DATA_TO_TX 4 // data waiting to be sent
#define SIG_MODEM_EVENTS 5
#define SIG_MODEM_CHECKED 6


using namespace std;
typedef struct
{
BYTE controladora;
BYTE tentativas;
bool detectaprot;
}STRU_CONFCONTROL;
STRU_CONFCONTROL ConfControl;

unsigned char *IGerenciadorEquipamento::GetDadosRecebidos(void)
{
return pacoteOUT;
}

unsigned char *IGerenciadorEquipamento::GetDadosEnviados(void)
{
return pacoteIN;
}

int IGerenciadorEquipamento::EnviaPOLLING(HANDLE hSerialCOM)
{
unsigned char ucPacoteIN[256];
unsigned char ucPacoteOUT[256];
int iTotalLido;

ZeroMemory(ucPacoteIN,3);

ucPacoteIN[0] = SYN;
ucPacoteIN[1] = '1';
ucPacoteIN[2] = 0x55;

EscreveMensagem(hSerialCOM ,ucPacoteIN,3);
iTotalLido=LeMensagem(hSerialCOM ,ucPacoteOUT,30);
if (iTotalLido)
{
if ((ucPacoteOUT[0] == SYN) && (ucPacoteOUT[1] == '1') &&
(ucPacoteOUT[2] == 0xAA))
ConfControl.detectaprot = false;
}
return iTotalLido;
}

int IGerenciadorEquipamento::ConcedePrivilegio(HANDLE hSerialCOM, BYTE
byEndereco)
{
unsigned char ucPacoteIN[256];
int iTotalEscrito;

ZeroMemory(ucPacoteIN,3);

// privilegio
ucPacoteIN[0] = SYN;
ucPacoteIN[1] = byEndereco+48;
ucPacoteIN[2] = ACK;

iTotalEscrito=EscreveMensagem(hSerialCOM ,ucPacoteIN,3);
return iTotalEscrito;
}

void IGerenciadorEquipamento::TraduzMens(unsigned char *ucPacote, DWORD
miTamanho)
{
int iCanal;
double dLitros;
char cPulsos[8];
double dPulsos;
char parcelaPacote;
char cInd;
int iInd;
int k;

dLitros = 0;
iCanal = ((((BYTE)ucPacote[1])-49)*8);
iInd = ucPacote[3] & 0x0F;

switch(iInd)
{
case 0:
iCanal += ((((BYTE)ucPacote[4])-47)+100);
printf("Bomba %i ligada\n",iCanal-100);
break;
case 1:
iCanal += ((((BYTE)ucPacote[4])-47)+100);
printf("Bomba %i desligada\n",iCanal-100);

dPulsos = 0;
k=0;
ZeroMemory(cPulsos,8);
for (int i=5;i<13;i++)
{
cPulsos[k] = ucPacote[i];
k++;
}
dPulsos = atof(cPulsos);

dLitros = round(dPulsos/1*100)/100;

if ((iCanal > 100) && (iCanal < 133))
{
printf("Bomba %i abasteceu %4.2f litros \n",iCanal-100, dLitros);
}
else
printf("Bomba %i abasteceu %4.2f litros \n",iCanal-100, 0.00);

break;
case 7:
printf("APM Reenergizado\n");
break;
}
}

DWORD IGerenciadorEquipamento::ExtraiCMD(unsigned char *ucPacoteIN,
DWORD dStartpos,
DWORD dQtdebytes,
unsigned char* ucPacoteOUT)
{
int i;
DWORD dPosETX = 0;
DWORD dPosSTX = 0;
DWORD dPosDC2 = 0;
bool bOneMoreSYN;
bool bMensTexto;
bool bContinuar = true;
DWORD dBytesToSYN;
int iTotalBytes;

iTotalBytes = 0;
dBytesToSYN = 0;
bMensTexto = false;
bOneMoreSYN = true;
dPosETX = 0;
dPosSTX = 0;
dPosDC2 = 0;

for(i=dQtdebytes-1;(i>=0);i--)
{

if (bOneMoreSYN)
dBytesToSYN++;

switch(ucPacoteIN[i])
{
case SYN:
if ((dPosETX) && (dPosSTX) && ((dPosSTX-i) == 2) && (dQtdebytes
dPosETX))

{
bMensTexto = true;
bContinuar = false;
break;
}
else
{
if ((dPosDC2) && (dPosDC2-i) == 2)
{
if ((!bOneMoreSYN) && (dBytesToSYN > 0))
{
return iTotalBytes;
}
else
{
bContinuar = false;
break;
}
}
else
{
if (!bOneMoreSYN) { return 0; }
bOneMoreSYN = false;
dPosDC2 = 0;
dPosETX = 0;
dPosSTX = 0;
}

}
break;

case DC2: dPosDC2 = i; break;
case STX: dPosSTX = i; break;
case ETX: dPosETX = i; break;
}
if (!bContinuar) break;
}

if ((i != 0xFFFF) && (ucPacoteIN[i] == SYN))
{
if (bMensTexto)
dPosETX++;
else
dPosETX = dPosDC2;

for(int j=i;j<=dPosETX;j++)
{
ucPacoteOUT[iTotalBytes] = ucPacoteIN[j];
iTotalBytes++;
}
}
return iTotalBytes;
}
IGerenciadorEquipamento::IGerenciadorEquipamento(c har *mcPortaSerial,
DWORD mdwBaudRate,
BYTE mbyByteSize,
BYTE mbyTipoParidade)
{
cPortaSerial = mcPortaSerial;
dwBaudRate = mdwBaudRate;
mbyTipoParidade = mbyTipoParidade;
mbyByteSize = mbyByteSize;
hSerial = INVALID_HANDLE_VALUE;
conectado = false;
bRX_In_Progress = false;
bTX_In_Progress = false;
ConfControl.detectaprot = true;
ConfControl.tentativas = 0;
ConfControl.controladora = 0;

}

IGerenciadorEquipamento::~IGerenciadorEquipamento( )
{
conectado = false;
cPortaSerial = "";
dwBaudRate = 0;
byTipoParidade = SERIAL_PARITY_NONE;
byByteSize = 0;

if (GetThreadHND()!=0)
WaitForSingleObject(GetThreadHND(), 2000);

bRX_In_Progress = false;
bTX_In_Progress = false;
if (hSerial != INVALID_HANDLE_VALUE)
CloseHandle(hSerial);
hSerial = INVALID_HANDLE_VALUE;
}

int IGerenciadorEquipamento::ConfigTimeouts(COMMTIMEOU TS mCommtimeout)
{

// configura os timeouts da Porta Serial
mCommtimeout.ReadIntervalTimeout = 20;
mCommtimeout.ReadTotalTimeoutMultiplier = 1;
mCommtimeout.ReadTotalTimeoutConstant = 20;
mCommtimeout.WriteTotalTimeoutMultiplier = 5;
mCommtimeout.WriteTotalTimeoutConstant = 5;

return SetCommTimeouts(hSerial,&mCommtimeout);
}

int IGerenciadorEquipamento::ConfigDCB(DCB mDCB)
{
// recupera as informa??es do DCB
if (!GetCommState(hSerial,&mDCB))
{
CloseHandle(hSerial);
return ERROR_INVALID_HANDLE;
}
// set DCB to configure the serial port
mDCB.DCBlength = sizeof(mDCB);

/* ---------- Serial Port Config ------- */
mDCB.BaudRate = dwBaudRate;

switch(byTipoParidade)
{
case SERIAL_PARITY_NONE:
mDCB.Parity = NOPARITY;
mDCB.fParity = 0;
break;
case SERIAL_PARITY_EVEN:
mDCB.Parity = EVENPARITY;
mDCB.fParity = 1;
break;
case SERIAL_PARITY_ODD:
mDCB.Parity = ODDPARITY;
mDCB.fParity = 1;
break;
}
mDCB.StopBits = ONESTOPBIT;
mDCB.ByteSize = 8;
mDCB.fBinary = 0;
mDCB.fAbortOnError = 0;
mDCB.wReserved = 0;
mDCB.XonLim = 100;
mDCB.XoffLim = 100;
mDCB.XonChar = 0x0D;
mDCB.XoffChar = 0x0A;
mDCB.ErrorChar = 0;
mDCB.EofChar = 0;
mDCB.EvtChar = 0;
mDCB.wReserved1 = 0;

return SetCommState(hSerial,&mDCB);

}
int IGerenciadorEquipamento::AtivaEquipamento(BOOL mbIniciaThread)
{
int iErro;
DCB dcb;
int i;

COMMTIMEOUTS cto;
if (hSerial != INVALID_HANDLE_VALUE)
CloseHandle(hSerial);
hSerial = INVALID_HANDLE_VALUE;

if (cPortaSerial != "")
{
iErro = 0;

hSerial = CreateFile(cPortaSerial, // filename
GENERIC_READ | GENERIC_WRITE, // acesso
desejado
0, // modo de
compartilhamento
NULL, // atributos
de seguran?a
OPEN_EXISTING, // disposi??o
da cria??o do arquivo
FILE_FLAG_NO_BUFFERING,
// flag de cria??o
NULL); // indica se
pode ou n?o copiar os
// atributos do
arquivo atual para outro
// arquivo
if (hSerial != INVALID_HANDLE_VALUE)
{
bConectado = true;

// aplica os timeous
if (!ConfigTimeouts(cto))
iErro = 2;

// aplica o DCB
if (!ConfigDCB(dcb))
iErro = 4;

}
}
else
iErro = -2;
/* --------------------------------------------- */
if (iErro > 0)
{
CloseHandle(hSerial);
hSerial = INVALID_HANDLE_VALUE;
}
else
{

HANDLE hThread1;
DWORD dThreadID1;
if(mbIniciaThread)
{
printf("Connected ! \n");

hThread1 = CreateThread(NULL, // default
security attributes
0, // use default
stack size
(DWORD (_stdcall *)(void *))ComSendRecv,
// thread function
(void*)this, // argument to thread
function
0, // use default
creation flags
&dThreadID1); // returns the
thread identifier

*/

}
}

/* --------------------------------------------- */
return iErro;

}
int IGerenciadorEquipamento::DesativaEquipamento(BOOL mbFinalizaThread)
{
conectado = false;

if(mbFinalizaThread)
{

}
if (hSerial != INVALID_HANDLE_VALUE)
CloseHandle(hSerial);
hSerial = INVALID_HANDLE_VALUE;
if (this->GetThreadHND())
{
if (WaitForSingleObject (this->GetThreadHND(), 2000) == WAIT_TIMEOUT)
{
TerminateThread (this->GetThreadHND(), 1);
CloseHandle (this->GetThreadHND());
}
else CloseHandle (this->GetThreadHND());
}
CloseHandle(this->GetThreadHND());

printf("Disconnected ! \n");

}

int IGerenciadorEquipamento::EscreveMensagem(HANDLE hSerialCOM,unsigned
char* mcMensagem, int miTamanho)

{
char cTXBuffer[SERIAL_MAX_RX];
DWORD iQtdebytesEscritos;
int iTamanhoBuffer = 0;
int iSuccess = 0;
int Error = 0;
HANDLE hCom;


if (!bTX_In_Progress)
{
PurgeComm(hSerialCOM,PURGE_TXCLEAR | PURGE_RXCLEAR);
//hCom = hSerialCOM;

iSuccess = WriteFile(hSerialCOM,
mcMensagem,
miTamanho,
&iQtdebytesEscritos,
NULL);

if (!iSuccess)
{
// failure
if((Error = GetLastError()) != ERROR_IO_PENDING )
printf("erro: %i , qtde: %i => WriteFile error (not pending)\
n", Error,iQtdebytesEscritos & 0xFFFF);
}

bTX_In_Progress = false;

}

return iQtdebytesEscritos;
}
int IGerenciadorEquipamento::LeMensagem(HANDLE hSerialCOM,unsigned char*
mcMensagem, int miTamanho)
{
DWORD iQtdebytesLidos;
DWORD iLenMensagem = 0;
int iSuccess = 0;
int Error = 0;
HANDLE hCom;

ZeroMemory(mcMensagem,SERIAL_MAX_RX);

if (!bRX_In_Progress)
{
// locking reading
bRX_In_Progress = true;
//hCom = hSerialCOM;

// starting a new read
iSuccess = ReadFile(hSerialCOM, // handle do arquivo
mcMensagem, // buffer de leitura
miTamanho, // n?mero de bytes a serem lidos
&iQtdebytesLidos, // n?mero de bytes realmente
lidos
NULL); // usado para leitura
concorrente
// da serial

if (!iSuccess)
{
// failure
if((Error = GetLastError()) != ERROR_IO_PENDING)
{
printf("erro: %i , qtde: %i => Readfile error (not pending)\
n", Error,iQtdebytesLidos & 0xFFFF);
}
}
bRX_In_Progress = false;
}

return iQtdebytesLidos;
}

void IGerenciadorEquipamento::PurgeSerial(void)
{
PurgeComm(hSerial,PURGE_TXCLEAR | PURGE_RXCLEAR);
}

bool IGerenciadorEquipamento::VerificaEstado(void)
{
// return (bRX_In_Progress || bTX_In_Progress);
}

int ComSendRecv(LPVOID p)
{
IGerenciadorEquipamento* pIGE;

pIGE = (IGerenciadorEquipamento*)p;

if (pIGE !=0)
return pIGE->Run();

}

BYTE CalculaCRC(unsigned char *msg, int qtdeBytes)
{
BYTE valor_crc = 0;

for (int i=0; i<=qtdeBytes-1;i++)
{
valor_crc += msg[i];
}
return valor_crc;
}

int IGerenciadorEquipamento::Run(void)
{
bool bDone;
unsigned char ucPacoteIN[256];
unsigned char ucPacoteOUT[256];
unsigned char ucPacoteCMD[256];
int iRetry;
BYTE byPacoteCRC, byPacoteCalcCRC;
// char *lista[3];

int iTotalLido = 0;
int iTamPacoteCMD = 0;

bDone = false;
bRX_In_Progress = false;
bTX_In_Progress = false;

GetLastError(); // just to clear any pending error

HANDLE hComm = hSerial;

char cmd[5];

while(!bDone)
{

Sleep(1000);

if (ConfControl.detectaprot)
EnviaPOLLING(hSerial);

if (ConfControl.controladora)
{
iTotalLido = LeMensagem(hSerial ,pacoteOUT,30);
if (iTotalLido)
{
ConcedePrivilegio(hSerial,ConfControl.controladora );
ConfControl.tentativas = 5;
}
ConfControl.tentativas--;
if (ConfControl.tentativas <= 0)
{
ConfControl.tentativas = 0;
ConfControl.controladora = 0;
}
}

ConcedePrivilegio(hSerial,0);

iRetry = 1;

while (iRetry >0)
{

iRetry--;

iTotalLido = LeMensagem(hSerial,ucPacoteOUT,30);
if (iTotalLido)
{
ZeroMemory(ucPacoteCMD,SERIAL_MAX_RX);

iTamPacoteCMD = ExtraiCMD
(ucPacoteOUT,1,iTotalLido,ucPacoteCMD);
if (iTamPacoteCMD > 0)
{

ZeroMemory(ucPacoteIN,SERIAL_MAX_RX);

switch(ucPacoteCMD[2])
{
case DC2:
if (isdigit(ucPacoteCMD[1]))
{
iRetry = 1;
ConcedePrivilegio(hSerial,((BYTE)ucPacoteCMD[1]
-48));
}
break;

case STX:
byPacoteCalcCRC = CalculaCRC
(ucPacoteCMD,iTamPacoteCMD-1);
byPacoteCRC = (BYTE)ucPacoteCMD[iTamPacoteCMD-1];
if (byPacoteCRC == byPacoteCalcCRC)
{
iRetry = 0;
if (isdigit(ucPacoteCMD[1]))
{

ConfControl.controladora = (BYTE)(
(ucPacoteCMD[1])- 48);
ConfControl.tentativas = 5;
ConcedePrivilegio(hSerial,((BYTE)ucPacoteCMD
[1]-48));
PurgeComm(hSerial, PURGE_RXCLEAR);
}
TraduzMens(ucPacoteCMD,iTamPacoteCMD);

/* teste do comando pede abastecimento
if (gets(cmd) != NULL)
{
y = dividePorCaractere(cmd," ",lista);

if (y > 1)
{
if (strcmp(lista[0],"abast") == 0)
{
PedeAbastecimentoManual(atoi(lista[1])
+100);
}
}
if (strcmp(cmd,"quit") == 0)
{
break;
}
}
*/
}
break;
}
}
}

}

}
DesativaEquipamento(true);
}

/*--------------------------------------------------------------------*/
/* until here */
/* cut */
/*--------------------------------------------------------------------*/
/* Main Exec Code */

/************************************************** *********************
main.cpp - The main() routine for all the "Basic Winsock" suite of
programs from the Winsock Programmer's FAQ. This function parses
the command line, starts up Winsock, and calls an external function
called DoWinsock to do the actual work.

This program is hereby released into the public domain. There is
ABSOLUTELY NO WARRANTY WHATSOEVER for this product. Caveat hacker.
************************************************** *********************/

#include "IThreadConnect.hpp"
#include "IGerenciadorEquipamento.hpp"
#include <windows.h>
#include <vector>
#include <algorithm>

using namespace std;

BOOL CtrlHandler(DWORD fdwCtrlType)
{
switch( fdwCtrlType )
{
// Handle the CTRL+C signal.
case CTRL_C_EVENT:
//printf( "Ctrl-C event\n\n" );
Beep( 750, 300 );
return( TRUE );

// CTRL+CLOSE: confirm that the user wants to exit.
case CTRL_CLOSE_EVENT:
Beep( 600, 200 );
//printf( "Ctrl-Close event\n\n" );
return( TRUE );

// Pass other signals to the next handler.
case CTRL_BREAK_EVENT:
Beep( 900, 200 );
//printf( "Ctrl-Break event\n\n" );
return FALSE;

case CTRL_LOGOFF_EVENT:
Beep( 1000, 200 );
//printf( "Ctrl-Logoff event\n\n" );
return FALSE;

case CTRL_SHUTDOWN_EVENT:
Beep( 750, 500 );
//printf( "Ctrl-Shutdown event\n\n" );
return FALSE;

default:
return FALSE;
}
system("PAUSE");
}

//// main //////////////////////////////////////////////////////////////
int main(int argc, char* argv[])
{
IThreadConnect threadConnect(0);
IGerenciadorEquipamento gerente1("COM1", 9600, 8, SERIAL_PARITY_NONE);
// IGerenciadorEquipamento gerente2("COM3", 9600, 8, SERIAL_PARITY_NONE);
// IGerenciadorEquipamento gerente3("COM3", 9600, 8, SERIAL_PARITY_NONE);

vector<IGerenciadorEquipamento> vEquipamento;

if( SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE))
{

gerente1.AtivaEquipamento();
printf("1 - Connected ! \n");

}
else
printf( "\nERROR: Could not set control handler");
//system("PAUSE");
// exit(1);
}

/*--------------------------------------------------------------------*/
/* until here */
Best Regards,
Leandro

Hi Leandro

It seems that your primary thread creates the new thread and then
return and exit the process, causing the ~IGerenciadorEquipamento
destructor to run, hence closing the handle.

To find out if this is the problem, let the primary thread to Sleep()
after it creates the new thread.

Alon Fliess
Nov 17 '05 #2
Hi Alon,

Thanks for the help.
I try to put a Sleep() after the CreateThread() but doesn?t work and i mark
the breakpoint at the Destructor method and the execution don?t reach it.
The problem is at the beginning the communication work, then goes to
error state:
error: 6 => WriteFile error (not pending)
error: 6 => Readfile error (not pending)
Best Regards,
Berti

--
Message posted via http://www.dotnetmonster.com
Nov 17 '05 #3
Berti,

Can you tell if the handle value is the same right after you create it and
at the time when you get errors?

Your code looks ok (as long as you take into account Alon's suggestion).
One thing I'd suggest you change is replace CreateThread() with
_beginthread[ex](). You should not use the former in a multi-threaded
environment unless you are absolutely sure that your thread proc will not
call (implicitly or explicitly) runtime library functions that utilize
thread local storage.

I've written quite a bit of code that does rs232 to a lot of different
devices. Under Win32 I've done it with and without overlapped io and always
in a multi-threaded environment. This stuff seems to work fine. I don't
recall any gotchas. So, as in most of the cases, it's gotta be something in
your code :)

Bogdan
"Leandro Berti via DotNetMonster.com" <fo***@DotNetMonster.com> wrote in
message news:9f******************************@DotNetMonste r.com...
Hi Alon,

Thanks for the help.
I try to put a Sleep() after the CreateThread() but doesn?t work and i
mark
the breakpoint at the Destructor method and the execution don?t reach it.
The problem is at the beginning the communication work, then goes to
error state:
error: 6 => WriteFile error (not pending)
error: 6 => Readfile error (not pending)
Best Regards,
Berti

--
Message posted via http://www.dotnetmonster.com

Nov 17 '05 #4
Hi Bogdan,

Answering your first question the Handle value is the same in all the cases.
I try your sugestion changed the CreateThread() to _beginthread[ex] and
doesn't work.
That is very weird because everything seems ok.
Can you tell me more about that shouldn?t use CreatThread in a Multi-thread
environment?
And maybe send me (le***********@gmail.com) any code with multi-thread
architecture.

Best Regards,
Berti

--
Message posted via http://www.dotnetmonster.com
Nov 17 '05 #5
Berti,

It is very unlikely that CreateThread() vs _beginthread() issue is causing
your problems. Still, it is a good practice to use _beginthread() when you
use CRT. The compiler/linker will force you to use multi-threaded libraries
(one less thing to remember) and you'll make sure that all static buffers
are properly cleaned up when threads terminate. See "Multithreading"
(specifically "Multithreading with C and Win32") in MSDN.

Your problems might be caused by a lack of synchronization when it comes to
access to class members. You've got quite a bit of public methods (I'm not
sure if this is intentional) that could potentially lead to race conditions.
Some of the methods take a comm handle which is also confusing. Another
thing that you might try to avoid is to pass structures by value (e.g. DCB,
timeouts) - simply unnecessary burden on the stack.

I'd suggest that you start with refactoring the code so the serial comms
related stuff is not mixed with your application code. I'm pretty sure that
this would make it much easier for you and guys in this newsgroup to
troubleshoot problems.

Let's see if I can be of any help off-line. I'll send you an e-mail later
today.

Bogdan
"Leandro Berti via DotNetMonster.com" <fo***@DotNetMonster.com> wrote in
message news:e7******************************@DotNetMonste r.com...
Hi Bogdan,

Answering your first question the Handle value is the same in all the
cases.
I try your sugestion changed the CreateThread() to _beginthread[ex] and
doesn't work.
That is very weird because everything seems ok.
Can you tell me more about that shouldn?t use CreatThread in a
Multi-thread
environment?
And maybe send me (le***********@gmail.com) any code with multi-thread
architecture.

Best Regards,
Berti

--
Message posted via http://www.dotnetmonster.com

Nov 17 '05 #6
"Leandro Berti via DotNetMonster.com" <fo***@DotNetMonster.com> wrote in message news:<e7******************************@DotNetMonst er.com>...
Hi Bogdan,

Answering your first question the Handle value is the same in all the cases.
I try your sugestion changed the CreateThread() to _beginthread[ex] and
doesn't work.
That is very weird because everything seems ok.
Can you tell me more about that shouldn?t use CreatThread in a Multi-thread
environment?
And maybe send me (le***********@gmail.com) any code with multi-thread
architecture.

Best Regards,
Berti


CreateThread is a Win32 API that does not take into account the C++
runtime. When you call some of the C/C++ runtime functions, they may
need to refer to a buffer created and initiated by the runtime. The
main thread creates this buffer before it calls your main() function.
In MT program, each thread should use its own buffer, so there has to
be a way to create this buffer for each of them. Using the
_beginthread[ex]() function lets the runtime prepare this buffer. It
also add a default exception handler around your code (for un-handled
exceptions and ANSI-C signal handling, and handles the atexit()
function (hence it handles destructors of static objects in C++) ).
CreateThread still works because whenever you call a function that
needs the buffer it checks if the buffer does not exist, and if so it
creates one. however this buffer will stay in memory even if your
thread has exit and there will be no other c/c++ support (signal and
atexit()). If you use _beginthread, c/c++ runtime will free the
buffer. There is one case the C/C++ runtime can create/destroy the
buffer for you even if you use CreateThread, and it is when you use
the DLL version of the runtime. The runtime uses the
DLL_THREAD_ATTACHED/DETACHED to handle initialization/finalization.
In any case you always have to use the MT runtime (even if you use
CreateThread) and this is one of the main reason to use the
_beginthread[ex] function, it forces you to compile in MT.

After all this explanation, I don't think that CreateThread is your
problem.
First, check if you compile with the MT version of the runtime.
Second, use Process Explorer from www.sysinternals.com. Check if the
handle is valid (you may also see when it becomes invalid - it will
become red and will disappear).

Alon Fliess
CTO
The Sela Group
Nov 17 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Mike C. | last post by:
I am trying to get Java v1.4.2 to use my PCI add-on serial port. So far, everything I try gives me javax.comm.NoSuchPortException at...
0
by: David | last post by:
I have been having a problem trying to transfer Serial Communications code over to .NET Web Services. Needs to stay in C++ and as a web service. The code will open the serial comm port and...
1
by: Mike | last post by:
Sorry, don't know if this is the correct board for my question. I'm a novice so I guess I have a valid excuse My question : I'm using Visual C++ and I need to collect data from a serial port. ...
7
by: Michael Chong | last post by:
I wrote a program that communicate with SerialComm. In every 300 milliseconds, my program continuously send & receive data via the serial port once the program starts. My program is once in a...
0
by: coolsilver.net | last post by:
I am not sure if I am in the right group. My problem is this: My VB.NET application prints to the Epson printer using Epson OPOS drivers. I have downloaded the Epson ADK for .NET from the...
12
by: ken | last post by:
Hello everyone, I'm new to visual VB and I am trying to setup communications to the outside world. I found the example listed below in the help section of Microsoft Visual Basic 2005 Express...
3
by: ... | last post by:
Hi I need to send a chr(255) to a serial port. When I send it, through comm.write (chr(255)) it sends a chr(63) ... in Hex, I write chr(&FF) and it actually sends chr(&3F) ... why does this...
0
by: joaquimfpinto | last post by:
Hi All, I've an application that write and read from different serial ports. I made a class with an object from Charon Communications. On the main form I create several instances of that...
3
by: John Dann | last post by:
Trying to learn Python here, but getting tangled up with variable scope across functions, modules etc and associated problems. Can anyone advise please? Learning project is a GUI-based...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.