📄 bus232.cpp
字号:
StopTxTask = FALSE; // To indicate that the task has stopped
ExitThread(0);
}
#ifdef __TURBOC__
#pragma argsused
#endif
VOID Rx232Proc(PVOID unused)
{
unsigned long dwBytesRead;
uint8 tmp;
uint16 wReceive232Pos=0;
uint16 wDataLength;
uint8 bReceive232ElementArr[1000];
uint8 bReceiveState = 0;
uint8 bCkeckSum;
while(StopRxTask == FALSE)
{
ovlRd.Offset = 0;
ovlRd.OffsetHigh = 0;
ResetEvent(ovlRd.hEvent);
// use overlapped read, not because of async read, but, due to
// multi thread read/write
ReadFile( hComPortHandle, &tmp, 1, &dwBytesRead, &ovlRd );
GetOverlappedResult( hComPortHandle,
&ovlRd,
&dwBytesRead,
TRUE );
switch(bReceiveState)
{
case 0: // Receive DLE
if(tmp == 0x10)
{
bReceiveState = 1;
wReceive232Pos = 0;
bCkeckSum = 0;
#ifdef RSX
if(clRsx.iPrintBytes)
{
clRsx.Printf("\nI: ");
clRsx.Printf("%02X ", tmp);
}
#else
#ifdef SENDMAIL_DEBUG
printf("\nI: ");
printf("%02X ", tmp);
#endif
#endif
}
else
{
#ifdef RSX
if(clRsx.iPrintBytes)
clRsx.Printf("%02X ", tmp);
#else
#ifdef SENDMAIL_DEBUG
printf("%02X ", tmp);
#endif
#endif
}
break;
case 1: // Receive MSB of the length
#ifdef RSX
if(clRsx.iPrintBytes)
clRsx.Printf("%02X ", tmp);
#else
#ifdef SENDMAIL_DEBUG
printf("%02X ", tmp);
#endif
#endif
wDataLength = (uint16) (tmp*256);
if(wDataLength > MAX_PACKET_LENGTH)
{
#ifdef BUSM_HDLC
if (Rs232LogToFile)
{
fprintf(Rs232HdlcLogFile, "\n Rx Packet too long");
}
#endif
#ifdef RSX
if(clRsx.iPrintBytes)
clRsx.Printf("Packet too long %d ", wDataLength);
#else
#ifdef SENDMAIL_DEBUG
printf("Packet too long %d ", wDataLength);
#endif
#endif
if(tmp == 0x10)
{
//try staying in same state
}
else
{
bReceiveState = 0;
}
}
else
bReceiveState = 2;
break;
case 2: // Receive LSB of the length
#ifdef RSX
if(clRsx.iPrintBytes)
clRsx.Printf("%02X ", tmp);
#else
#ifdef SENDMAIL_DEBUG
printf("%02X ", tmp);
#endif
#endif
wDataLength += tmp;
if(wDataLength > MAX_PACKET_LENGTH)
{
#ifdef BUSM_HDLC
if (Rs232LogToFile)
{
fprintf(Rs232HdlcLogFile, "\n Rx Packet too long");
}
#endif
#ifdef RSX
if(clRsx.iPrintBytes)
clRsx.Printf("Packet too long %d ", wDataLength);
#else
#ifdef SENDMAIL_DEBUG
printf("Packet too long %d ", wDataLength);
#endif
#endif
if(tmp == 0x10)
{
bReceiveState = 1;
}
else
{
bReceiveState = 0;
}
}
else if(wDataLength < MIN_PACKET_LENGTH)
{
#ifdef RSX
if(clRsx.iPrintBytes)
clRsx.Printf("Packet too short: %d ", wDataLength);
#else
#ifdef SENDMAIL_DEBUG
printf("Packet too short: %d ", wDataLength);
#endif
#endif
bReceiveState = 0;
}
else
bReceiveState = 3;
break;
case 3: // Receive Data
#ifdef RSX
if(clRsx.iPrintBytes)
clRsx.Printf("%02X ", tmp);
#else
#ifdef SENDMAIL_DEBUG
printf("%02X ", tmp);
#endif
#endif
bReceive232ElementArr[wReceive232Pos] = tmp;
bCkeckSum += tmp;
wReceive232Pos++;
if(wReceive232Pos == wDataLength)
{
// Calculate checksum.
bReceiveState = 4;
}
break;
case 4: // Receive checksum
#ifdef RSX
if(clRsx.iPrintBytes)
{
clRsx.Printf("%02X ", tmp);
}
#else
#ifdef SENDMAIL_DEBUG
printf("%02X ", tmp);
#endif
#endif
#ifdef SIM_RS232_ERRORS
if (--BUSM_SimulateRxError==0)
{
bCkeckSum++;
#ifdef RSX
if(clRsx.iPrintBytes)
{
clRsx.Printf("\n Sim Rx Error");
}
#endif
BUSM_SimulateRxError = rand()&0x1F;
if (BUSM_SimulateTxError == 0) BUSM_SimulateTxError = 1;
}
#endif
if(bCkeckSum == tmp)
{
#ifdef BUSM_HDLC // Sliding window protocol
if (RsxSwpCheckReceivedFrame(bReceive232ElementArr))
{
// Received frame O.k.
#endif
#ifdef RSX
if(clRsx.iPrintBytes)
clRsx.Printf("CRC OK, Task %d, Program %d ", bReceive232ElementArr[1], bReceive232ElementArr[2]);
#else
#ifdef SENDMAIL_DEBUG
printf("CRC OK, Task %d, Program %d ", bReceive232ElementArr[1], bReceive232ElementArr[2]);
#endif
#endif
#ifdef RSX
if((bReceive232ElementArr[3] == 0x00) && (bReceive232ElementArr[4] == 0xff))
internal_SendPacketToTask(bReceive232ElementArr[2], wDataLength-3, &bReceive232ElementArr[3]); // test communication
else if((bReceive232ElementArr[1] == debug_ProgramId) || (debug_ProgramId<0))
{
debug_LogMailTrace(0x00, bReceive232ElementArr[2], wDataLength-3, &bReceive232ElementArr[3], MAILTRACE_TYPE_UART_INPUT_MAIL);
internal_SendPacketToTask(bReceive232ElementArr[2], wDataLength-3, &bReceive232ElementArr[3]);
}
else
cm_SendPacketToCm(bReceive232ElementArr[1], bReceive232ElementArr[2], wDataLength-3, &bReceive232ElementArr[3]);
#else
// Sendmail program
sendmail_ReceivePacket((uint16) (wDataLength-3), &bReceive232ElementArr[3]);
#endif
#ifdef BUSM_HDLC // Sliding window protocol
}
else
{
WrongFrame++;
}
#endif
}
else
{
#ifdef RSX
if(clRsx.iPrintBytes)
clRsx.Printf("CRC ERROR, Received %d, Cal %d ",tmp,bCkeckSum);
#endif
}
bReceiveState = 0;
break;
}
}
StopRxTask = FALSE; // To indicate that the task has stopped
ExitThread(0);
}
void CloseRs232(void)
{
// Stop the threads
StopTxTask = TRUE;
StopRxTask = TRUE;
StopRtsTask = TRUE;
PurgeComm(hComPortHandle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
while(StopTxTask || StopRxTask || StopRtsTask)
{
Sleep(100);
}
#ifdef BUSM_HDLC
fclose(Rs232HdlcLogFile);
#endif
CloseHandle(hComPortHandle);
}
void InitTestBus(void)
{
ovlRd.hEvent = CreateEvent( NULL,false,false,NULL );
ovlWr.hEvent = CreateEvent( NULL,false,false,NULL );
semTestbusFrameQueueSem = CreateMutex( NULL, FALSE, NULL );
#ifdef BUSM_HDLC
sHdlcControl.eHdlcState = BUSM_UNLOCKED;
semBusmHdlcSem = CreateMutex( NULL, FALSE, NULL );
#endif
}
void InitRs232(int Port, int BaudRate)
{
DCB dcb;
DWORD dwErrorCode;
BOOL fSuccess;
COMSTAT stat;
DWORD error;
COMMTIMEOUTS commtimeouts;
//DWORD dwEvtMask;
const char *PortName[] = {"COM1", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "COM10"};
#ifdef SIM_RS232_ERRORS
srand( (unsigned)time( NULL ) );
BUSM_SimulateRxError = (rand()&0x1F) + 1;
BUSM_SimulateTxError = (rand()&0x1F) + 1;
#endif
hComPortHandle = CreateFile(PortName[Port],
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL );
if(hComPortHandle == INVALID_HANDLE_VALUE)
{
dwErrorCode = GetLastError();
#ifdef RSX
PrintfInt("Failed to open %s! %lu\n", PortName[Port], dwErrorCode);
#endif
return;
}
ClearCommError( hComPortHandle, &error, &stat );
memset(&dcb, 0x0, sizeof(DCB) );
fSuccess = GetCommState(hComPortHandle, &dcb);
if(!fSuccess)
{
#ifdef RSX
PrintfInt("Failed to get DCB!\n");
#endif
return;
}
// Fill in the DCB
dcb.BaudRate = BaudRate;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fBinary = 1;
// disable all kind of flowcontrol and error handling
dcb.fOutxCtsFlow = 0;
dcb.fOutxDsrFlow = 0;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.fInX = 0;
dcb.fOutX = 0;
dcb.fErrorChar = 0;
dcb.fNull = 0;
dcb.fAbortOnError = 0;
fSuccess = SetCommState(hComPortHandle, &dcb);
if(!fSuccess)
{
#ifdef RSX
PrintfInt("Failed to set DCB!\n");
#endif
return;
}
commtimeouts.ReadIntervalTimeout = 1000;
commtimeouts.ReadTotalTimeoutMultiplier = 0;
commtimeouts.ReadTotalTimeoutConstant = 0;
commtimeouts.WriteTotalTimeoutMultiplier = 0;
commtimeouts.WriteTotalTimeoutConstant = 0;
fSuccess = SetCommTimeouts( hComPortHandle,
&commtimeouts );
// dwEvtMask = EV_TXEMPTY;
// fSuccess = SetCommMask(hComPortHandle,dwEvtMask);
StopTxTask = FALSE;
StopRxTask = FALSE;
StopRtsTask = FALSE;
Rx232Id = (HANDLE) _beginthread(Rx232Proc, 10000, NULL);
Tx232Id = (HANDLE) _beginthread(Tx232Proc, 10000, NULL);
RtsTaskId = (HANDLE) _beginthread(RtsProc, 10000, NULL);
// Set thread priorities
SetThreadPriority(Rx232Id, THREAD_PRIORITY_TIME_CRITICAL);
SetThreadPriority(Tx232Id, THREAD_PRIORITY_TIME_CRITICAL);
#ifdef RSX
PrintfInt("%s succesfully opened, baud rate %d\n", PortName[Port], BaudRate);
#endif
#ifdef BUSM_HDLC
for (int i=0;i<BUSM_HDLC_SEQ_MOD;i++)
{
NotAcknowledgeFramePtr[i] = NULL;
}
if((Rs232HdlcLogFile = fopen("Rs232trace.txt", "w")) == NULL)
{
// XXXX Udskriv fejlmeddelse.
#ifdef RSX
PrintfInt("Rs232 communication log file could not be opened \n");
#endif
}
else
{
SYSTEMTIME t;
Rs232LogToFile=TRUE;
GetLocalTime(&t);
fprintf(Rs232HdlcLogFile, " Logfile: Rs232trace.txt");
fprintf(Rs232HdlcLogFile, " Date: %d-%d-%d", t.wDay, t.wMonth, t.wYear);
fprintf(Rs232HdlcLogFile, " Time: %d.%02d\n\n", t.wHour, t.wMinute);
}
#ifdef RSX
PrintfInt("Using HDLC-like Protocol \n");
#endif
if (sHdlcControl.eHdlcState == BUSM_UNLOCKED)
{
bus232_SendUnnumberedFrame(0, 1); // Final flag set, wiat for Unnumbered frame response
sHdlcControl.eHdlcState = BUSM_LOCK_PENDING;
}
#endif
}
#ifndef BUSM_HDLC
void bus232_SendPacketToUnit(int iTaskId, int iLength, unsigned char *bInputDataPtr)
{
uint8 *bDataPtr = (uint8*) malloc(iLength + 7);
uint16 wDataLength = (uint16) (iLength + 3);
static uint8 bSequenceNumber = 0x00;
uint8 bCheckSum = 0;
uint16 i;
bSequenceNumber += (uint8) 0x10;
*(bDataPtr+0) = 0x10; // DLE
*(bDataPtr+1) = (uint8) ((wDataLength&0xff00)>>8); // Length MSB
*(bDataPtr+2) = (uint8) (wDataLength&0x00ff); // Length LSB
*(bDataPtr+3) = bSequenceNumber; // Sequence number
*(bDataPtr+4) = 0; // Program ID
*(bDataPtr+5) = (uint8) iTaskId; // Task ID
memcpy((bDataPtr+6), bInputDataPtr, iLength); // Data
for(i=0; i<wDataLength; i++)
bCheckSum += *(bDataPtr+3+i);
*(bDataPtr+6+iLength) = bCheckSum; // Checksum
WaitForSingleObject(semTestbusFrameQueueSem, INFINITE);
EnQueue(&TestbusFrameQueue, bDataPtr);
ReleaseMutex(semTestbusFrameQueueSem);
}
#endif
#ifdef BUSM_HDLC // Sliding window protocol
void bus232_SendPacketToUnit(int iTaskId, int iLength, unsigned char *bInputDataPtr)
{
BUSM_FrameType *bDataPtr,*pTempNoAckPtr;
uint16 wDataLength = (uint16) (iLength + 3);
BUSM_InfoFrameType bControl;
uint8 bCheckSum,i;
WaitForSingleObject(semBusmHdlcSem, INFINITE);
if (sHdlcControl.bTxNoAckCnt<BUSM_MAX_OUTSTANDING_FRAMES && sHdlcControl.eHdlcState == BUSM_LOCKED)
{
bDataPtr = (BUSM_FrameType*) malloc(iLength + sizeof(BUSM_FrameType));
pTempNoAckPtr = (BUSM_FrameType*) malloc(iLength + sizeof(BUSM_FrameType));
if(bDataPtr==NULL || pTempNoAckPtr==NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -