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(&ltime);
133 struct tm *now=localtime( &ltime );
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 }