📄 port.cpp
字号:
//=================================================================//// Port.cpp//// Port test class////=================================================================//####COPYRIGHTBEGIN####//// -------------------------------------------// The contents of this file are subject to the Cygnus eCos Public License// Version 1.0 (the "License"); you may not use this file except in// compliance with the License. You may obtain a copy of the License at// http://sourceware.cygnus.com/ecos// // Software distributed under the License is distributed on an "AS IS"// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the// License for the specific language governing rights and limitations under// the License.// // The Original Code is eCos - Embedded Cygnus Operating System, released// September 30, 1998.// // The Initial Developer of the Original Code is Cygnus. Portions created// by Cygnus are Copyright (C) 1998, 1999 Cygnus Solutions.// All Rights Reserved.// -------------------------------------------////####COPYRIGHTEND####//=================================================================//#####DESCRIPTIONBEGIN####//// Author(s): sdf// Contributors: sdf// Date: 1999-04-01// Description: This class abstracts the serial port for use in the testing infrastructure// Usage:////####DESCRIPTIONEND#####include "stdafx.h"#include "Port.h"#include "TestResource.h"#include "eCosTestUtils.h"#include "eCosTestSocket.h"// Hardware with resetCPort::CPort(CeCosTest::TargetType target, const char * pszDownloadPort, int nBaud, const char *pszResetHostPort, char cControl1, char cControl2, const char *pszAuxPort,int nDelay): m_strPort(pszDownloadPort), m_Target(target), m_bInUse(false), m_nBaud(nBaud), m_cControl1(cControl1), m_cControl2(cControl2), m_bSim(false), m_bLocked(false), m_strAuxPort(pszAuxPort), m_nDelay(nDelay){ // Decompose host:port TRACE("Created hw port : target=%s port=%s baud=%d reset=%s %c %c aux=%s\n", CeCosTest::Image(target),pszDownloadPort, nBaud,pszResetHostPort,cControl1,cControl2,(const char *)m_strAuxPort); bool b=CeCosTestUtils::ParseHostPort(pszResetHostPort, m_strResetHost, m_nResetPort); assert(b); Chain();}// Hardware without resetCPort::CPort(CeCosTest::TargetType target, const char * pszDownloadPort, int nBaud): m_strPort(pszDownloadPort), m_Target(target), m_bInUse(false), m_nBaud(nBaud), m_cControl1('\0'), m_cControl2('\0'), m_bSim(false), m_bLocked(false), m_nDelay(0){ TRACE("Created hw port : target=%s port=%s baud=%d\n",CeCosTest::Image(target),pszDownloadPort, nBaud); Chain();}// SimulatorCPort::CPort(CeCosTest::TargetType target): m_Target(target), m_bInUse(false), m_nBaud(0), m_cControl1('\0'), m_cControl2('\0'), m_bSim(true), m_bLocked(false), m_nDelay(0){ TRACE("Created sim port : target=%s\n",CeCosTest::Image(target)); Chain();}CPort::~CPort() { ENTERCRITICAL; if(pFirstInstance==this){ pFirstInstance=m_pNextInstance; } if(m_pPrevInstance){ m_pPrevInstance->m_pNextInstance=m_pNextInstance; } if(m_pNextInstance){ m_pNextInstance->m_pPrevInstance=m_pPrevInstance; } LEAVECRITICAL;}void CPort::Release (){ // No need to use a critical section here TRACE("Release port %s\n",Name()); m_bInUse=false; return;}// This function determines whether the board startup has all that is requiredstatic bool CALLBACK StopFunc (void *pParam){ const char *buf=(const char *)pParam; const char *tpkt=strstr(buf,"$T"); if(tpkt){ // T packet ends with #hh const char *d=strchr(tpkt,'#'); if(d && d[1] && d[2]){ return true; } } else if (strstr(buf,"cygmon> ")) { return true; } return false;}bool CPort::Reset(int &nErr, CeCosTestUtils::String &str){ str.SetLength(0); const int dTimeout=20*1000; bool rc=false; nErr=0; bool bReading=false; CeCosTestSocket *pSock=0; if(m_strResetHost.GetLength()==0){ rc=true; } else { const char *pszPort=m_strAuxPort.GetLength()>0 ?m_strAuxPort:m_strPort;TRACE("Reset port %s\n",pszPort); if(*pszPort){ if(0==strchr(pszPort,':')){ // Comms device m_Serial.SetReadTimeOuts(dTimeout,500); bReading=m_Serial.Open(pszPort,Baud()); if(!bReading){ TRACE("Failed to open comms port %s\n",pszPort); } } else { CeCosTestUtils::String strHost; int nPort; if(CeCosTestUtils::ParseHostPort(pszPort,strHost,nPort)){ pSock=new CeCosTestSocket(strHost,nPort,dTimeout); bReading=pSock->Ok(); if(!bReading){ TRACE("Failed to open %s\n",pszPort); } } else { TRACE("Illegal host:port %s\n",pszPort); } } } CeCosTestSocket sock(m_strResetHost,m_nResetPort,dTimeout); if(sock.Ok()){ // Write the message to the socket char send_buff[4]={0,m_cControl1,m_cControl2,(char)(m_nDelay/100)}; if(sock.send(send_buff, sizeof send_buff, "Reset control codes", dTimeout)){ // Wait for an acknowledgement if(!sock.recv(&nErr, 1, "Reset ack", dTimeout)){ TRACE("Failed to read ack\n"); nErr=sock.SocketError(); } else { rc=(0==nErr); } } else { TRACE("Failed to write to socket\n"); nErr=sock.SocketError(); } } else { nErr=sock.OpenRC(); } if(bReading){ if(rc){ // Board has apparently been powered on. Suck initial output. str.SetLength(0); TRACE("Reading board startup output from %s\n",pszPort); CeCosTestUtils::Time t=CeCosTestUtils::Time::Now(); enum {BUFSIZE=512}; char *buf=str.GetBuffer(BUFSIZE); memset(buf,0,BUFSIZE); // safety for string functions in StopFunc if(pSock){ // Single blocking read: StopFunc tells us when to stop pSock->recv(buf,BUFSIZE,"Startup",dTimeout,StopFunc,buf); } else { char *c=buf; do { unsigned int dwRead; if (!m_Serial.Read(c,BUFSIZE-(c-buf),dwRead)){ m_Serial.ClearError(); } else if(dwRead>0){ TRACE("Read %d bytes - '%s'\n",dwRead,c); c+=dwRead; break; } } while (CeCosTestUtils::Time::Now()-t<dTimeout); } str.ReleaseBuffer(); } m_Serial.Close(); } } delete pSock; return rc;}CPort *CPort::pFirstInstance=0;CPort *CPort::GetPort (const CeCosTest::ExecutionParameters &e){ CPort *p=0; if(0==Count(e)){ TRACE("GetPort: no candidates available\n"); } else { ENTERCRITICAL; for(p=pFirstInstance;p;p=p->m_pNextInstance){ if(p->Matches(e)&&!p->m_bInUse){ TRACE("Acquired port %s\n",p->Name()); p->m_bInUse=true; break; } } LEAVECRITICAL; } return p;}bool CPort::Lock (const CeCosTest::ExecutionParameters &e){ CPort *p=0; bool rc=false; if(0==Count(e)){ TRACE("GetPort: no candidates available\n"); } else { ENTERCRITICAL; for(p=pFirstInstance;p;p=p->m_pNextInstance){ if(p->Matches(e)&&!p->m_bInUse){ TRACE("Lock port %s\n",p->Name()); p->m_bLocked=true; rc=true; } } LEAVECRITICAL; } return rc;}void CPort::DeleteAllInstances(){ while(pFirstInstance){ delete pFirstInstance; }}CPort::GarbageCollector CPort::GarbageCollector::gc;CPort::GarbageCollector::GarbageCollector(){};CPort::GarbageCollector::~GarbageCollector(){ CPort::DeleteAllInstances();};int CPort::Count(const CeCosTest::ExecutionParameters &e){ int nCount=0; for(const CPort *p=pFirstInstance;p;p=p->m_pNextInstance){ if(p->Matches(e)){ nCount++; } } return nCount;}void CPort::Chain(){ ENTERCRITICAL; m_pNextInstance=pFirstInstance; if(m_pNextInstance){ m_pNextInstance->m_pPrevInstance=this; } m_pPrevInstance=0; pFirstInstance=this; LEAVECRITICAL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -