📄 ecostest.cpp
字号:
String strHostPort,strOutput; // Big timeout here because we have to wait for the target to be reset // We do this: // do { // target ready indicator (0==fail, 1==ready, 2==fail and will retry) // any output so far // } while (2==target ready indicator) // read host:port if(GetTargetReady(strHostPort)){ ENTERCRITICAL; m_pPort=new CTestResource(Target(), strHostPort, 0); m_pPort->Use(); LEAVECRITICAL; RunLocal(); delete m_pPort; m_pPort=0; m_pSock->sendInteger(123,_T("Terminating ack")); m_pSock->Close(); rc=true; } } } TRACE(_T("RemoteThreadFunc(): Exiting\n")); return rc;}// Run the test locallybool CeCosTest::RunLocal(){ m_nRunCount++; bool rc=false; if(0==CTestResource::Count(m_ep)){ Log(_T("Cannot run a %s test\n"),m_ep.Target()); } else { TRACE(_T("Run %s, timeouts: active=%d elapsed=%d\n"),(LPCTSTR )m_strExecutable, ActiveTimeout(), DownloadTimeout()); m_Status=NotStarted; m_tPrevSample=Now(); m_tGdbCpuTime=0; GetPath(m_strPath); TRACE(_T("LocalThreadFunc - target=%s\n"),Target()); // Acquire a port (our caller may have done this for us) VTRACE(_T("LocalThreadFunc():Tring to acquire a port\n")); if(0==m_pPort){ for(;;){ m_pPort=CTestResource::GetResource(m_ep); if(m_pPort||Cancelled==Status()){ break; } Sleep(2000); TRACE(_T("Waiting for a port\n")); } } VTRACE(_T("\nPort acquired!\n")); if(Cancelled!=Status()){ // This means we have acquired a local port bool bTargetReady=false; if(!m_pPort->HasReset()){ bTargetReady=true; } else { bTargetReady=(CResetAttributes::RESET_OK==Reset(false)); } // we may proceed to execute the test if(bTargetReady){ SetStatus(NotStarted); if(_TCHAR('\0')!=*(m_pPort->Serial())){ // No elapsed timeout given - calculate from knowledge of executable size and baud rate // 10 baud ~= 1 byte/sec, but we halve this to account for download in hex :-( // This means that a 200k executable is given ~100 seconds // In any case the whole thing is an overestimate [we should use the stripped size] // We use a minimum of 30 seconds and add 50% for safety int nSpeed=((0==m_pPort->Baud()?9600:m_pPort->Baud())/10)/2; // Hex nSpeed/=2; // Safety if(NOTIMEOUT==m_ep.DownloadTimeout()){ m_ep.SetDownloadTimeout (1000*MAX(60,(m_nStrippedSize/nSpeed))); } TRACE(_T("Timeout=%d\n"),m_ep.DownloadTimeout()); } if(NOTIMEOUT==m_ep.ActiveTimeout()){ m_ep.SetActiveTimeout(1000*(_TCHAR('\0')==*(m_pPort->Serial())?300:30)); } { // Construct commands for gdb const TargetInfo &t=Target(Target()); TargetInfo::HwType hwt=t.Type(); StringArray arstrGdbCmds; LPCTSTR pszPrompt; String strGdb; // running using gdb pszPrompt=_T("(gdb) "); strGdb.Format(_T("%s-gdb -nw %s"),t.Prefix(),(LPCTSTR)CygPath(m_strExecutable)); // Tell gdb its paper size :-) arstrGdbCmds.push_back(_T("set height 0")); arstrGdbCmds.push_back(_T("set remotedebug 0")); if(_TCHAR('\0')!=*t.GdbCmd()){ arstrGdbCmds.push_back(t.GdbCmd()); } String str; if(_TCHAR('\0')!=*(m_pPort->Serial())){ // Talking remotely if(CeCosTestSocket::IsLegalHostPort(m_pPort->Serial())){ // Talking to a tcp/ip socket arstrGdbCmds.push_back(_T("set watchdog 0")); } else { // Talking to a serial port str.Format(_T("set remotebaud %d"),m_pPort->Baud()); arstrGdbCmds.push_back(str); } str.Format(_T("target remote %s"),m_pPort->Serial());#ifdef _WIN32 // Serial names on windows must be in l.c. (gdb bug) for(TCHAR *c=str.GetBuffer();*c;c++){ if(isalpha(*c)){ *c=(TCHAR)_totlower(*c); } } str.ReleaseBuffer();#endif arstrGdbCmds.push_back(str); } if(TargetInfo::SYNTHETIC!=hwt){ arstrGdbCmds.push_back(_T("load")); } arstrGdbCmds.push_back(_T("break cyg_test_exit")); arstrGdbCmds.push_back(_T("break cyg_assert_fail")); if(/*start hack*/BreakpointsOperational()/*end hack*/){ arstrGdbCmds.push_back(_T("break cyg_test_init")); } switch(hwt){ case TargetInfo::SYNTHETIC: case TargetInfo::SIM: arstrGdbCmds.push_back(_T("run")); break; case TargetInfo::HARDWARE: case TargetInfo::HARDWARE_NO_BP: case TargetInfo::REMOTE_SIM: arstrGdbCmds.push_back(_T("cont")); // run the program break; default: assert(false); } if(BreakpointsOperational()){ str.Format(_T("set cyg_test_is_simulator=%d"),hwt); arstrGdbCmds.push_back(str); arstrGdbCmds.push_back(_T("cont")); // continue from cyg_test_init breakpoint } // run/cont command must be the last (logic in DriveGdb) TRACE(_T("Calling RunGdb\n")); RunGdb(strGdb,pszPrompt,arstrGdbCmds); rc=true; } } } TRACE(_T("LocalThreadFunc - releasing resource\n")); if(m_pPort){ m_pPort->Release(); m_pPort=0; } TRACE(_T("LocalThreadFunc - exiting\n")); } return rc;}void CeCosTest::Cancel (){ SetStatus(Cancelled);}CeCosTest::ServerStatus CeCosTest::Connect (String strHost,int port, CeCosTestSocket *&pSock, const ExecutionParameters &e,String &strInfo,Duration dTimeout){ // Find out whether this host is receptive ServerStatus s=CONNECTION_FAILED; pSock=new CeCosTestSocket(strHost,port,dTimeout); int nStatus; if(pSock->Ok() && pSock->sendString(e.Image(), _T("execution parameters")) && pSock->recvInteger(nStatus,_T("ready status")) && pSock->recvString(strInfo)){ s=(ServerStatus)MIN(nStatus,ServerStatusMax); } if(SERVER_READY!=s || ExecutionParameters::RUN!=e.Request()){ delete pSock; pSock=0; } return s;}// Initiate a connection to hostName:nPort and acquire the ready status [retry until this is achieved]// The socket (m_pSock) is left open.// This function is either called with m_strExecutionHostPort already set to a desired server// or else m_strExecutionHostPort empty (in which case the server is / dynamically)void CeCosTest::ConnectForExecution (){ bool bSchedule=(0==m_strExecutionHostPort.GetLength()); Duration nDelay=2000; m_pSock=0; bool *arbHostTried=0; while(Cancelled!=Status()){ StringArray arstrHostPort,arstrTries; int nChoices; if(bSchedule){ if(!CTestResource::GetMatches(m_ep,arstrHostPort)){ Log(_T("Could not establish matches\n")); continue; } nChoices=arstrHostPort.size(); if(nChoices>0){ TRACE(_T("ConnectForExecution: choices are:\n")); for(int i=0;i<nChoices;i++){ TRACE(_T("\t%s\n"),(LPCTSTR )arstrHostPort[i]); } } } else { // Server has already been picked by caller nChoices=1; String str; arstrHostPort.push_back(m_strExecutionHostPort); } if(nChoices>0){ delete [] arbHostTried; arbHostTried=new bool[nChoices]; for(int i=0;i<nChoices;i++){ arbHostTried[i]=false; } // Loop around the choices for(int nUntried=nChoices;nUntried>0;nUntried--) { // Select one we haven't tried already: int nChoice; do { nChoice=rand() % nChoices; } while (arbHostTried[nChoice]); m_strExecutionHostPort=arstrHostPort[nChoice]; TRACE(_T("ConnectForExecution: chosen %s\n"),(LPCTSTR )m_strExecutionHostPort); String strHost; int nPort; CeCosTestSocket::ParseHostPort(m_strExecutionHostPort, strHost, nPort); if(nPort){ // If we're using the resource server we had better check that the host // we are about to lock has not been resource-locked (the other match checks // will of course always succeed) String strInfo; ServerStatus s=bSchedule && !CTestResource::Matches(strHost, nPort,m_ep)?SERVER_LOCKED: Connect(strHost,nPort,m_pSock,m_ep,strInfo); arbHostTried[nChoice]=true; TRACE(_T("Connect: %s says %s %s\n"),(LPCTSTR )m_strExecutionHostPort,Image(s),(LPCTSTR )strInfo); CTestResource *pResource=CTestResource::Lookup(strHost,nPort); if(pResource){ String str; str.Format(_T("%s %s %s"),(LPCTSTR )pResource->Output(),(LPCTSTR )strInfo,Image(s)); arstrTries.push_back(str); } if(SERVER_READY==s){ // So that's ok then. We're outta here. Interactive(_T("Connected to %s\n"),(LPCTSTR )m_strExecutionHostPort); goto Done; } else { delete m_pSock; m_pSock=0; } } } } Interactive(_T("Warning - could not connect to any test servers:\n")); if(arstrTries.size()>0){ for(unsigned int i=0;i<arstrTries.size();i++){ Interactive(_T(" %s\n"),(LPCTSTR )arstrTries[i]); } } else { Interactive(_T("No servers available to execute %s test:\n"),m_ep.Target()); ENTERCRITICAL; for(CTestResource *pResource=CTestResource::First();pResource;pResource=pResource->Next()){ Interactive(_T(" %s\n"),(LPCTSTR )pResource->Output()); } LEAVECRITICAL; } Interactive(_T("Retry in %d seconds...\n"),nDelay/1000); // We have tried all possibilities - sleep before retrying Sleep(nDelay); if(Cancelled==m_Status){ TRACE(_T("ConnectForExecution : cancelled\n")); goto Done; } if(nDelay<20*1000){ nDelay+=rand() % 500; } }Done: delete [] arbHostTried;}void CeCosTest::LogResult(){ CeCosTrace::Out(ResultString()); CeCosTrace::Out(_T("\n") ); CeCosTrace::Trace(_T("%s\n"),ResultString());}void CeCosTest::SetStatus (StatusType status){ ENTERCRITICAL; if((int)status>(int)m_Status){ TRACE(_T("Status <- %s\n"),Image(status)); m_Status=status; } LEAVECRITICAL;}bool CeCosTest::WaitForAllInstances(int nPoll,Duration nTimeout){ Time t0=Now(); while(InstanceCount>0){ Sleep(nPoll); if(NOTIMEOUT!=nTimeout && Now()-t0>nTimeout){ return false; } } return true;}void CeCosTest::DeleteAllInstances(){ while(pFirstInstance){ delete pFirstInstance; }}void CeCosTest::CancelAllInstances(){ ENTERCRITICAL; for(CeCosTest *pTest=pFirstInstance;pTest;pTest=pTest->m_pNextInstance){ pTest->Cancel(); } LEAVECRITICAL;}// The same format is used for _stscanf as for Format (which is like printf), so restrict to the format specifiers// the former is happy with. In particular, do not use %-3s etc...LPCTSTR CeCosTest::pszFormat=// 1999-01-15 17:24:36 Fireblade:5002 MN10300 sin.exe 219k/134k Pass sin download=106.3/117.0 Total=107.6 Max inactive=1.0/300.0 _T("%04d-%02d-%02d %02d:%02d:%02d ") // Time_T("%15s ") // Execution host:port_T("%16s ") // Target_T("%30s ") // Executable tail_T("%11s ") // Result_T("%dk/%dk ") // Sizes_T("D=") WFS _T("/") WFS _T(" Total=") WFS _T(" ") // Times_T("E=") WFS _T("/") WFS _T(" ")_T("\"%s\"");bool CeCosTest::Value ( LPCTSTR pszStr, struct tm &t, StatusType &status, String &target, String &strExecutionHostPort, String &strExecutableTail, String &strTitle, int &nFileSize, Duration &nTotalTime, Duration &nMaxInactiveTime, Duration &nDownloadTime, Duration &nDownloadTimeout, Duration &nActiveTimeout, int &nDownloadedSize){ int nLen=_tcslen(pszStr); String strStatus; nFileSize=nTotalTime=nMaxInactiveTime=nDownloadTime=nDownloadTimeout=nActiveTimeout=nDownloadedSize=0; int nTotalTimeFrac=0; int nMaxInactiveTimeFrac=0; int nActiveTimeoutFrac=0; int nDownloadTimeFrac=0; int nDownloadTimeoutFrac=0; static String strFormat; if(0==strFormat.GetLength()){ // Construct a version of the format string sans length attributes for %s items LPCTSTR c=pszFormat; TCHAR *d=strFormat.GetBuffer(_tcslen(pszFormat)); while(_TCHAR('\0')!=*c){ if(_TCHAR('%')==c[0] && _istdigit(c[1])){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -