예제 #1
0
    /*
     * PhxCommonWriteCxpReg()
     * Write to a 32 bit CXP register in camera.
     */
    public unsafe Phx.etStat PhxCommonWriteCxpReg(
        uint hCamera,   /* PHX handle */
        uint dwAddress, /* Address of the camera register */
        uint dwValue,   /* Value to write */
        uint dwTimeout  /* Timeout for operation */
        )
    {
        Phx.etStat eStat  = Phx.etStat.PHX_OK;
        uint       dwSize = sizeof(uint);

        dwValue = htonl(dwValue);

        eStat = Phx.PHX_ControlWrite(hCamera, Phx.etControlPort.PHX_REGISTER_DEVICE, ref dwAddress, ref dwValue, ref dwSize, dwTimeout);
        return(eStat);
    }
예제 #2
0
    /*
     * PhxCommonGetCxpDiscoveryStatus()
     * Checks if CXP camera is discovered.
     */
    public Phx.etStat PhxCommonGetCxpDiscoveryStatus(
        uint hCamera,
        uint dwTimeoutSec,
        ref bool fIsDiscovered
        )
    {
        Phx.etStat eStat   = Phx.etStat.PHX_OK;
        uint       dwIndex = 0;

        Console.WriteLine("Checking for CXP camera discovery...");

        fIsDiscovered = false;
        while (dwIndex++ < dwTimeoutSec * 2) /* Sleep between two attempts is only 500 ms */
        {
            Phx.etCxpInfo eDiscoveryStatus = 0;
            eStat = Phx.PHX_ParameterGet(hCamera, Phx.etParam.PHX_CXP_INFO, ref eDiscoveryStatus);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Exit;
            }
            if ((int)Phx.etCxpInfo.PHX_CXP_CAMERA_DISCOVERED == ((int)eDiscoveryStatus & (int)(Phx.etCxpInfo.PHX_CXP_CAMERA_DISCOVERED)))
            {
                fIsDiscovered = true;
                break;
            }

            Console.Write(".");

            System.Threading.Thread.Sleep(500);
        }
        Console.WriteLine("");

        if (fIsDiscovered)
        {
            Console.WriteLine("CXP camera is discovered.");
        }
        else
        {
            Console.WriteLine("CXP camera was not discovered.");
        }

Exit:
        return(eStat);
    }
예제 #3
0
        /// <summary>
        /// Write out the instrumented binary.
        /// </summary>
        /// <param name="unit">Instrumented unit.</param>
        protected override void Execute(Phx.Unit unit)
        {
            if (!unit.IsPEModuleUnit)
            {
                return;
            }

            // Write the instrumented binary
            Phx.PEModuleUnit executable = unit.AsPEModuleUnit;
            Phx.PE.Writer writer = Phx.PE.Writer.New(
                Phx.GlobalData.GlobalLifetime,
                Application.Output.GetValue(null),
                null, // Writing an instrumented PDB currently crashes
                executable,
                executable.SymbolTable,
                executable.Architecture,
                executable.Runtime);
            writer.Write();
        }
예제 #4
0
 /// <summary>
 /// Creates a new instance of the EmitPhase class.
 /// </summary>
 /// <param name="config">The phase list container.</param>
 /// <returns>New EmitPhase object.</returns>
 public static EmitPhase New(Phx.Phases.PhaseConfiguration config)
 {
     EmitPhase emitPhase = new EmitPhase();
     emitPhase.Initialize(config, "Emit");
     return emitPhase;
 }
 /// <summary>
 /// Encode the instrumented IR.
 /// </summary>
 /// <param name="unit">Instrumented unit.</param>
 protected override void Execute(Phx.Unit unit)
 {
     Phx.PE.Writer.EncodeUnit(unit);
 }
 /// <summary>
 /// Initializes a new instance of the EncodePhase class.
 /// </summary>
 /// <param name="config">The phase list container.</param>
 /// <returns>New EncodePhase object.</returns>
 public static EncodePhase New(Phx.Phases.PhaseConfiguration config)
 {
     EncodePhase encodePhase = new EncodePhase();
     encodePhase.Initialize(config, "Encode");
     return encodePhase;
 }
예제 #7
0
        /*
         * phxlive()
         * Simple live capture application code, using image conversion in order to reduce
         * the amount of PCI bandwidth used.
         */
        unsafe static int phxlive(
            Phx.etParamValue eBoardNumber,            /* Board number, i.e. 1, 2, or 0 for next available */
            Phx.etParamValue eChannelNumber,          /* Channel number */
            String strConfigFileName,                 /* Name of config file */
            PhxCommon.tCxpRegisters sCameraRegs       /* Camera CXP registers */
            )
        {
            Phx.etStat          eStat             = Phx.etStat.PHX_OK;           /* Status variable */
            Phx.etParamValue    eAcqType          = 0;                           /* Parameter for use with PHX_ParameterSet/Get calls */
            Pbl.etPblParamValue eBayCol           = 0;
            Phx.etParamValue    eParamValue       = 0;
            Pbl.etPblParamValue ePblCaptureFormat = 0;
            Phx.etParamValue    eCamSrcCol        = 0;
            Phx.etParamValue    eCaptureFormat    = Phx.etParamValue.PHX_BUS_FORMAT_MONO8;
            Phx.etParamValue    eCamFormat        = 0;
            uint      dwBufferReadyLast           = 0;                           /* Previous BufferReady count value */
            IntPtr    pParamValue = IntPtr.Zero;
            IntPtr    pConfigFile = IntPtr.Zero;
            PhxCommon myPhxCommon = new PhxCommon();

            Phx.PHX_AcquireCallBack PHX_Callback   = new Phx.PHX_AcquireCallBack(phxlive_callback);
            Phx.stImageBuff[]       asImageBuffers = null;                       /* Capture buffer array */
            uint[]   ahCaptureBuffers = null;                                    /* Capture buffer handle array */
            tPhxLive sPhxLive;                                                   /* User defined event context */
            uint     hCamera                = 0;                                 /* Camera handle */
            uint     hDisplay               = 0;                                 /* Display handle */
            uint     hDisplayBuffer         = 0;                                 /* Display buffer handle */
            uint     dwAcqNumBuffers        = 0;
            uint     dwBufferWidth          = 0;
            uint     dwBufferHeight         = 0;
            uint     dwBufferStride         = 0;
            uint     dwCamSrcDepth          = 0;
            bool     fDebayer               = false;
            bool     fCameraIsCxp           = false;
            bool     fIsCxpCameraDiscovered = false;


            /* Create a Phx handle */
            eStat = Phx.PHX_Create(ref hCamera, Phx.PHX_ErrHandlerDefault);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }

            /* Set the configuration file name */
            if (!String.IsNullOrEmpty(strConfigFileName))
            {
                pConfigFile = Marshal.UnsafeAddrOfPinnedArrayElement(PhxCommon.GetBytesFromString(strConfigFileName), 0);
                eStat       = Phx.PHX_ParameterSet(hCamera, Phx.etParam.PHX_CONFIG_FILE, ref pConfigFile);
                if (Phx.etStat.PHX_OK != eStat)
                {
                    goto Error;
                }
            }

            /* Set the board number */
            eStat = Phx.PHX_ParameterSet(hCamera, Phx.etParam.PHX_BOARD_NUMBER, ref eBoardNumber);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }

            /* Set the channel number */
            eStat = Phx.PHX_ParameterSet(hCamera, Phx.etParam.PHX_CHANNEL_NUMBER, ref eChannelNumber);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }

            /* Open the board using the above configuration file */
            eStat = Phx.PHX_Open(hCamera);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }

            /* Read various parameter values in order to generate the capture buffers. */
            eStat = Phx.PHX_ParameterGet(hCamera, Phx.etParam.PHX_ROI_XLENGTH, ref dwBufferWidth);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }
            eStat = Phx.PHX_ParameterGet(hCamera, Phx.etParam.PHX_ROI_YLENGTH, ref dwBufferHeight);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }
            eStat = Phx.PHX_ParameterGet(hCamera, Phx.etParam.PHX_CAM_SRC_DEPTH, ref dwCamSrcDepth);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }
            eStat = Phx.PHX_ParameterGet(hCamera, Phx.etParam.PHX_CAM_SRC_COL, ref eCamSrcCol);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }
            eStat = Phx.PHX_ParameterGet(hCamera, Phx.etParam.PHX_BUS_FORMAT, ref eCaptureFormat);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }
            eStat = Phx.PHX_ParameterGet(hCamera, Phx.etParam.PHX_CAM_FORMAT, ref eCamFormat);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }
            eStat = Phx.PHX_ParameterGet(hCamera, Phx.etParam.PHX_ACQ_FIELD_MODE, ref eAcqType);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }
            eStat = Phx.PHX_ParameterGet(hCamera, Phx.etParam.PHX_ACQ_NUM_BUFFERS, ref dwAcqNumBuffers);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }

            /* Interlaced Camera in Field Mode */
            if (Phx.etParamValue.PHX_CAM_INTERLACED == eCamFormat &&
                (Phx.etParamValue.PHX_ACQ_FIELD_12 == eAcqType ||
                 Phx.etParamValue.PHX_ACQ_FIELD_21 == eAcqType ||
                 Phx.etParamValue.PHX_ACQ_FIELD_NEXT == eAcqType ||
                 Phx.etParamValue.PHX_ACQ_FIELD_1 == eAcqType ||
                 Phx.etParamValue.PHX_ACQ_FIELD_2 == eAcqType))
            {
                dwBufferHeight /= 2;
            }

            /* Determine PHX_BUS_FORMAT based on the camera format */
            eStat = myPhxCommon.PhxCommonGetBusFormat(eCamSrcCol, dwCamSrcDepth, eCaptureFormat, ref eCaptureFormat);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }

            /* Determine bayer format */
            fDebayer = true;
            if (Phx.etParamValue.PHX_CAM_SRC_BAYER_BG == eCamSrcCol)
            {
                eBayCol = Pbl.etPblParamValue.PBL_BAY_COL_BLU;
            }
            else if (Phx.etParamValue.PHX_CAM_SRC_BAYER_GB == eCamSrcCol)
            {
                eBayCol = Pbl.etPblParamValue.PBL_BAY_COL_GRNB;
            }
            else if (Phx.etParamValue.PHX_CAM_SRC_BAYER_GR == eCamSrcCol)
            {
                eBayCol = Pbl.etPblParamValue.PBL_BAY_COL_GRNR;
            }
            else if (Phx.etParamValue.PHX_CAM_SRC_BAYER_RG == eCamSrcCol)
            {
                eBayCol = Pbl.etPblParamValue.PBL_BAY_COL_RED;
            }
            else
            {
                fDebayer = false;
            }

            /* Update the PHX_BUS_FORMAT, as it may have changed (above) */
            eStat = Phx.PHX_ParameterSet(hCamera, (Phx.etParam.PHX_BUS_FORMAT | Phx.etParam.PHX_CACHE_FLUSH), ref eCaptureFormat);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }

            /* Read back the Buffer Stride */
            eStat = Phx.PHX_ParameterGet(hCamera, Phx.etParam.PHX_BUF_DST_XLENGTH, ref dwBufferStride);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }

            /* Init the array of capture buffer handles */
            ahCaptureBuffers = new uint[dwAcqNumBuffers];

            /* Init the array of image buffers */
            asImageBuffers = new Phx.stImageBuff[dwAcqNumBuffers + 1];

            /* Create and initialise our capture buffers (not associated with display) */
            for (int i = 0; i < dwAcqNumBuffers; i++)
            {
                /* We create a capture buffer for our double buffering */
                eStat = Pbl.PBL_BufferCreate(ref ahCaptureBuffers[i], Pbl.etPblBufferMode.PBL_BUFF_SYSTEM_MEM_DIRECT, 0, hCamera, myPhxCommon.PhxCommonDisplayErrorHandler);
                if (Phx.etStat.PHX_OK != eStat)
                {
                    goto Error;
                }

                /* Initialise our capture buffer */
                eStat = Pbl.PBL_BufferParameterSet(ahCaptureBuffers[i], Pbl.etPblParam.PBL_BUFF_WIDTH, ref dwBufferWidth);
                if (Phx.etStat.PHX_OK != eStat)
                {
                    goto Error;
                }
                eStat = Pbl.PBL_BufferParameterSet(ahCaptureBuffers[i], Pbl.etPblParam.PBL_BUFF_HEIGHT, ref dwBufferHeight);
                if (Phx.etStat.PHX_OK != eStat)
                {
                    goto Error;
                }
                eStat = Pbl.PBL_BufferParameterSet(ahCaptureBuffers[i], Pbl.etPblParam.PBL_BUFF_STRIDE, ref dwBufferStride);
                if (Phx.etStat.PHX_OK != eStat)
                {
                    goto Error;
                }
                ePblCaptureFormat = (Pbl.etPblParamValue)eCaptureFormat;
                eStat             = Pbl.PBL_BufferParameterSet(ahCaptureBuffers[i], Pbl.etPblParam.PBL_DST_FORMAT, ref ePblCaptureFormat);
                if (Phx.etStat.PHX_OK != eStat)
                {
                    goto Error;
                }
                eStat = Pbl.PBL_BufferInit(ahCaptureBuffers[i]);
                if (Phx.etStat.PHX_OK != eStat)
                {
                    goto Error;
                }

                /* Set up the type of Bayer conversion required */
                if (fDebayer)
                {
                    Pbl.etPblParamValue ePblParamValue = Pbl.etPblParamValue.PBL_BAY_DEC_DUP;
                    eStat = Pbl.PBL_BufferParameterSet(ahCaptureBuffers[i], Pbl.etPblParam.PBL_BUFF_BAYDEC, ref ePblParamValue);
                    if (Phx.etStat.PHX_OK != eStat)
                    {
                        goto Error;
                    }
                    eStat = Pbl.PBL_BufferParameterSet(ahCaptureBuffers[i], Pbl.etPblParam.PBL_BUFF_BAYCOL, ref eBayCol);
                    if (Phx.etStat.PHX_OK != eStat)
                    {
                        goto Error;
                    }
                }

                /* Build up our array of capture buffers */
                Pbl.PBL_BufferParameterGet(ahCaptureBuffers[i], Pbl.etPblParam.PBL_BUFF_ADDRESS, ref asImageBuffers[i].pvAddress);
                asImageBuffers[i].pvContext = (IntPtr)ahCaptureBuffers[i];
            }
            /* Terminate the array */
            asImageBuffers[dwAcqNumBuffers].pvAddress = System.IntPtr.Zero;
            asImageBuffers[dwAcqNumBuffers].pvContext = System.IntPtr.Zero;

            /* The above code has created dwAcqNumBuffers acquisition buffers.
             * Therefore ensure that the Phoenix is configured to use this number, by overwriting
             * the value already loaded from the config file.
             */
            eStat = Phx.PHX_ParameterSet(hCamera, Phx.etParam.PHX_ACQ_NUM_BUFFERS, ref dwAcqNumBuffers);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }

            /* These are 'direct' buffers, so we must tell Phoenix about them
             * so that it can capture data directly into them.
             */
            eStat = Phx.PHX_ParameterSet(hCamera, Phx.etParam.PHX_BUF_DST_XLENGTH, ref dwBufferStride);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }
            eStat = Phx.PHX_ParameterSet(hCamera, Phx.etParam.PHX_BUF_DST_YLENGTH, ref dwBufferHeight);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }
            eStat = Phx.PHX_ParameterSet(hCamera, Phx.etParam.PHX_DST_PTRS_VIRT, asImageBuffers);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }
            eParamValue = Phx.etParamValue.PHX_DST_PTR_USER_VIRT;
            eStat       = Phx.PHX_ParameterSet(hCamera, (Phx.etParam.PHX_DST_PTR_TYPE | Phx.etParam.PHX_CACHE_FLUSH | Phx.etParam.PHX_FORCE_REWRITE), ref eParamValue);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }

            /* We create our display with a NULL hWnd, this will automatically create an image window. */
            eStat = Pdl.PDL_DisplayCreate(ref hDisplay, IntPtr.Zero, hCamera, myPhxCommon.PhxCommonDisplayErrorHandler);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }

            /* We create a display buffer (indirect) */
            eStat = Pdl.PDL_BufferCreate(ref hDisplayBuffer, hDisplay, Pdl.etPdlBufferMode.PDL_BUFF_SYSTEM_MEM_INDIRECT);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }

            /* Initialise the display, this associates the display buffer with the display */
            eStat = Pdl.PDL_DisplayInit(hDisplay);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }

            /* Enable FIFO Overflow events */
            eParamValue = Phx.etParamValue.PHX_INTRPT_FIFO_OVERFLOW;
            eStat       = Phx.PHX_ParameterSet(hCamera, Phx.etParam.PHX_INTRPT_SET, ref eParamValue);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }

            /* Setup our own event context */
            eStat = Phx.PHX_ParameterSet(hCamera, Phx.etParam.PHX_EVENT_CONTEXT, (void *)&sPhxLive);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }

            /* Check if camera is CXP */
            eStat = Phx.PHX_ParameterGet(hCamera, Phx.etParam.PHX_BOARD_VARIANT, ref eParamValue);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }
            if (Phx.etParamValue.PHX_BOARD_FBD_4XCXP6_2PE8 == eParamValue ||
                Phx.etParamValue.PHX_BOARD_FBD_2XCXP6_2PE8 == eParamValue ||
                Phx.etParamValue.PHX_BOARD_FBD_1XCXP6_2PE8 == eParamValue)
            {
                fCameraIsCxp = true;
            }

            /* Check that camera is discovered (only applies to CXP) */
            if (fCameraIsCxp)
            {
                myPhxCommon.PhxCommonGetCxpDiscoveryStatus(hCamera, 10, ref fIsCxpCameraDiscovered);
                if (!fIsCxpCameraDiscovered)
                {
                    goto Error;
                }
            }

            /* Now start our capture, using the callback method */
            eStat = Phx.PHX_StreamRead(hCamera, Phx.etAcq.PHX_START, PHX_Callback);
            if (Phx.etStat.PHX_OK != eStat)
            {
                goto Error;
            }

            /* Now start camera */
            if (fCameraIsCxp && 0 != sCameraRegs.dwAcqStartAddress)
            {
                eStat = myPhxCommon.PhxCommonWriteCxpReg(hCamera, sCameraRegs.dwAcqStartAddress, sCameraRegs.dwAcqStartValue, 800);
                if (Phx.etStat.PHX_OK != eStat)
                {
                    goto Error;
                }
            }

            /* Continue processing data until the user presses a key in the console window
             * or a FIFO overflow is detected.
             */
            Console.WriteLine("Press a key to exit");
            while (0 == myPhxCommon.PhxCommonKbHit())
            {
                /* Wait here until either:
                 * (a) The user aborts the wait by pressing a key in the console window
                 * (b) The BufferReady event occurs indicating that the image is complete
                 * (c) The FIFO overflow event occurs indicating that the image is corrupt
                 * Keep calling the sleep function to avoid burning CPU cycles
                 */
                while (0 == myPhxCommon.PhxCommonKbHit() && !sPhxLive.fBufferReady && !sPhxLive.fFifoOverflow)
                {
                    System.Threading.Thread.Sleep(10);
                }

                if (dwBufferReadyLast != sPhxLive.dwBufferReadyCount)
                {
                    uint dwStaleBufferCount;

                    /* If the processing is too slow to keep up with acquisition,
                     * then there may be more than 1 buffer ready to process.
                     * The application can either be designed to process all buffers
                     * knowing that it will catch up, or as here, throw away all but the
                     * latest
                     */
                    dwStaleBufferCount = sPhxLive.dwBufferReadyCount - dwBufferReadyLast;
                    dwBufferReadyLast += dwStaleBufferCount;

                    /* Throw away all but the last image */
                    if (1 < dwStaleBufferCount)
                    {
                        do
                        {
                            eStat = Phx.PHX_StreamRead(hCamera, Phx.etAcq.PHX_BUFFER_RELEASE, IntPtr.Zero);
                            if (Phx.etStat.PHX_OK != eStat)
                            {
                                goto Error;
                            }
                            dwStaleBufferCount--;
                        } while (dwStaleBufferCount > 1);
                    }
                }
                sPhxLive.fBufferReady = false;

                Phx.stImageBuff stBuffer;
                stBuffer.pvAddress = IntPtr.Zero;
                stBuffer.pvContext = IntPtr.Zero;

                /* Get the info for the last acquired buffer */
                eStat = Phx.PHX_StreamRead(hCamera, Phx.etAcq.PHX_BUFFER_GET, ref stBuffer);
                if (Phx.etStat.PHX_OK != eStat)
                {
                    eStat = Phx.PHX_StreamRead(hCamera, Phx.etAcq.PHX_BUFFER_RELEASE, IntPtr.Zero);
                    if (Phx.etStat.PHX_OK != eStat)
                    {
                        goto Error;
                    }
                    continue;
                }

                /* Process the newly acquired buffer,
                 * which in this simple example is a call to display the data.
                 * For our display function we use the pvContext member variable to
                 * pass a display buffer handle.
                 * Alternatively the actual video data can be accessed at stBuffer.pvAddress
                 */
                byte[] wtf = new byte[4036608];
                Marshal.Copy(stBuffer.pvAddress, wtf, 0, 4036608);
                // Console.WriteLine(wtf[0].ToString());
                for (int i = 50000; i < 500000; i++)
                {
                    wtf[i] = 0;
                }
                Marshal.Copy(wtf, 0, stBuffer.pvAddress, 4036608);

                uint hBufferHandle = (uint)stBuffer.pvContext;

                /* This copies/converts data from the direct capture buffer to the indirect display buffer */
                eStat = Pil.PIL_Convert(hBufferHandle, hDisplayBuffer);
                if (Phx.etStat.PHX_OK != eStat)
                {
                    eStat = Phx.PHX_StreamRead(hCamera, Phx.etAcq.PHX_BUFFER_RELEASE, IntPtr.Zero);
                    if (Phx.etStat.PHX_OK != eStat)
                    {
                        goto Error;
                    }
                    continue;
                }

                Pdl.PDL_BufferPaint(hDisplayBuffer);

                /* Having processed the data, release the buffer ready for further image data */
                eStat = Phx.PHX_StreamRead(hCamera, Phx.etAcq.PHX_BUFFER_RELEASE, IntPtr.Zero);
                if (Phx.etStat.PHX_OK != eStat)
                {
                    goto Error;
                }
            }

            /* In this simple example we abort the processing loop on an error condition (FIFO overflow).
             * However handling of this condition is application specific, and generally would involve
             * aborting the current acquisition, and then restarting.
             */
            if (sPhxLive.fFifoOverflow)
            {
                Console.WriteLine("FIFO Overflow detected. Aborting.");
            }

Error:
            /* Now cease all captures */
            if (0 != hCamera)
            {
                /* Stop camera */
                if (fIsCxpCameraDiscovered && 0 != sCameraRegs.dwAcqStopAddress)
                {
                    myPhxCommon.PhxCommonWriteCxpReg(hCamera, sCameraRegs.dwAcqStopAddress, sCameraRegs.dwAcqStopValue, 800);
                }
                /* Stop frame grabber */
                Phx.PHX_StreamRead(hCamera, Phx.etAcq.PHX_ABORT, IntPtr.Zero);
            }

            Console.WriteLine("Exiting");
            return(0);
        }
        /// <summary>
        /// Create a new InstrumentationPhase object.
        /// </summary>
        /// <param name="config">The phase list container.</param>
        /// <param name="logger">
        /// Logger to save information about the basic blocks in the assembly.
        /// </param>
        /// <returns>A new InstrumentationPhase object.</returns>
        public static InstrumentPhase New(Phx.Phases.PhaseConfiguration config, LogWriter logger)
        {
            InstrumentPhase instrumentPhase = new InstrumentPhase();
            instrumentPhase.Initialize(config, "CodeCoverage instrumentation phase");

#if PHX_DEBUG_SUPPORT
            instrumentPhase.PhaseControl = InstrumentPhase.InstrumentPhaseControl;
#endif

            instrumentPhase.Log = logger;
            return instrumentPhase;
        }
        /// <summary>
        /// Get a symbol representing a function that takes an unsigned integer
        /// parameter.
        /// </summary>
        /// <param name="unit">Module calling the function.</param>
        /// <param name="assembly">Name of the assembly.</param>
        /// <param name="type">Name of the class.</param>
        /// <param name="method">Name of the function.</param>
        /// <returns>FunctionSymbol representing the function.</returns>
        private static Phx.Symbols.FunctionSymbol GetFunctionSymbol(Phx.PEModuleUnit unit, string assembly, string type, string method)
        {
            // Look the function up in the cache
            Phx.Symbols.FunctionSymbol functionSymbol = null;
            if (FunctionSymbols.TryGetValue(unit, out functionSymbol) && functionSymbol != null)
            {
                return functionSymbol;
            }

            // Create symbols for the assemblies and types
            Phx.Symbols.AssemblySymbol assemblySymbol = GetAssemblySymbol(unit, assembly);
            Phx.Symbols.MsilTypeSymbol typeSymbol = GetTypeSymbol(unit, type, assemblySymbol);

            // Build a symbol reference
            Phx.Types.FunctionTypeBuilder builder = Phx.Types.FunctionTypeBuilder.New(unit.TypeTable);
            builder.Begin();
            builder.CallingConventionKind = Phx.Types.CallingConventionKind.ClrCall;
            builder.AppendReturnParameter(unit.TypeTable.VoidType);
            builder.AppendParameter(unit.TypeTable.UInt32Type);

            // Create the function symbol
            Phx.Name name = Phx.Name.New(unit.Lifetime, method);
            functionSymbol = Phx.Symbols.FunctionSymbol.New(unit.SymbolTable, 0, name, builder.GetFunctionType(), Phx.Symbols.Visibility.GlobalReference);
            typeSymbol.InsertInLexicalScope(functionSymbol, name);

            // Create a type 
            Phx.Types.AggregateType aggregate = Phx.Types.AggregateType.NewDynamicSize(unit.TypeTable, typeSymbol);
            aggregate.IsDefinition = false;
            aggregate.AppendMethodSymbol(functionSymbol);

            // Cache the function
            FunctionSymbols[unit] = functionSymbol;

            return functionSymbol;
        }
        /// <summary>
        /// Get a symbol representing a type in the assembly.
        /// </summary>
        /// <param name="unit">Module calling the type.</param>
        /// <param name="type">Name of the type.</param>
        /// <param name="assembly">Assembly containing the type.</param>
        /// <returns>Symbol representing the type.</returns>
        private static Phx.Symbols.MsilTypeSymbol GetTypeSymbol(Phx.ModuleUnit unit, string type, Phx.Symbols.AssemblySymbol assembly)
        {
            Phx.Symbols.MsilTypeSymbol typeSymbol = null;

            // Look for any existing symbol
            foreach (Phx.Symbols.Symbol symbol in unit.SymbolTable.AllSymbols)
            {
                Phx.Symbols.MsilTypeSymbol s = symbol as Phx.Symbols.MsilTypeSymbol;
                if (s != null && s.NameString.Equals(type))
                {
                    typeSymbol = s;
                    break;
                }
            }

            if (typeSymbol == null)
            {
                // Create the symbol if not found
                Phx.Name classTypeName = Phx.Name.New(unit.Lifetime, type);
                typeSymbol = Phx.Symbols.MsilTypeSymbol.New(unit.SymbolTable, classTypeName, 0);

                // Add the type to the assembly's scope
                assembly.InsertInLexicalScope(typeSymbol, classTypeName);
            }

            return typeSymbol;
        }
        /// <summary>
        /// Get a symbol representing the assembly.
        /// </summary>
        /// <param name="unit">Module calling the assembly.</param>
        /// <param name="assembly">Name of the assembly.</param>
        /// <returns>Symbol representing the assembly.</returns>
        private static Phx.Symbols.AssemblySymbol GetAssemblySymbol(Phx.ModuleUnit unit, string assembly)
        {
            Phx.Symbols.AssemblySymbol assemblySymbol = null;

            // Look for any existing symbol
            foreach (Phx.Symbols.Symbol symbol in unit.SymbolTable.AllSymbols)
            {
                Phx.Symbols.AssemblySymbol s = symbol as Phx.Symbols.AssemblySymbol;
                if (s != null && s.NameString.Equals(assembly))
                {
                    assemblySymbol = s;
                    break;
                }
            }

            if (assemblySymbol == null)
            {
                // Create the assembly manifest
                Phx.Name name = Phx.Name.New(unit.Lifetime, assembly);
                Phx.Version version = Phx.Version.New(unit.Lifetime);

                // A bug in Phx.Version ToString renders this field incorrect in
                // the debugger, FYI.
                version.MajorVersion = (ushort)CoverageVisitAssemblyVersion.Major;
                version.MinorVersion = (ushort)CoverageVisitAssemblyVersion.Minor;
                version.BuildNumber = (ushort)CoverageVisitAssemblyVersion.Build;
                version.RevisionNumber = (ushort)CoverageVisitAssemblyVersion.Revision;

                Phx.Manifest manifest = Phx.Manifest.New(unit.Lifetime);
                manifest.Name = name;
                manifest.HashAlgorithm = 0x00008004;
                manifest.Version = version;

                if (!string.IsNullOrEmpty(CoverageVisitAssemblyPublicKey))
                {
                    byte[] key = PublicKeyTokenToBytes(CoverageVisitAssemblyPublicKey);
                    if (key != null)
                    {
                        Phx.PublicKey pk = Phx.PublicKey.New(unit.Lifetime);
                        pk.IsPublicKeyToken = true;
                        pk.KeyLength = (uint)key.Length;
                        pk.Key = key;
                        manifest.PublicKey = pk;
                    }
                }

                // Create the assembly symbol if not found
                assemblySymbol = Phx.Symbols.AssemblySymbol.New(null, manifest, name, unit.SymbolTable);
            }

            return assemblySymbol;
        }
        /// <summary>
        /// Inject a call to the coverage function with the id of a basic block
        /// before its first instruction.
        /// </summary>
        /// <param name="function">Function being instrumented.</param>
        /// <param name="coverageVisit">
        /// Coverage function to call before each block.
        /// </param>
        /// <param name="block">
        /// The id of the block to pass to the coverage function.
        /// </param>
        /// <param name="blockStartInstruction">
        /// First instruction of the basic block.
        /// </param>
        private static void InjectCoverageCall(Phx.FunctionUnit function, Phx.Symbols.FunctionSymbol coverageVisit, uint block, Phx.IR.Instruction blockStartInstruction)
        {
            Phx.Types.Table typeTable = function.ParentUnit.TypeTable;
            if (function.FlowGraph == null)
            {
                function.BuildFlowGraph();
            }

            // Create the instructions
            Phx.IR.Operand blockOperand = Phx.IR.ImmediateOperand.New(function, typeTable.UInt32Type, (uint)block);
            Phx.IR.Instruction loadBlock = Phx.IR.ValueInstruction.NewUnaryExpression(function, Phx.Targets.Architectures.Msil.Opcode.ldc, typeTable.UInt32Type, blockOperand);
            loadBlock.DestinationOperand.Register = Phx.Targets.Architectures.Msil.Register.SR0;
            Phx.IR.Instruction callCoverage = Phx.IR.CallInstruction.New(function, Phx.Targets.Architectures.Msil.Opcode.call, coverageVisit);

            // Insert the instructions
            blockStartInstruction.InsertBefore(loadBlock);
            callCoverage.AppendSource(loadBlock.DestinationOperand);
            loadBlock.DestinationOperand.BreakExpressionTemporary();
            loadBlock.DebugTag = blockStartInstruction.DebugTag;
            blockStartInstruction.InsertBefore(callCoverage);
        }
        /// <summary>
        /// Inject code coverage information into a function.
        /// </summary>
        /// <param name="unit">The function to instrument.</param>
        protected override void Execute(Phx.Unit unit)
        {
            // Only instrument MSIL functions
            if (!unit.IsFunctionUnit)
            {
                return;
            }
            Phx.FunctionUnit function = unit.AsFunctionUnit;
            if (!function.Architecture.NameString.Equals("Msil"))
            {
                return;
            }

            Phx.PEModuleUnit module = function.ParentUnit.AsPEModuleUnit;
            Phx.Symbols.FunctionSymbol functionSymbol = function.FunctionSymbol;
            Phx.Types.FunctionType functionType = functionSymbol.FunctionType;

            // Create the method signature
            List<string> parameterTypes = new List<string>();
            foreach (Phx.Types.Parameter parameter in functionType.UserDefinedParameters)
            {
                parameterTypes.Add(parameter.Type.ToString());
            }
            string methodName = string.Format(
                CultureInfo.InvariantCulture,
                "{0}({1})",
                functionSymbol.NameString,
                string.Join(", ", parameterTypes.ToArray()));

            // Build the control flow graph for the current function
            function.BuildFlowGraph();
            Phx.Graphs.FlowGraph flow = function.FlowGraph;

            // Log method details
            string typeName = (functionSymbol.EnclosingAggregateType != null) ?
                functionSymbol.EnclosingAggregateType.TypeSymbol.NameString :
                "<Module>";
            Log.StartMethod(
                methodName,
                typeName,
                flow.StartBlock.FirstInstruction.GetFileName(),
                flow.StartBlock.FirstInstruction.GetLineNumber());

            // Create a mapping of the disassembled from instructions to the
            // basic block IDs so we can use them for coverage viewing.
            Dictionary<Phx.IR.Instruction, uint> dissassembly = new Dictionary<Phx.IR.Instruction, uint>();

            // Instrument and log the blocks for the current function.
            Log.StartBlocks();
            foreach (Phx.Graphs.BasicBlock block in flow.BasicBlocks)
            {
                // Find the first real instruction in the block
                Phx.IR.Instruction first = null;
                foreach (Phx.IR.Instruction instruction in block.Instructions)
                {
                    // Save the instructions to be dumped later
                    dissassembly.Add(instruction, BlockCounter);

                    // Ignore instructions that aren't actually "real"
                    if (first == null && instruction.IsReal)
                    {
                        Phx.Common.Opcode opcode = instruction.Opcode as Phx.Common.Opcode;
                        if (opcode == Phx.Common.Opcode.ReturnFinally ||
                            opcode == Phx.Common.Opcode.Leave ||
                            opcode == Phx.Common.Opcode.Unreached ||
                            opcode == Phx.Common.Opcode.ExitTypeFilter)
                        {
                            continue;
                        }

                        first = instruction;
                    }
                }

                // Inject a code coverage visitor call before the first
                // instruction of the basic block
                if (first != null)
                {
                    // Log the basic block
                    Phx.IR.Instruction last = block.LastInstruction;
                    bool skipBlock = first == last;
                    if (!skipBlock)
                    {
                        Log.StartBlock(
                            BlockCounter,
                            first.GetMsilOffset(),
                            first.GetFileName(),
                            first.GetLineNumber(),
                            first.GetColumnNumber(),
                            last.GetLineNumberEnd(),
                            last.GetColumnNumberEnd());
                    }

                    Phx.Symbols.FunctionSymbol coverageVisit = GetFunctionSymbol(module, CoverageVisitAssembly, CoverageVisitType, CoverageVisitMethod);
                    if (!skipBlock)
                    {
                        InjectCoverageCall(function, coverageVisit, BlockCounter, first);
                    }

#if LogBlockDissassembly
                    // Dump the disassembly for the current block
                    Log.StartBlockDisassembly();
                    foreach (Phx.IR.Instruction instruction in block.Instructions)
                    {
                        Log.WriteBlockDisassembly(
                            instruction.GetMsilOffset(),
                            instruction.ToString(),
                            BlockCounter);
                    }
                    Log.EndBlockDisassembly();
#endif
                    if (!skipBlock)
                    {
                        Log.EndBlock();
                    }
                }

                // Increment the number of basic blocks
                BlockCounter++;
            }

            function.DeleteFlowGraph();
            Log.EndBlocks();

            // Dump the disassembly for the current method
            Log.StartMethodDisassembly();
            foreach (KeyValuePair<Phx.IR.Instruction, uint> pair in dissassembly)
            {
                Log.WriteBlockDisassembly(
                    pair.Key.GetMsilOffset(),
                    pair.Key.ToString(),
                    pair.Value);
            }
            Log.EndMethodDisassembly();

            Log.EndMethod();
        }