📄 o22siomm.cpp
字号:
//-----------------------------------------------------------------------------//// O22SIOMM.cpp// Copyright (c) 1999 - 2002 by Opto 22//// Source for the O22SnapIoMemMap C++ class. // // The O22SnapIoMemMap C++ class is used to communicate from a computer to an// Opto 22 SNAP Ethernet I/O unit.//// See the header file for more information on using this class.//// While this class was developed on Microsoft Windows 32-bit operating // systems, it is intended to be as generic as possible. For Windows specific// code, search for "_WIN32" and "_WIN32_WCE". For Linux specific code, search// for "_LINUX".//-----------------------------------------------------------------------------#ifndef __O22SIOMM_H_#include "O22SIOMM.h"#endif#ifdef _WIN32#define WINSOCK_VERSION_REQUIRED_MAJ 2#define WINSOCK_VERSION_REQUIRED_MIN 0#endif//added by added for vxworks #include "VxWorks.h"#include "sockLib.h"#include "inetLib.h"#include "stdioLib.h"#include "strLib.h"#include "ioLib.h"#include "fioLib.h"#include "time.h"#include "vxWorks.h"#include "wdLib.h"#include "iv.h"#include "vme.h"#include "net/mbuf.h"#include "net/unixLib.h"#include "net/protosw.h"#include "sys/socket.h"#include "sys/ioctl.h"#include "errno.h"#include "memLib.h"#include "intLib.h"#include "net/route.h"#include "iosLib.h"#include "errnoLib.h"#include "vxLib.h" #include "cacheLib.h"#include "logLib.h"#include "netLib.h"#include "stdio.h"#include "stdlib.h"#include "sysLib.h"#include "taskLib.h"#include "net/systm.h"#include "D:/tornado2.2/host/diab/include/sys/times.h"#include "net/if_subr.h"//end added O22SnapIoMemMap::O22SnapIoMemMap()//-------------------------------------------------------------------------------------------------// Constructor//-------------------------------------------------------------------------------------------------{ // Set defaults m_Socket = INVALID_SOCKET; m_byTransactionLabel = 0; m_nRetries = 0; m_nOpenTime = 0; m_nOpenTimeOutMS = 0; m_nTimeOutMS = 1000; m_tvTimeOut.tv_sec = m_nTimeOutMS / 1000; m_tvTimeOut.tv_usec = (m_nTimeOutMS % 1000) * 1000;} O22SnapIoMemMap::~O22SnapIoMemMap()//-------------------------------------------------------------------------------------------------// Destructor//-------------------------------------------------------------------------------------------------{ CloseSockets();#ifdef _WIN32 WSACleanup();#endif}LONG O22SnapIoMemMap::OpenEnet(char * pchIpAddressArg, long nPort, long nOpenTimeOutMS, long nAutoPUC)//-------------------------------------------------------------------------------------------------// Open a connection to a SNAP Ethernet I/O unit//-------------------------------------------------------------------------------------------------{ m_nAutoPUCFlag = nAutoPUC; m_nConnectionType = SIOMM_TCP; return OpenSockets(pchIpAddressArg, nPort, nOpenTimeOutMS);}LONG O22SnapIoMemMap::OpenEnet2(char * pchIpAddressArg, long nPort, long nOpenTimeOutMS, long nAutoPUC, long nConnectionType)//-------------------------------------------------------------------------------------------------// Open a connection to a SNAP Ethernet I/O unit//-------------------------------------------------------------------------------------------------{ m_nAutoPUCFlag = nAutoPUC; m_nConnectionType = nConnectionType; return OpenSockets(pchIpAddressArg, nPort, nOpenTimeOutMS);}LONG O22SnapIoMemMap::OpenSockets(char * pchIpAddressArg, long nPort, long nOpenTimeOutMS)//-------------------------------------------------------------------------------------------------// Use sockets to open a connection to the SNAP I/O unit//-------------------------------------------------------------------------------------------------{ int nResult; // for checking the return values of functions#ifdef _WIN32 // Initialize WinSock.dll WSADATA wsaData; // for checking WinSock nResult = WSAStartup( O22MAKEWORD( WINSOCK_VERSION_REQUIRED_MIN, WINSOCK_VERSION_REQUIRED_MAJ ), &wsaData ); if ( nResult != 0 ) { // We couldn't find a socket interface. return SIOMM_ERROR_NO_SOCKETS; } // Confirm that the WinSock DLL supports WINSOCK_VERSION if (( O22LOBYTE( wsaData.wVersion ) != WINSOCK_VERSION_REQUIRED_MAJ) || ( O22HIBYTE( wsaData.wVersion ) != WINSOCK_VERSION_REQUIRED_MIN)) { // We couldn't find an acceptable socket interface. WSACleanup( ); return SIOMM_ERROR_NO_SOCKETS; } #endif // If a socket is open, close it now. CloseSockets(); m_nOpenTimeOutMS = nOpenTimeOutMS; // Create the socket via TCP or UDP m_Socket = socket(AF_INET, m_nConnectionType, 0); if (m_Socket == INVALID_SOCKET) { // Couldn't create the socket#ifdef _WIN32 WSACleanup( );#endif return SIOMM_ERROR_CREATING_SOCKET; } // Make the socket non-blocking#ifdef _WIN32 // Windows uses ioctlsocket() to set the socket as non-blocking. // Other systems may use ioctl() or fcntl() unsigned long nNonBlocking = 1; if (SOCKET_ERROR == ioctlsocket(m_Socket, FIONBIO, &nNonBlocking))#endif#ifdef _LINUX if (-1 == fcntl(m_Socket,F_SETFL,O_NONBLOCK))#endifif((socket (AF_INET,SOCK_DGRAM,0))==ERROR)//gy added for vxworks 5.29 { CloseSockets(); return SIOMM_ERROR_CREATING_SOCKET; } // Setup the socket address structure m_SocketAddress.sin_addr.s_addr = inet_addr(pchIpAddressArg); m_SocketAddress.sin_family = AF_INET; m_SocketAddress.sin_port = htons((WORD)nPort); // attempt connection connect(m_Socket, (sockaddr*) &m_SocketAddress, sizeof(m_SocketAddress)); // Get the time for the timeout logic in IsOpenDone()#ifdef _WIN32 m_nOpenTime = GetTickCount(); // GetTickCount returns the number of milliseconds that have // elapsed since the system was started.#endif#ifdef _LINUX tms DummyTime; m_nOpenTime = times(&DummyTime); // times() returns the number of milliseconds that have // elapsed since the system was started.#endif return SIOMM_OK;}LONG O22SnapIoMemMap::CloseSockets()//-------------------------------------------------------------------------------------------------// Close the sockets connection//-------------------------------------------------------------------------------------------------{ // Close up everything if (m_Socket != INVALID_SOCKET) { #ifdef _WIN32 closesocket(m_Socket);#endif//#ifdef _LINUX close(m_Socket);//#endif } // Reset our data members memset(&m_SocketAddress, 0, sizeof(m_SocketAddress)); m_Socket = INVALID_SOCKET; m_nOpenTimeOutMS = 0; m_nOpenTime = 0; m_nRetries = 0; return SIOMM_OK;}LONG O22SnapIoMemMap::IsOpenDone()//-------------------------------------------------------------------------------------------------// Called after an OpenEnet() function to determine if the open process is completed yet.//-------------------------------------------------------------------------------------------------{ fd_set fds; timeval tvTimeOut; DWORD nOpenTimeOutTemp; DWORD dwPUCFlag; // a flag for checking the status of PowerUp Clear on the I/O unit long nResult; // for checking the return values of functions // Check the open timeout#ifdef _WIN32 nOpenTimeOutTemp = GetTickCount(); // GetTickCount returns the number of milliseconds that have // elapsed since the system was started. #endif#ifdef _LINUX tms DummyTime; nOpenTimeOutTemp = times(&DummyTime); // times() returns the number of milliseconds that have // elapsed since the system was started. #endif // Check for overflow of the system timer if (m_nOpenTime > nOpenTimeOutTemp) m_nOpenTime = 0; // Check for timeout if (m_nOpenTimeOutMS < (nOpenTimeOutTemp - m_nOpenTime)) { // Timeout has occured. CloseSockets(); return SIOMM_TIME_OUT; } FD_ZERO(&fds); FD_SET(m_Socket, &fds); // We want the select to return immediately, so set the timeout to zero tvTimeOut.tv_sec = 0; tvTimeOut.tv_usec = 100; // Use select() to check if the socket is connect and ready if (0 == select(m_Socket + 1, NULL, &fds, NULL, &tvTimeOut)) { // we're not connected yet! return SIOMM_ERROR_NOT_CONNECTED_YET; } // Okay, we must be connected if we get past the select() above. if (m_nAutoPUCFlag) { // Now, check the PowerUp Clear flag of the brain. It must be cleared // before can do anything with it (other than read the status area.) // Read PowerUp Clear flag nResult = ReadQuad(SIOMM_STATUS_READ_PUC_FLAG, &dwPUCFlag); // Check for good result from the ReadQuad() if (SIOMM_OK == nResult) { // the PUC flag will be TRUE if PUC is needed if (dwPUCFlag) { // Send PUC nResult = WriteQuad(SIOMM_STATUS_WRITE_OPERATION, 1); return nResult; } else { // Everything must be okay return SIOMM_OK; } } else // the ReadQuad() had an error { return SIOMM_ERROR; } } else { // Everything must be okay return SIOMM_OK; }}LONG O22SnapIoMemMap::SetCommOptions(LONG nTimeOutMS, LONG nReserved)//-------------------------------------------------------------------------------------------------// Set communication options//-------------------------------------------------------------------------------------------------{ // m_nRetries = nReserved; m_nTimeOutMS = nTimeOutMS; // Set the timeout that sockets will use m_tvTimeOut.tv_sec = m_nTimeOutMS / 1000; m_tvTimeOut.tv_usec = (m_nTimeOutMS % 1000) * 1000; return SIOMM_OK;}LONG O22SnapIoMemMap::BuildReadBlockRequest(BYTE * pbyReadBlockRequest, BYTE byTransactionLabel, DWORD dwDestinationOffset, WORD wDataLength)//-------------------------------------------------------------------------------------------------// Build a read block request packet//-------------------------------------------------------------------------------------------------{ // Destination Id pbyReadBlockRequest[0] = 0x00; pbyReadBlockRequest[1] = 0x00; // Transaction Label pbyReadBlockRequest[2] = byTransactionLabel << 2; // Transaction Code pbyReadBlockRequest[3] = SIOMM_TCODE_READ_BLOCK_REQUEST << 4; // Source Id pbyReadBlockRequest[4] = 0x00; pbyReadBlockRequest[5] = 0x00; // Destination Offset pbyReadBlockRequest[6] = 0xFF; pbyReadBlockRequest[7] = 0xFF; pbyReadBlockRequest[8] = O22BYTE0(dwDestinationOffset);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -