Mercurial > ecos-v2_0-branch
comparison host/tools/ecostest/common/ResetAttributes.cpp @ 82:6736c52df507 ecos-sw-2000-04-14
Merge from eCos master repository on 2000-04-14-13:35:46-BST
| author | jlarmour |
|---|---|
| date | Tue, 18 Apr 2000 21:51:55 +0000 |
| parents | 435cced73e2f |
| children | 489eb5632bc3 |
comparison
equal
deleted
inserted
replaced
| 81:89fef2181d7d | 82:6736c52df507 |
|---|---|
| 36 #include "eCosTrace.h" | 36 #include "eCosTrace.h" |
| 37 #include "ResetAttributes.h" | 37 #include "ResetAttributes.h" |
| 38 | 38 |
| 39 const CResetAttributes CResetAttributes::NoReset; | 39 const CResetAttributes CResetAttributes::NoReset; |
| 40 | 40 |
| 41 CResetAttributes::CResetAttributes(LPCTSTR psz) : | |
| 42 // Default values: | |
| 43 m_nDelay(1000), | |
| 44 m_nReadTimeout(10*1000), | |
| 45 m_nBaud(38400) | |
| 46 { | |
| 47 // Remove spaces | |
| 48 while(*psz){ | |
| 49 if(!_istspace(*psz)){ | |
| 50 m_str+=*psz; | |
| 51 } | |
| 52 psz++; | |
| 53 } | |
| 54 } | |
| 55 | |
| 56 /* | |
| 41 LPCTSTR CResetAttributes::Image(int nErr) | 57 LPCTSTR CResetAttributes::Image(int nErr) |
| 42 { | 58 { |
| 43 switch(nErr){ | 59 switch(nErr){ |
| 44 case RESET_OK: | 60 case RESET_OK: |
| 45 return _T("RESET_OK"); | 61 return _T("RESET_OK"); |
| 59 default: | 75 default: |
| 60 return _T("Unknown reset error"); | 76 return _T("Unknown reset error"); |
| 61 break; | 77 break; |
| 62 } | 78 } |
| 63 } | 79 } |
| 64 | 80 */ |
| 65 void CResetAttributes::SuckThreadFunc() | 81 void CResetAttributes::SuckThreadFunc() |
| 66 { | 82 { |
| 67 m_strResetOutput.SetLength(0); | 83 m_strResetOutput=_T(""); |
| 68 | 84 |
| 69 // Board has apparently been powered on. Suck initial output. | 85 // Board has apparently been powered on. Suck initial output. |
| 70 String strMsg; | 86 ResetLog(String::SFormat(_T("Reading board startup output from %s with timeout of %d seconds..."),(LPCTSTR)m_strAuxPort,m_nReadTimeout/1000)); |
| 71 strMsg.Format(_T(">>> Reading board startup output from %s with timeout of %d seconds...\n"),(LPCTSTR)m_strAuxPort,m_nReadTimeout/1000); | |
| 72 ResetLog(strMsg); | |
| 73 | 87 |
| 74 enum {BUFSIZE=512}; | 88 enum {BUFSIZE=512}; |
| 75 TCHAR *buf=new TCHAR[BUFSIZE]; | 89 TCHAR buf[1+BUFSIZE]; |
| 76 memset(buf,0,BUFSIZE); // safety for string functions in IsValidReset | 90 memset(buf,0,BUFSIZE); // safety for string functions in IsValidReset |
| 77 TCHAR *c=buf; | |
| 78 do { | 91 do { |
| 79 unsigned int dwRead=0; | 92 unsigned int dwRead=0; |
| 80 // We are working in non-blocking mode | 93 // We are working in non-blocking mode |
| 81 if(m_Socket.Ok()){ | 94 if(m_Socket.Ok()){ |
| 82 if(!m_Socket.Peek(dwRead)||!m_Socket.recv(c,MIN(dwRead,(unsigned)BUFSIZE-(c-buf)))){ | 95 if(!m_Socket.Peek(dwRead)||!m_Socket.recv(buf,MIN(dwRead,BUFSIZE))){ |
| 83 break; | 96 break; |
| 84 } | 97 } |
| 85 } else if (!m_Serial.Read(c,BUFSIZE-(c-buf),dwRead)){ | 98 } else if (!m_Serial.Read(buf,BUFSIZE,dwRead)){ |
| 86 m_Serial.ClearError(); | 99 m_Serial.ClearError(); |
| 87 c=buf; | 100 continue; |
| 88 } | 101 } |
| 89 if(dwRead>0){ | 102 if(dwRead>0){ |
| 90 c[dwRead]=_TCHAR('\0'); | 103 buf[dwRead]=_TCHAR('\0'); |
| 91 { | 104 |
| 92 String str; | 105 // Remove unprintable characters |
| 93 for(const TCHAR *t=c;*t;t++){ | 106 String str; |
| 94 if(_istprint(*t)){ | 107 for(const TCHAR *t=buf;*t;t++){ |
| 95 str+=*t; | 108 if(_istprint(*t)){ |
| 96 } | 109 str+=*t; |
| 97 } | 110 } |
| 98 ResetLog(str); | 111 } |
| 99 } | 112 |
| 100 | 113 if(m_pfnReset){ |
| 101 for(int i=dwRead-1;i>=0;--i){ | 114 ENTERCRITICAL; |
| 102 if(c[i]<0x20 || c[i]>=0x7f){ | 115 m_pfnReset(m_pfnResetparam,str); |
| 103 // Control character - assume nothing up to this is of interest | 116 LEAVECRITICAL; |
| 104 i++; | 117 } |
| 105 dwRead-=i; | 118 |
| 106 memmove(c,c+i,dwRead); | 119 ResetLog(str); |
| 107 break; | 120 m_strResetOutput+=str; |
| 108 } | 121 |
| 109 } | 122 if(IsValidReset()){ |
| 110 c+=dwRead; | |
| 111 if(IsValidReset((void *)buf)){ | |
| 112 ResetLog(_T("\n>>> Valid reset determined\n")); | |
| 113 break; | 123 break; |
| 114 } | 124 } |
| 115 } else { // Nothing read | 125 // } else { // Nothing read |
| 116 Sleep(500); | 126 // CeCosThreadUtils::Sleep(50); |
| 117 } | 127 } |
| 118 } while (0==m_tResetOccurred || Now()-m_tResetOccurred<m_nReadTimeout); | 128 } while (0==m_tResetOccurred || Now()-m_tResetOccurred<m_nReadTimeout); |
| 119 m_strResetOutput=buf; | 129 |
| 120 delete [] buf; | 130 if(0==m_strResetOutput.size()){ |
| 121 if(0==m_strResetOutput.GetLength()){ | 131 ResetLog(_T("No response from board")); |
| 122 ResetLog(_T("\n>>> No response from board\n")); | 132 } else { |
| 133 if(m_pfnReset){ | |
| 134 ENTERCRITICAL; | |
| 135 m_pfnReset(m_pfnResetparam,_T("\n")); | |
| 136 LEAVECRITICAL; | |
| 137 } | |
| 138 TRACE(_T("%s"),(LPCTSTR)m_strResetOutput); | |
| 123 } | 139 } |
| 124 } | 140 } |
| 125 | 141 |
| 126 bool CResetAttributes::Reset(Action action,bool bCheckOutput) | 142 bool CResetAttributes::Reset(Action action,bool bCheckOutput) |
| 127 { | 143 { |
| 144 m_tResetOccurred=0; | |
| 128 m_strResetOutput=_T(""); | 145 m_strResetOutput=_T(""); |
| 129 bool rc=false; | 146 bool rc=false; |
| 130 CeCosTestSocket sock; | 147 CeCosSocket sock; |
| 131 time_t ltime; | |
| 132 time(<ime); | |
| 133 struct tm *now=localtime( <ime ); | |
| 134 String strStatus; | 148 String strStatus; |
| 135 | 149 strStatus.Format(_T("Reset target using %s %s port=%s(%d) read timeout=%d delay=%d"), |
| 150 (LPCTSTR)m_strHostPort,(LPCTSTR)m_strControl, | |
| 151 (LPCTSTR)m_strAuxPort, m_nBaud, m_nReadTimeout, m_nDelay); | |
| 136 if(bCheckOutput){ | 152 if(bCheckOutput){ |
| 137 strStatus.Format(_T(">>> Reset target using %s %s port=%s(%d) read timeout=%d delay=%d [%02d:%02d:%02d]\n"), | 153 strStatus+=_T(" expect("); |
| 138 (LPCTSTR)m_strHostPort,(LPCTSTR)m_strControl, (LPCTSTR)m_strAuxPort, m_nBaud, m_nReadTimeout, m_nDelay, | 154 for(unsigned int i=0;i<m_arValidResetStrings.size();i++){ |
| 139 now->tm_hour,now->tm_min,now->tm_sec); | 155 if(i>0){ |
| 140 } else { | 156 strStatus+=_TCHAR(','); |
| 141 strStatus.Format(_T(">>> Reset target using %s %s delay=%d [%02d:%02d:%02d]\n"), | 157 } |
| 142 (LPCTSTR)m_strHostPort,(LPCTSTR)m_strControl, m_nDelay, | 158 strStatus+=m_arValidResetStrings[i]; |
| 143 now->tm_hour,now->tm_min,now->tm_sec); | 159 } |
| 160 strStatus+=_T(")"); | |
| 144 } | 161 } |
| 145 ResetLog(strStatus); | 162 ResetLog(strStatus); |
| 146 | 163 |
| 147 // Open up communication to port whence we read the board startup | 164 // Open up communication to port whence we read the board startup |
| 148 bool bThreadDone=false; | 165 bool bThreadDone=false; |
| 149 bCheckOutput&=(m_strAuxPort.GetLength()>0); | 166 bCheckOutput&=(m_strAuxPort.size()>0); |
| 150 if(bCheckOutput){ | 167 if(bCheckOutput){ |
| 151 TRACE(_T("Opening %s\n"),(LPCTSTR)m_strAuxPort); | 168 TRACE(_T("Opening %s\n"),(LPCTSTR)m_strAuxPort); |
| 152 String strHost; | 169 if(CeCosSocket::IsLegalHostPort(m_strAuxPort)){ |
| 153 int nPort; | |
| 154 if(CeCosTestSocket::ParseHostPort(m_strAuxPort,strHost,nPort)){ | |
| 155 // tcp/ip port | 170 // tcp/ip port |
| 156 if(!m_Socket.Connect(strHost,nPort,m_nReadTimeout)){ | 171 if(!m_Socket.Connect(m_strAuxPort,m_nReadTimeout)){ |
| 157 String str; | 172 ResetLog(String::SFormat(_T("Failed to open %s - %s"),(LPCTSTR)m_strAuxPort,(LPCTSTR)m_Socket.SocketErrString())); |
| 158 str.Format(_T("Failed to open %s - %s\n"),(LPCTSTR)m_strAuxPort,(LPCTSTR)m_Socket.SocketErrString()); | |
| 159 ResetLog(str); | |
| 160 return false; | 173 return false; |
| 161 } | 174 } |
| 162 } else { | 175 } else { |
| 163 // Comms device | 176 // Comms device |
| 164 m_Serial.SetBlockingReads(false); | 177 m_Serial.SetBlockingReads(false); |
| 165 if(m_Serial.Open(m_strAuxPort,m_nBaud)){ | 178 if(m_Serial.Open(m_strAuxPort,m_nBaud)){ |
| 166 m_Serial.Flush(); | 179 m_Serial.Flush(); |
| 167 } else { | 180 } else { |
| 168 String str; | 181 ResetLog(String::SFormat(_T("Failed to open comms port %s - %s"),(LPCTSTR)m_strAuxPort,(LPCTSTR)m_Serial.ErrString())); |
| 169 str.Format(_T("Failed to open comms port %s - %s\n"),(LPCTSTR)m_strAuxPort,(LPCTSTR)m_Serial.ErrString()); | |
| 170 ResetLog(str); | |
| 171 return false; | 182 return false; |
| 172 } | 183 } |
| 173 } | 184 } |
| 174 CeCosThreadUtils::RunThread(SSuckThreadFunc,this,&bThreadDone,_T("SSuckThreadFunc")); | 185 CeCosThreadUtils::RunThread(SSuckThreadFunc,this,&bThreadDone,_T("SSuckThreadFunc")); |
| 175 } else { | 186 } else { |
| 176 ResetLog(_T(">>> [not checking output]\n")); | 187 ResetLog(_T("[not checking output]")); |
| 177 } | 188 } |
| 178 | 189 |
| 179 String strHost; | |
| 180 int nPort; | |
| 181 // This will be true if we need to talk to a reset server, false to talk down a local port | 190 // This will be true if we need to talk to a reset server, false to talk down a local port |
| 182 bool bRemote=CeCosTestSocket::ParseHostPort(m_strHostPort,strHost,nPort); | 191 bool bRemote=CeCosSocket::IsLegalHostPort(m_strHostPort); |
| 183 if(bRemote){ | 192 if(bRemote){ |
| 184 if(sock.Connect(strHost,nPort,10*1000)){ | 193 if(sock.Connect(m_strHostPort,10*1000)){ |
| 185 m_tResetOccurred=0; | |
| 186 // Write the message to the socket | 194 // Write the message to the socket |
| 187 String strCmd; | |
| 188 int nDelay=(action==ON_OFF || action==OFF_ON)?m_nDelay:0; | 195 int nDelay=(action==ON_OFF || action==OFF_ON)?m_nDelay:0; |
| 189 strCmd.Format(_T("-Control=%s -Action=%d -Delay=%d"),(LPCTSTR)m_strControl,action,nDelay); | 196 TRACE(_T("-Control=%s -Action=%d -Delay=%d"),(LPCTSTR)m_strControl,action,nDelay); |
| 190 TRACE(_T("-Control=%s -Action=%d -Delay=%d"),(LPCTSTR)m_strControl,action,0); | 197 if(sock.sendString(String::SFormat(_T("-Control=%s -Action=%d -Delay=%d"),(LPCTSTR)m_strControl,action,nDelay),_T("Reset control codes"), 10*1000)){ |
| 191 if(sock.sendString(strCmd,_T("Reset control codes"), 10*1000)){ | |
| 192 // Wait for an acknowledgement | 198 // Wait for an acknowledgement |
| 193 String strResponse; | 199 String strResponse; |
| 194 if(sock.recvString(strResponse, _T("Response"), 20*1000)){ | 200 if(sock.recvString(strResponse, _T("Response"), nDelay+20*1000)){ |
| 195 rc=(0==strResponse.GetLength()); | 201 rc=(0==strResponse.size()); |
| 196 if(!rc && m_pfnReset){ | 202 if(!rc && m_pfnReset){ |
| 197 String strMsg; | 203 ResetLog(String::SFormat(_T("Reset server reports error '%s'"),(LPCTSTR)strResponse)); |
| 198 strMsg.Format(_T("Reset server reports error '%s'\n"),(LPCTSTR)strResponse); | |
| 199 ResetLog(strMsg); | |
| 200 } | 204 } |
| 201 } else { | 205 } else { |
| 202 String str; | 206 ResetLog(String::SFormat(_T("Failed to read response from reset server %s - %s"),(LPCTSTR)m_strHostPort,(LPCTSTR)sock.SocketErrString())); |
| 203 str.Format(_T(">>> Failed to read response from reset server %s - %s\n"),(LPCTSTR)m_strHostPort,(LPCTSTR)sock.SocketErrString()); | |
| 204 ResetLog(str); | |
| 205 } | 207 } |
| 206 } else { | 208 } else { |
| 207 String str; | 209 ResetLog(String::SFormat(_T("Failed to contact reset server %s - %s"),(LPCTSTR)m_strHostPort,(LPCTSTR)sock.SocketErrString())); |
| 208 str.Format(_T(">>> Failed to contact reset server %s - %s\n"),(LPCTSTR)m_strHostPort,(LPCTSTR)sock.SocketErrString()); | |
| 209 ResetLog(str); | |
| 210 ResetLog(_T(">>> Failed to contact reset server\n")); | |
| 211 } | 210 } |
| 212 m_tResetOccurred=Now(); | 211 m_tResetOccurred=Now(); |
| 213 if(bCheckOutput){ | 212 if(bCheckOutput){ |
| 214 if(!rc){ | 213 if(!rc){ |
| 215 // force thread to time out | 214 // force thread to time out |
| 216 m_tResetOccurred=Now()-m_nReadTimeout; | 215 m_tResetOccurred=Now()-m_nReadTimeout; |
| 217 } | 216 } |
| 218 CeCosThreadUtils::WaitFor(bThreadDone); // do not apply a timeout - the thread has one | 217 CeCosThreadUtils::WaitFor(bThreadDone); // do not apply a timeout - the thread has one |
| 219 rc=IsValidReset((void *)(LPCTSTR)m_strResetOutput); | 218 rc=IsValidReset(); |
| 220 ResetLog(rc?_T(">>> Reset output valid\n"):_T("!!! Reset output invalid\n")); | 219 ResetLog(rc?_T("Reset output valid"):_T("Reset output INVALID")); |
| 221 } | 220 } |
| 222 } else { | 221 } else { |
| 223 String str; | 222 ResetLog(String::SFormat(_T("Failed to contact reset server %s - %s"),(LPCTSTR)m_strHostPort,(LPCTSTR)sock.SocketErrString())); |
| 224 str.Format(_T(">>> Failed to contact reset server %s - %s\n"),(LPCTSTR)m_strHostPort,(LPCTSTR)sock.SocketErrString()); | |
| 225 ResetLog(str); | |
| 226 ResetLog(_T(">>> Failed to contact reset server\n")); | |
| 227 } | 223 } |
| 228 } else { | 224 } else { |
| 229 // Sending something locally | 225 // Sending something locally |
| 230 m_tResetOccurred=Now(); | 226 m_tResetOccurred=Now(); |
| 231 unsigned int nWritten; | 227 unsigned int nWritten; |
| 232 m_Serial.Write((void *)(LPCTSTR)m_strControl,1,nWritten); | 228 m_Serial.Write((void *)(LPCTSTR)m_strControl,1,nWritten); |
| 233 if(bCheckOutput){ | 229 if(bCheckOutput){ |
| 234 CeCosThreadUtils::WaitFor(bThreadDone); // do not apply a timeout - the thread has one | 230 CeCosThreadUtils::WaitFor(bThreadDone); // do not apply a timeout - the thread has one |
| 235 rc=IsValidReset((void *)(LPCTSTR)m_strResetOutput); | 231 rc=IsValidReset(); |
| 236 ResetLog(rc?_T(">>> Reset output valid\n"):_T("!!! Reset output invalid\n")); | 232 ResetLog(rc?_T("Reset output valid"):_T("Reset output INVALID")); |
| 237 } | 233 } |
| 238 } | 234 } |
| 239 | 235 |
| 240 if(m_Socket.Ok()){ | 236 if(m_Socket.Ok()){ |
| 241 m_Socket.Close(); | 237 m_Socket.Close(); |
| 243 m_Serial.Close(); | 239 m_Serial.Close(); |
| 244 } | 240 } |
| 245 return rc && bCheckOutput; | 241 return rc && bCheckOutput; |
| 246 } | 242 } |
| 247 | 243 |
| 244 // We expect to be passed a string that starts with "xxx(yyy)" | |
| 245 // and the task is to extract xxx into strID and yyy into strArg | |
| 248 const TCHAR *CResetAttributes::GetIdAndArg (LPCTSTR psz,String &strID,String &strArg) | 246 const TCHAR *CResetAttributes::GetIdAndArg (LPCTSTR psz,String &strID,String &strArg) |
| 249 { | 247 { |
| 250 const TCHAR *cEnd=_tcschr(psz,_TCHAR('(')); | 248 const TCHAR *cEnd=_tcschr(psz,_TCHAR('(')); |
| 251 if(cEnd){ | 249 if(cEnd){ |
| 252 strID=String(psz,cEnd-psz); | 250 strID=String(psz,cEnd-psz); |
| 265 assert(false); | 263 assert(false); |
| 266 } | 264 } |
| 267 return 0; | 265 return 0; |
| 268 } | 266 } |
| 269 | 267 |
| 270 int CResetAttributes::GetArgs(LPCTSTR psz,StringArray &ar) | 268 // Do the reset |
| 271 { | |
| 272 ar.clear(); | |
| 273 if(0==*psz){ | |
| 274 return 0; | |
| 275 } else { | |
| 276 String str; | |
| 277 for(const TCHAR *c=psz;*c;c++){ | |
| 278 if(_TCHAR(',')==*c){ | |
| 279 ar.push_back(str); | |
| 280 str=_T(""); | |
| 281 } else { | |
| 282 str+=*c; | |
| 283 } | |
| 284 } | |
| 285 ar.push_back(str); | |
| 286 return ar.size(); | |
| 287 } | |
| 288 } | |
| 289 | |
| 290 // m_str will hold something like | |
| 291 // 3(off(ginga:5000,a1) delay(2000) on(,..com2,38400)) | |
| 292 CResetAttributes::ResetResult CResetAttributes::Reset (LogFunc *pfnLog, void *pfnLogparam,bool bCheckOnly) | 269 CResetAttributes::ResetResult CResetAttributes::Reset (LogFunc *pfnLog, void *pfnLogparam,bool bCheckOnly) |
| 293 { | 270 { |
| 294 m_pfnReset=pfnLog; | 271 m_pfnReset=pfnLog; |
| 295 m_pfnResetparam=pfnLogparam; | 272 m_pfnResetparam=pfnLogparam; |
| 296 | 273 |
| 297 const TCHAR *c; | 274 // First we clean up the reset string so as to make subsequent parsing less complicated. |
| 298 String str; | 275 // Spaces have already been removed in the ctor |
| 299 // Remove spaces | |
| 300 for(c=m_str;*c;c++){ | |
| 301 if(!_istspace(*c)){ | |
| 302 str+=*c; | |
| 303 } | |
| 304 } | |
| 305 | 276 |
| 306 // Check paren matching: | 277 // Check paren matching: |
| 307 int nNest=0; | 278 int nNest=0; |
| 308 for(c=str;*c;c++){ | 279 for(const TCHAR *c=m_str;*c;c++){ |
| 309 if(_TCHAR('(')==*c){ | 280 if(_TCHAR('(')==*c){ |
| 310 nNest++; | 281 nNest++; |
| 311 } else if(_TCHAR(')')==*c){ | 282 } else if(_TCHAR(')')==*c){ |
| 312 nNest--; | 283 nNest--; |
| 313 if(nNest<0){ | 284 if(nNest<0){ |
| 319 if(nNest>0){ | 290 if(nNest>0){ |
| 320 ResetLog(_T("Too many left parentheses")); | 291 ResetLog(_T("Too many left parentheses")); |
| 321 return INVALID_STRING; | 292 return INVALID_STRING; |
| 322 } | 293 } |
| 323 | 294 |
| 324 m_nReadTimeout=10*1000; | 295 return Parse(m_str,bCheckOnly); |
| 325 m_nBaud=38400; | 296 } |
| 326 m_nDelay=1000; | 297 |
| 327 | 298 // This function parses the reset string, whose form is something like: |
| 328 return Parse(str,bCheckOnly); | 299 // expect($T05) 3(off(ginga:5000,a1) delay(2000) on(ginga:5000,a1,com1,38400,10000)) |
| 329 } | 300 // It is recursive (which is another reason elementary syntax checking was carried out above) |
| 330 | 301 // and calls itself to perform repeats [e.g. 3(...)] |
| 331 // 3(off(ginga:5000,a1) delay(2000) on(,..com2,38400)) | |
| 332 CResetAttributes::ResetResult CResetAttributes::Parse (LPCTSTR psz,bool bCheckOnly) | 302 CResetAttributes::ResetResult CResetAttributes::Parse (LPCTSTR psz,bool bCheckOnly) |
| 333 { | 303 { |
| 304 enum {ARGSEP=_TCHAR(',')}; | |
| 334 bool bCheck=false; | 305 bool bCheck=false; |
| 335 for(const TCHAR *c=psz;*c;){ | 306 for(const TCHAR *c=psz;*c;){ |
| 336 String strID,strArg; | 307 String strID,strArg; |
| 337 c=GetIdAndArg(c,strID,strArg); | 308 c=GetIdAndArg(c,strID,strArg); |
| 338 if(0==c){ | 309 if(0==c){ |
| 339 ResetLog(_T("Invalid reset string")); | 310 ResetLog(_T("Invalid reset string")); |
| 340 return INVALID_STRING; | 311 return INVALID_STRING; |
| 341 } | 312 } |
| 342 | 313 |
| 343 if(isdigit(*(LPCTSTR)strID)){ | 314 if(isdigit(*(LPCTSTR)strID)){ |
| 315 // Process a repeat-until-reset. Syntax is n(resetstring) | |
| 344 int nRepeat=_ttoi(strID); | 316 int nRepeat=_ttoi(strID); |
| 345 if(0==nRepeat){ | 317 if(0==nRepeat){ |
| 346 ResetLog(_T("Invalid reset string")); | 318 ResetLog(_T("Invalid reset string")); |
| 347 return INVALID_STRING; | 319 return INVALID_STRING; |
| 348 } | 320 } |
| 354 if(RESET_OK==r||INVALID_STRING==r){ | 326 if(RESET_OK==r||INVALID_STRING==r){ |
| 355 return r; | 327 return r; |
| 356 } | 328 } |
| 357 } | 329 } |
| 358 } | 330 } |
| 331 } else if (_T("expect")==strID) { | |
| 332 // Expected string(s). e.g. expect(str1,str2,...). | |
| 333 strArg.Chop(m_arValidResetStrings,ARGSEP,true); | |
| 359 } else if (_T("port")==strID) { | 334 } else if (_T("port")==strID) { |
| 335 // Port information. e.g. port(com1,38400,1000) | |
| 336 // This information will apply to all subsequent actions until overwritten. | |
| 337 // Specifically args are: | |
| 360 // 0. Port | 338 // 0. Port |
| 361 // 1. Baud | 339 // 1. Baud |
| 362 // 2. Timeout | 340 // 2. Read timeout |
| 363 StringArray ar; | 341 StringArray ar; |
| 364 int nArgs=GetArgs(strArg,ar); | 342 int nArgs=strArg.Chop(ar,ARGSEP,true); |
| 365 if(nArgs>0 && ar[0].GetLength()){ | 343 if(nArgs>0 && ar[0].size()){ |
| 366 m_strAuxPort=ar[0]; | 344 m_strAuxPort=ar[0]; |
| 367 } | 345 } |
| 368 if(nArgs>1 && ar[1].GetLength()){ | 346 if(nArgs>1 && ar[1].size()){ |
| 369 m_nBaud=_ttoi(ar[1]); | 347 m_nBaud=_ttoi(ar[1]); |
| 370 } | 348 } |
| 371 if(nArgs>2 && ar[2].GetLength()){ | 349 if(nArgs>2 && ar[2].size()){ |
| 372 m_nReadTimeout=_ttoi(ar[2]); | 350 m_nReadTimeout=_ttoi(ar[2]); |
| 373 } | 351 } |
| 374 } else if (_T("off")==strID || _T("on")==strID || _T("on_off")==strID || _T("off_on")==strID) { | 352 } else if (_T("off")==strID || _T("on")==strID || _T("on_off")==strID || _T("off_on")==strID) { |
| 375 // args are: | 353 // Action information. e.g. off(ginga:500,A4,com1,38400,10000,1000) |
| 354 // Specifically args are: | |
| 376 // 0. Reset host:port | 355 // 0. Reset host:port |
| 377 // 1. Control string | 356 // 1. Control string |
| 378 // 2. Port | 357 // 2. Port |
| 379 // 3. Baud | 358 // 3. Baud |
| 380 // 4. Read timeout | 359 // 4. Read timeout |
| 381 // 5. Delay | 360 // 5. Delay |
| 382 StringArray ar; | 361 StringArray ar; |
| 383 int nArgs=GetArgs(strArg,ar); | 362 int nArgs=strArg.Chop(ar,ARGSEP,true); |
| 384 if(nArgs>0 && ar[0].GetLength()){ | 363 if(nArgs>0 && ar[0].size()){ |
| 385 m_strHostPort=ar[0]; | 364 m_strHostPort=ar[0]; |
| 386 } | 365 } |
| 387 if(nArgs>1 && ar[1].GetLength()){ | 366 if(nArgs>1 && ar[1].size()){ |
| 388 m_strControl=ar[1]; | 367 m_strControl=ar[1]; |
| 389 } | 368 } |
| 390 if(nArgs>2 && ar[2].GetLength()){ | 369 if(nArgs>2 && ar[2].size()){ |
| 391 m_strAuxPort=ar[2]; | 370 m_strAuxPort=ar[2]; |
| 392 } | 371 } |
| 393 if(nArgs>3 && ar[3].GetLength()){ | 372 if(nArgs>3 && ar[3].size()){ |
| 394 m_nBaud=_ttoi(ar[3]); | 373 m_nBaud=_ttoi(ar[3]); |
| 395 } | 374 } |
| 396 if(nArgs>4 && ar[4].GetLength()){ | 375 if(nArgs>4 && ar[4].size()){ |
| 397 m_nReadTimeout=_ttoi(ar[4]); | 376 m_nReadTimeout=_ttoi(ar[4]); |
| 398 } | 377 } |
| 399 if(nArgs>5 && ar[5].GetLength()){ | 378 if(nArgs>5 && ar[5].size()){ |
| 400 m_nDelay=_ttoi(ar[5]); | 379 m_nDelay=_ttoi(ar[5]); |
| 401 } | 380 } |
| 402 | 381 |
| 403 if(0==m_strHostPort.GetLength()){ | 382 if(0==m_strHostPort.size()){ |
| 404 ResetLog(_T("Failed to specify reset host:port")); | 383 ResetLog(_T("Failed to specify reset host:port")); |
| 405 return INVALID_STRING; | 384 return INVALID_STRING; |
| 406 } | 385 } |
| 407 | 386 |
| 408 Action action=ON; // prevent compiler warning | 387 Action action=ON; // prevent compiler warning |
| 419 if(!bCheckOnly && Reset(action,bCheck||action==ON_OFF||action==OFF_ON)){ | 398 if(!bCheckOnly && Reset(action,bCheck||action==ON_OFF||action==OFF_ON)){ |
| 420 return RESET_OK; | 399 return RESET_OK; |
| 421 } | 400 } |
| 422 bCheck ^= 1; | 401 bCheck ^= 1; |
| 423 } else if (_T("delay")==strID) { | 402 } else if (_T("delay")==strID) { |
| 424 TRACE(_T("Sleep %d\n"),_ttoi(strArg)); | 403 // Delay for a given time right now. e.g. delay(1000) |
| 404 // Specifically args are: | |
| 405 // 0. msec to delay | |
| 406 TRACE(_T("CeCosThreadUtils::Sleep %d\n"),_ttoi(strArg)); | |
| 425 if(!bCheckOnly){ | 407 if(!bCheckOnly){ |
| 426 Sleep(_ttoi(strArg)); | 408 CeCosThreadUtils::Sleep(_ttoi(strArg)); |
| 427 } | 409 } |
| 428 } else { | 410 } else { |
| 429 ResetLog(_T("Unrecognized command")); | 411 ResetLog(String::SFormat(_T("Unrecognized command '%s'"),(LPCTSTR)strID)); |
| 430 return INVALID_STRING; | 412 return INVALID_STRING; |
| 431 } | 413 } |
| 432 } | 414 } |
| 433 ResetLog(_T("!!! Target reset not verified\n")); | 415 ResetLog(_T("Target reset not verified")); |
| 434 return NOT_RESET; | 416 return NOT_RESET; |
| 435 } | 417 } |
| 436 | 418 |
| 419 // Log some output to the reset log function. | |
| 437 void CResetAttributes::ResetLog(LPCTSTR psz) | 420 void CResetAttributes::ResetLog(LPCTSTR psz) |
| 438 { | 421 { |
| 439 if(m_pfnReset){ | 422 if(m_pfnReset){ |
| 440 ENTERCRITICAL; | 423 ENTERCRITICAL; |
| 441 m_pfnReset(m_pfnResetparam,psz); | 424 m_pfnReset(m_pfnResetparam,String::SFormat(_T("%s >>> %s\n"),(LPCTSTR)CeCosTrace::Timestamp(),psz)); |
| 442 TRACE(_T("%s"),psz); | 425 TRACE(_T("%s"),psz); |
| 443 LEAVECRITICAL; | 426 LEAVECRITICAL; |
| 444 } | 427 } |
| 445 } | 428 } |
| 446 | 429 |
| 447 // This function determines whether the board startup has all that is required | 430 bool CResetAttributes::IsValidReset() |
| 448 // It is a hack because it has hardwired knowledge of what boards say at startup time | 431 { |
| 449 bool CALLBACK CResetAttributes::IsValidReset (void *pParam) | 432 unsigned int n=0; |
| 450 { | 433 ENTERCRITICAL; |
| 451 bool rc=false; | 434 for(int i=m_arValidResetStrings.size()-1;i>=0;--i){ |
| 452 LPCTSTR pszBuf=(LPCTSTR)pParam; | 435 if(_tcsstr(m_strResetOutput,m_arValidResetStrings[i])){ |
| 453 | 436 n++; |
| 454 // Look for $T or $S | 437 } |
| 455 LPCTSTR pcTpkt=_tcsstr(pszBuf,_T("$T")); | 438 } |
| 456 if(0==pcTpkt){ | 439 LEAVECRITICAL; |
| 457 pcTpkt=_tcsstr(pszBuf,_T("$S")); | 440 return n==m_arValidResetStrings.size(); |
| 458 } | 441 } |
| 459 | |
| 460 if(pcTpkt){ | |
| 461 // T packet ends with #hh | |
| 462 LPCTSTR d=_tcschr(pcTpkt,_TCHAR('#')); | |
| 463 if(d && d[1] && d[2]){ | |
| 464 rc=true; | |
| 465 } | |
| 466 } else if (_tcsstr(pszBuf,_T("cygmon> "))) { | |
| 467 rc=true; | |
| 468 } else { | |
| 469 LPCTSTR pBootp=_tcsstr(pszBuf,_T("BOOTP got ")); | |
| 470 if(pBootp){ | |
| 471 int i1,i2,i3,i4; | |
| 472 rc=(4==_stscanf(pBootp+10,_T("%d.%d.%d.%d"),&i1,&i2,&i3,&i4)); | |
| 473 } | |
| 474 } | |
| 475 return rc; | |
| 476 } | |
| 477 | |
| 478 bool CResetAttributes::IsValid() | |
| 479 { | |
| 480 return INVALID_STRING!=Reset (0,0,true); | |
| 481 } |
