bool EMI1Layer2::leaveBusmonitor () { if (!Layer2::leaveBusmonitor ()) return false; TRACEPRINTF (t, 2, this, "CloseBusmon"); uchar t[] = { 0x46, 0x01, 0x00, 0x60, 0xc0 }; iface->Send_Packet (CArray (t, sizeof (t))); while (!iface->Send_Queue_Empty ()) { pth_event_t e = pth_event (PTH_EVENT_SEM, iface->Send_Queue_Empty_Cond ()); pth_wait (e); pth_event_free (e, PTH_FREE_THIS); } pth_usleep (1000000); return true; }
bool EMI1Layer2::enterBusmonitor () { if (!Layer2::enterBusmonitor ()) return false; const uchar t1[] = { 0x46, 0x01, 0x00, 0x60, 0x90 }; TRACEPRINTF (t, 2, this, "OpenBusmon"); iface->SendReset (); pth_usleep (1000000); iface->Send_Packet (CArray (t1, sizeof (t1))); if (!iface->Send_Queue_Empty ()) { pth_event_t e = pth_event (PTH_EVENT_SEM, iface->Send_Queue_Empty_Cond ()); pth_wait (e); pth_event_free (e, PTH_FREE_THIS); } return true; }
/** * More precise sleep() * * Portable usleep() function. * \param delay the amount of time to sleep */ void msleep( mtime_t delay ) { #if defined( HAVE_KERNEL_OS_H ) snooze( delay ); #elif defined( PTH_INIT_IN_PTH_H ) pth_usleep( delay ); #elif defined( ST_INIT_IN_ST_H ) st_usleep( delay ); #elif defined( WIN32 ) || defined( UNDER_CE ) Sleep( (int) (delay / 1000) ); #elif defined( HAVE_NANOSLEEP ) struct timespec ts_delay; ts_delay.tv_sec = delay / 1000000; ts_delay.tv_nsec = (delay % 1000000) * 1000; nanosleep( &ts_delay, NULL ); #else struct timeval tv_delay; tv_delay.tv_sec = delay / 1000000; tv_delay.tv_usec = delay % 1000000; /* select() return value should be tested, since several possible errors * can occur. However, they should only happen in very particular occasions * (i.e. when a signal is sent to the thread, or when memory is full), and * can be ignored. */ select( 0, NULL, NULL, NULL, &tv_delay ); #endif }
void BCU1SerialLowLevelDriver::Run (pth_sem_t * stop1) { pth_event_t stop = pth_event (PTH_EVENT_SEM, stop1); pth_event_t input = pth_event (PTH_EVENT_SEM, &in_signal); pth_event_t timeout = pth_event (PTH_EVENT_RTIME, pth_time (0, 10)); while (pth_event_status (stop) != PTH_STATUS_OCCURRED) { int error; timeout = pth_event (PTH_EVENT_RTIME | PTH_MODE_REUSE, timeout, pth_time (0, 150)); pth_event_concat (stop, input, timeout, NULL); pth_wait (stop); pth_event_isolate (stop); pth_event_isolate (input); timeout = pth_event (PTH_EVENT_RTIME | PTH_MODE_REUSE, timeout, pth_time (0, 200)); pth_event_concat (stop, timeout, NULL); struct timeval v1, v2; gettimeofday (&v1, 0); CArray e; CArray r; uchar s; if (!inqueue.isempty ()) { const CArray & c = inqueue.top (); e.resize (c () + 1); s = c () & 0x1f; s |= 0x20; s |= 0x80 * bitcount (s); e[0] = s; e.setpart (c, 1); } else { e.resize (1); e[0] = 0xff; } if (!startsync ()) { error = 1; goto err; } if (!exchange (e[0], s, stop)) { error = 3; goto err; } if (!endsync ()) { error = 2; goto err; } if (s == 0xff && e[0] != 0xff) { for (unsigned i = 1; i < e (); i++) { if (!startsync ()) { error = 1; goto err; } if (!exchange (e[i], s, stop)) { error = 3; goto err; } if (endsync ()) { error = 2; goto err; } } if (s != 0x00) { error = 10; goto err; } inqueue.get (); TRACEPRINTF (t, 0, this, "Sent"); pth_sem_dec (&in_signal); if (inqueue.isempty ()) pth_sem_set_value (&send_empty, 1); } else if (s != 0xff) { r.resize ((s & 0x1f)); for (unsigned i = 0; i < (s & 0x1f); i++) { if (!startsync ()) { error = 1; goto err; } if (!exchange (0, r[i], stop)) { error = 3; goto err; } if (!endsync ()) { error = 2; goto err; } } TRACEPRINTF (t, 0, this, "Recv"); outqueue.put (new CArray (r)); pth_sem_inc (&out_signal, 1); } gettimeofday (&v2, 0); TRACEPRINTF (t, 1, this, "Recvtime: %d", v2.tv_sec * 1000000L + v2.tv_usec - (v1.tv_sec * 1000000L + v1.tv_usec)); if (0) { err: gettimeofday (&v2, 0); TRACEPRINTF (t, 1, this, "ERecvtime: %d", v2.tv_sec * 1000000L + v2.tv_usec - (v1.tv_sec * 1000000L + v1.tv_usec)); setstat (getstat () & ~(TIOCM_RTS | TIOCM_CTS)); pth_usleep (2000); while ((getstat () & TIOCM_CTS)); TRACEPRINTF (t, 0, this, "Restart %d", error); } pth_event_isolate (timeout); } pth_event_free (timeout, PTH_FREE_THIS); pth_event_free (stop, PTH_FREE_THIS); pth_event_free (input, PTH_FREE_THIS); }
/** * Wait for a date * * This function uses select() and an system date function to wake up at a * precise date. It should be used for process synchronization. If current date * is posterior to wished date, the function returns immediately. * \param date The date to wake up at */ void mwait( mtime_t date ) { #if defined( HAVE_KERNEL_OS_H ) mtime_t delay; delay = date - real_time_clock_usecs(); if( delay <= 0 ) { return; } snooze( delay ); #elif defined( WIN32 ) || defined( UNDER_CE ) mtime_t usec_time, delay; usec_time = mdate(); delay = date - usec_time; if( delay <= 0 ) { return; } msleep( delay ); #else struct timeval tv_date; mtime_t delay; /* delay in msec, signed to detect errors */ /* see mdate() about gettimeofday() possible errors */ gettimeofday( &tv_date, NULL ); /* calculate delay and check if current date is before wished date */ delay = date - (mtime_t) tv_date.tv_sec * 1000000 - (mtime_t) tv_date.tv_usec - 10000; /* Linux/i386 has a granularity of 10 ms. It's better to be in advance * than to be late. */ if( delay <= 0 ) /* wished date is now or already passed */ { return; } # if defined( PTH_INIT_IN_PTH_H ) pth_usleep( delay ); # elif defined( ST_INIT_IN_ST_H ) st_usleep( delay ); # else # if defined( HAVE_NANOSLEEP ) { struct timespec ts_delay; ts_delay.tv_sec = delay / 1000000; ts_delay.tv_nsec = (delay % 1000000) * 1000; nanosleep( &ts_delay, NULL ); } # else tv_date.tv_sec = delay / 1000000; tv_date.tv_usec = delay % 1000000; /* see msleep() about select() errors */ select( 0, NULL, NULL, NULL, &tv_date ); # endif # endif #endif }