📄 ecostest.cpp
字号:
// Start again delete [] arstrHostPort; // For the benefit of interactive users fprintf(stderr,"Warning - could not connect to any test servers\n"); goto Retry; } } else { goto Done; } } } Done: delete [] arstrHostPort; bool rc=(SERVER_READY==s); if(!rc){ CloseSocket(); } return rc;}// In this function we execute a test and can safely block doing so.// pParam is a char * pointing to host:port (we delete it)void CeCosTest::RemoteThreadFunc (void *pParam){ CeCosTestUtils::String strHost; int port=0; VTRACE("RemoteThreadFunc()\n"); bool bSchedule=(0==pParam); if(!bSchedule){ char *pszHostPort=(char *)pParam; VTRACE("RemoteThreadFunc() : Parsing hostPort\n"); bool b=CeCosTestUtils::ParseHostPort(pszHostPort,strHost,port); assert(b); VTRACE("Deleting pszHostPort\n"); delete [] pszHostPort; } if(ConnectForExecution(strHost,port)){ //m_pSock->SetSocketOptions(); if(Sim()){ // Open the file early to avoid setting up a connection pointlessly FILE *f1=fopen(m_strExecutable,"rb"); if(0==f1){ Log("Failed to open %s - %s\n",(const char *)m_strExecutable,strerror(errno)); } else { // send file size if(m_pSock->sendInteger(m_nFileSize)&&m_nFileSize>0){ int nBufSize=min(10000,m_nFileSize); char *buf=new char[nBufSize]; Trace("Sending [%d bytes]\n", m_nFileSize); int nToSend=m_nFileSize; while (nToSend>0){ int nRead=fread( buf, 1, nBufSize, f1); if(nRead<=0){ Log("Failure reading %s - %s\n",(const char *)m_strExecutable,strerror(errno)); break; } if(!send( buf, nRead, "executable")){ Log("Failure sending %s - %s\n",(const char *)m_strExecutable,(const char *)m_pSock->SocketErrString()); break; } nToSend-=nRead; } if(nToSend>0){ Trace("done [%d bytes sent]\n",m_nFileSize-nToSend); Log("Failed to transmit %s - %d/%d bytes sent\n",(const char *)m_strExecutable,m_nFileSize-nToSend,m_nFileSize); } else { Trace("done\n"); } delete [] buf; } fclose(f1); f1=0; WaitForRemoteCompletion(); CloseSocket(); } } else { CeCosTestUtils::String strHostPort; // Big timeout here because we have to wait for the target to be reset if(!m_pSock->recvString(strHostPort,"Port name",120*1000)){ Log("Failed to read host:port from server - %s\n",(const char *)m_pSock->SocketErrString()); } else if(!CeCosTestUtils::IsLegalHostPort(strHostPort)){ Log("%s\n",(const char *)strHostPort); } else { TRACE("Instructed to use %s\n",(const char *)strHostPort); m_pPort=new CPort(Target(), strHostPort, 0); RunLocal(); delete m_pPort; m_pPort=0; } // Tell the server we're through char cAck=123; m_pSock->send(&cAck,1,"Terminating ack"); } } else { Log(0==strHost.GetLength()?"Failed to connect to any host": "Failed to connect to %s:%d\n",(const char *)strHost,port); LOCKRESOURCES; const CTestResource **ar=0; int nChoices=CTestResource::GetMatches(m_ep,ar,/*bIgnoreLocking=*/true); if(nChoices>0){ for(int i=0;i<nChoices;i++){ const CTestResource *pResource=ar[i]; Log (" %s:%d %s\n", (const char *)pResource->Host(), pResource->Port(), Image(pResource->Query())); } } else { LogString("No hosts available to execute this test\n"); } UNLOCKRESOURCES; delete [] ar; } m_bSocketErrorOccurred=false; TRACE("RemoteThreadFunc(): Exiting\n");}// function run by thread to execute a test locallyvoid CeCosTest::LocalThreadFunc (void *pParam){ pParam; // prevent compiler warnings Trace("LocalThreadFunc - target=%s\n",Image(Target())); // Acquire a port (our caller may have done this for us) VTRACE("LocalThreadFunc():Tring to acquire a port\n"); if(0==m_pPort){ for(;;){ m_pPort=CPort::GetPort(m_ep); if(m_pPort||Cancelled==Status()){ break; } CeCosTestUtils::Sleep(2000); Trace("Waiting for a port\n"); } } VTRACE("\nPort acquired!\n"); if(Cancelled!=Status()){ // This means we have acquired a local port bool bTargetReady=false; if(Sim()||'\0'==*(m_pPort->ResetHost())){ bTargetReady=true; } else { for(int nTry=1;nTry<=3;nTry++){ int nErr; if(m_pPort->Reset(nErr, m_strOutput)){ if(0==m_strOutput.GetLength()){ Log("Could not reset target (board silent after power on) [attempt %d/3]\n",nTry); } else { bTargetReady=true; break; } } else { Log("Could not reset target [attempt %d/3] - rc=%d\n",nTry,nErr); } } } // we may proceed to execute the test if(bTargetReady){ SetStatus(NotStarted); if(!Sim() /*&& NOTIMEOUT==m_ep.ElapsedTimeout()*/){ // 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 m_ep.SetElapsedTimeout (1000*max(40,(m_nStrippedSize/nSpeed))); Trace("Timeout<-%d\n",1000*max(40,(m_nStrippedSize/nSpeed))); } if(NOTIMEOUT==m_ep.ActiveTimeout()){ m_ep.SetActiveTimeout(1000*(Sim()?300:30)); } { // Construct commands for gdb int i=0; CeCosTestUtils::String arstrGdbCmds[14]; // Tell gdb its paper size :-) arstrGdbCmds[i++]="set height 0"; arstrGdbCmds[i++]="set remotedebug 0"; if(arTargetInfo[Target()].pszGdbcmd){ arstrGdbCmds[i++]=arTargetInfo[Target()].pszGdbcmd; } if(Sim()){ arstrGdbCmds[i++]="load"; } else { // Standard incantations for hardware: if(0==strchr(m_pPort->Name(),':')){ arstrGdbCmds[i++].Format("set remotebaud %d",m_pPort->Baud()); } arstrGdbCmds[i++].Format("target remote %s",m_pPort->Name()); #ifdef _WIN32 // pass port name to GDB in lower case arstrGdbCmds[i-1].MakeLower(); #endif arstrGdbCmds[i++]="load"; } arstrGdbCmds[i++]="break cyg_test_exit"; arstrGdbCmds[i++]="break cyg_assert_fail"; if(/*start hack*/BreakpointsOperational()/*end hack*/){ arstrGdbCmds[i++]="break cyg_test_init"; } if(Sim()){ arstrGdbCmds[i++]="run"; switch(m_ep.Target()){ case TX39_minsim: arstrGdbCmds[i++]="set cyg_test_is_simulator=2"; break; case I386_Linux: arstrGdbCmds[i++]="set cyg_test_is_simulator=3"; break; default: arstrGdbCmds[i++]="set cyg_test_is_simulator=1"; break; } } else { arstrGdbCmds[i++]="cont"; // run the program } if(/*start hack*/BreakpointsOperational()/*end hack*/){ arstrGdbCmds[i++]="cont"; // continue from cyg_test_init breakpoint } // arstrGdbCmds[i++]="bt"; // stack traceback // run/cont command must be the last (logic in DriveGdb) assert(i<sizeof arstrGdbCmds/sizeof arstrGdbCmds[0]); // Invoke gdb: CeCosTestUtils::String strGdb(arTargetInfo[Target()].pszPrefix); strGdb+="-gdb"; Trace("Calling RunGdb\n"); /* for(int nAttempt=0;nAttempt<3;nAttempt++){ RunGdb(strGdb,arstrGdbCmds); if(NotStarted!=Status()){ break; } m_Status=NotStarted; } */ RunGdb(strGdb,arstrGdbCmds); } } } if(0!=m_pPort){ m_pPort->Release(); m_pPort=0; }}void CeCosTest::LogResult(){ const char *psz=ResultString(); Trace("%s\n",psz); ENTERCRITICAL; if(strLogFile.GetLength()>0){ FILE *f=fopen(strLogFile,"at"); // Append, create if necessary, text mode if(f){ fprintf(f,"%s\n",psz); fclose(f); } else { puts(psz); } } else { puts(psz); fflush(stdout); } LEAVECRITICAL;}void CeCosTest::SetLogFile (const char *pszFile){ strLogFile=pszFile;}void CeCosTest::SetStatus (StatusType status){ ENTERCRITICAL; if((int)status>(int)m_Status){ Trace("Status <- %s\n",Image(status)); m_Status=status; } LEAVECRITICAL;}bool CeCosTest::WaitForAllInstances(int nPoll,CeCosTestUtils::Duration nTimeout){ CeCosTestUtils::Time t0=CeCosTestUtils::Time::Now(); while(InstanceCount>0){ CeCosTestUtils::Sleep(nPoll); if(NOTIMEOUT!=nTimeout && CeCosTestUtils::Time::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 sscanf 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...static const char *arpszFormat[2]={ // For hardware: // 1999-01-15 17:24:36 Fireblade:5002 MN10300 sin.exe 219k/134k Pass sin Elapsed: download=106.3/117.0 Total=107.6 Max inactive=1.0/300.0 "%04d-%02d-%02d %02d:%02d:%02d " // CeCosTestUtils::Time "%15s " // Execution host:port "%16s " // Target "%30s " // Executable tail "%11s " // Result "%dk/%dk " // Sizes "Elapsed: D=" WFS "/" WFS " Total=" WFS " " // Times "E=" WFS "/" WFS " " "\"%s\"", // Title // For sim: // 1999-01-15 17:24:36 Fireblade:5002 MN10300 sin.exe 219k Pass sin Cpu: Total=106.3 Max inactive=1.0/300.0 "%04d-%02d-%02d %02d:%02d:%02d " // CeCosTestUtils::Time "%15s " // Execution host:port "%16s " // Target "%30s " // Executable tail "%11s " // Result "%dk/%dk " // Sizes "Cpu: Total=" WFS " " "E=" WFS "/" WFS " " // Times "\"%s\"" // Title
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -