Ejemplo n.º 1
0
//! Task execution comes here
// NOTE: for interlaced cams
//       for exposures < 2460 ms the cam will aquire an exposure for each frame
//       i.e. 2.4 sec expo for F1 then send one frame then 2.4 sec for F2 then send the frame
//       i.e. the receiver thread must have enough time to capture the second one too
void Atik16Thread::Entry()
{
   // Sanity check
   if ( !m_pCaller ) {
      return; // immediately - this is messy - we cannot even reach our creator
   }

   // Thread actions
   const long WAIT_INTERVALL = 250;  // milliseconds

   // INIT
	m_exitCode = 0;         // task result
	bool done = false;      // task status
	bool readData = false;  // read status
	bool linger = false;    // something left to trash

   long toRead = 0;        // what do we have to read
   long nRead = 0;         // how much is left
	long readSize = 1;      // best read chuncksize
	long readCount= 0;      // counts the already read bytes

	const long InitNullReads = 20; // allow enough null reads (-> 20 sec)
	long nullReads = 0;     // read=0 counter to allow cam lag times

   unsigned char* pBuffer = NULL; // will hold the destination ptr

   ArtTimeHelper bpsTimer; // in read timer
   long Bps;               // Bytes per second value (DL rate)

   // Sanity check
   if ( m_dev.DevNULL() ) {
      m_exitCode = 2;
      done = true;
   }

   // Init FTD
   m_dev.ftd->SetDefaultBuffer();
   m_dev.ftd->SetTimeouts(CAM_RX_TIMEOUT, CAM_TX_TIMEOUT);
   m_pCaller->ProcessThreadStart(); // and down to the caller

   /* ----------------------------------------------------------- */
   while(!done)
   {
      if (m_aborted) {
         // task was aborted by some
         m_exitCode = 1;
         done = true;  // thread will die now
      }
      else {
         // process cam states
         switch (m_pCaller->m_camState) {
            case CAMERA_IDLE: {
               ;
            }// IDLE task
            break; // nothing to do ..

            case CAMERA_EXPOSING: {
               // the cam is now waiting for the exposure to end - next is either READING or FLUSHING
               m_waitMsRemaining = m_timeHelper.RemainingMSec(); //BM:20090410 - bugfix not showing EXP time
               if (m_abortExposure) {
                  // waiting ended with abort
                  OnWaitEnd(m_waitMsRemaining); // call with what's left
               }
               else if ( m_timeHelper.HasEnded() ) {
                  // waiting ended
                  OnWaitEnd(0);           // process below with 0 left
               }// expo done
               else {
                  ; // just wait
               }
            }// EXPO task
            break;

            case CAMERA_READING: {
               // the cam is reading the CCD - next is DOWNLOADING
               // not yet in reading state - now reading starts
               pBuffer = (unsigned char*)m_buffer; // where to write ??
               // note: this either reads the camera
               //       or does short exposures i.e. up to ~2.5 secs inplace
               m_elapsedMs = m_timeHelper.ElapsedMSec(); // real end duration just before CCD is read
               m_pCaller->ProcessTriggerRDCCD();         // issue the read command down to the camera

               // reading is done - we prepare DL
               toRead = m_aquiringLength; // get aquire size
               nRead  = toRead;           // set remaining amout
               linger = false;

               nullReads = InitNullReads;   // number of errors with read == 0 allowed
               readCount = 0;       // read counter (to calc DL percents)
               readSize = m_dev.ftd->GetAskSize();  // optimal ask size according to manual
               readData = true;     //reading now
               m_readErrorDetected = false;

               m_dev.ftd->SetTimeouts(1000, CAM_TX_TIMEOUT); // timeout - 20 retries in the thread
               m_pCaller->ProcessTriggerDownload(0);  // init DL with 0% done and update State
               bpsTimer.StartNow();                   // get the time to calc Bps later
               // triggers download processing
               if (m_abortExposure) {
                  m_pCaller->SetCameraState(CAMERA_FLUSHING); // immediate flush
               }
               else {
                  m_pCaller->SetCameraState(CAMERA_DOWNLOADING);
               }
            }// READING task
            break;

            case CAMERA_FLUSHING: {
               // just readout the cam if needed - next is IDLE again
               if (readData) {
                  // read remaining bytes from camera
                  // we cannot cancel data collection, once started
                  // so we have to read what's left
                  nullReads = InitNullReads;      // number of errors with read == 0 allowed
                  linger = (nRead>0) ? true : false; // something left
                  while (linger && (nullReads>0))
                  {
                     // do not longer gather data but read the buffers from USB if needed
                     // just read the rest (hogging)
                     size_t read;
                     if ( m_dev.ftd->ReadBYTEsNIL(read) ) {
                        nRead -= read;
                     }
                     else {
                        ::fprintf(stderr, "Atik16Thread - Error reading from camera while flushing !\n");
                        nullReads = 0; // force error exit
                        m_readErrorDetected = true;
                     }

                     if (read<=0) {
                        nullReads--; // make sure to get to an end once
                     }
                     else {
                        nullReads = InitNullReads; // reset nullreads after getting some
                     }
                     linger = (nRead>0) ? true : false; // something left
                  }
                  nRead = 0; // left to read is forced to 0 now
                  linger = false; // not longer
                  readData = false; // not longer
               }// was reading

               OnReadEnd(-1);
            }// FLUSHING task
            break;

            case CAMERA_DOWNLOADING: {
               // the cam is now downloading the image data - next is IDLE
               if (nRead>0) {
                  // still something to read
                  size_t read = 0;
                  // get data in chunks that should be optimal
                  if ( m_dev.ftd->ReadBYTEs(pBuffer, (nRead>=readSize)? readSize : nRead, read) ) {
                     // we have read something
                     if (read>0) {
                        // Regular Read: got something
                        readCount += read; nRead -= read;
                        pBuffer+=read; // advance dest ptr
                        if (toRead>0) m_pCaller->ProcessTriggerDownload((readCount *100) / toRead); // update DL status
                        nullReads = InitNullReads;  // reset Read Error counter once we got something
                        // continue with next round
                     }
                     else {
                        // Zero Read: read=0 - try more read
                        // again - here we may have to wait for the second 2.46 sec exposure - so be patient...
                        nullReads--;
                        _V_ ::fprintf(stdout, "Atik16Thread - Read 0 bytes: %ld - got %ld waitingfor %ld \n", nullReads, readCount, nRead);
                        if (nullReads<=0) {
                           // too many 0-reads, bail out - cam seems not longer responding (or we expected too much...)
                           ::fprintf(stderr, "Atik16Thread - too many 0 byte reads from camera!\n");
#ifdef _DEBUG
                           ::fprintf(stderr, "Atik16Thread - DEBUG continues!\n");
                           readData = false; // not longer
                           m_readErrorDetected = false; // we have a read error condition now
                           nRead=0;
                           OnReadEnd(0); // call my creator with success for debug
#else
                           readData = false; // not longer
                           m_readErrorDetected = true; // we have a read error condition now
                           nRead=0;
                           OnReadEnd(-1); // call my creator with failure
#endif
                           // this will terminate DL
                        }
                     }
                  }// read OK
                  else {
                     // IO Read Error: abort
                     ::fprintf(stderr, "Atik16Thread - Error reading from camera during download!\n");
                     readData = false; // not longer
                     m_readErrorDetected = true; // we have a read error condition now
                     nRead=0;
                     OnReadEnd(-1); // call my creator with failure
                     // this will terminate DL
                  }// read error
               }//if something to read

               else {
                  // regular read end
                  readData = false; // not longer
                  long dlTime =  long(bpsTimer.ElapsedMSec());
                  if (dlTime!=0) Bps = (toRead*1000) / dlTime; //bytes / sec
                  else           Bps = 1;
                  m_readErrorDetected = false;
                  OnReadEnd(Bps); // call my creator to indicate read end
                  // this will terminate DL
               }// DL done
            }// DOWNLOADING task
            break;

            default: {
            // other state such as CAMERA_ERROR
            // just waiting
            ;
            }//default
         }//switch

         if (!readData) m_dev.ftd->Sleep_ms(WAIT_INTERVALL);  // now wait a while if not reading

      }//not aborted
   }// thread loop

   OnThreadExit();      // call my creator to expect to shutdown things
}
Ejemplo n.º 2
0
void NTAPI OnTlsCallback(PVOID, DWORD dwReason, PVOID)
{
    if (dwReason == DLL_THREAD_DETACH) OnThreadExit();
}