FTDI Multithreaded Read

Viewed 98

I have the following problem and hope someone can help me.

My basic flow: I want to program any number of devices in parallel using the FTDI D2XX driver and then communicate with them for testing purposes. For this I use two arrays from BackgroundWorker - the first array for programming and the second for testing.

Programming works without any problems. But if I start the BackgroundWorker from the second array to start the test, the connection fails. If I run the complete sequence with only one BackgroundWorker for programming and one BackgroundWorker for testing, the sequence works without problems.

Initialization of BackgroundWorker

 private void InitializeBackgoundWorkers()
    {
        for (var f = 0; f < ftdiDeviceCount; f++)
        {
            threadArrayProgram[f] = new BackgroundWorker();
            threadArrayProgram[f].DoWork += new DoWorkEventHandler(bgr_WorkerStirrerProg_DoWork);
            threadArrayProgram[f].RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundWorkerProgRunWorkerCompleted);
            threadArrayProgram[f].WorkerReportsProgress = true;
            threadArrayProgram[f].WorkerSupportsCancellation = true;
        }

        for (var f = 0; f < ftdiDeviceCount; f++)
        {
            threadArrayTest[f] = new BackgroundWorker();
            threadArrayTest[f].DoWork += new DoWorkEventHandler(bgr_WorkerStirrerTest_DoWork);
            threadArrayTest[f].RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundWorkerTestRunWorkerCompleted);
            threadArrayTest[f].WorkerReportsProgress = true;
            threadArrayTest[f].WorkerSupportsCancellation = true;
        }
    }

Aufruf der BackgroundWorker

 private void button2_Click_1(object sender, EventArgs e)
    {

       

        if (!bStirrerSerached)
        {
            vSetProgressBarValueRuehrer(1, imaxprogressbar);
            vSearchStirrer();
        }

        if (FtStatus == FTDI.FT_STATUS.FT_OK)
        {
            //bgr_Worker_Stirrer.RunWorkerAsync();

            InitializeBackgoundWorkers();

            //---programmieren---//
            for (var f = 0; f < /*FilesToProcess*/ftdiDeviceCount; f++)
            {
                var fileProcessed = false;
                while (!fileProcessed)
                {
                    for (var threadNum = 0; threadNum < MaxThreads; threadNum++)
                    {
                        if (!threadArrayProgram[threadNum].IsBusy)
                        {
                            Console.WriteLine("Starting Thread: {0}", threadNum);
                            stemp = "Starting Thread: " + threadNum;
                            File.AppendAllText(slogfile, stemp);

                            threadArrayProgram[threadNum].RunWorkerAsync(f);
                            fileProcessed = true;
                            Thread.Sleep(1000);
                            break;
                        }
                    }
                    if (!fileProcessed)
                    {
                        Thread.Sleep(50);
                    }
                }
            }


            //---testen---//
            for (var f = 0; f < /*FilesToProcess*/ftdiDeviceCount; f++)
            {
                var fileProcessed = false;
                while (!fileProcessed)
                {
                    for (var threadNum = 0; threadNum < MaxThreads; threadNum++)
                    {
                        if (!threadArrayTest[threadNum].IsBusy)
                        {
                            Console.WriteLine("Starting Thread: {0}", threadNum);
                            stemp = "Starting Thread: " + threadNum;
                            File.AppendAllText(slogfile, stemp);

                            threadArrayTest[threadNum].RunWorkerAsync(f);
                            fileProcessed = true;
                            Thread.Sleep(1000);
                            break;
                        }
                    }
                    if (!fileProcessed)
                    {
                        Thread.Sleep(50);
                    }
                }
            }
        }


        button2.Enabled = false;
    }

BackgroundWorker

private void bgr_WorkerStirrerProg_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {
            if (FtStatus == FTDI.FT_STATUS.FT_OK)
            {
                if (ftdiDeviceList != null)
                {
                    //---db werte sammeln---//
                    cRuehrerProp = new CRuehrerProperties();
                    cRuehrerProp.SBenutzer = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
                    cRuehrerProp.SComputername = System.Windows.Forms.SystemInformation.ComputerName.ToString();


                    //---Rührer programmieren---//
                    vStirrerProgram((int)e.Argument);
                }
            }
        }
        catch (NotSupportedException /*exc*/)
        {

        }
        finally
        {
            this.Invoke((MethodInvoker)delegate
            {

            });
        }
    }

 private void bgr_WorkerStirrerTest_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {
            if (!bfinish)
            {
                while (!bfinish)
                {
                    if (bfinish)
                        break;
                }
            }
            //---Test starten---//
            vStirrerTest((int)e.Argument);
        }
        catch (NotSupportedException /*exc*/)
        {

        }
        finally
        {
            this.Invoke((MethodInvoker)delegate
            {
                button2.Enabled = true;

                myFtdiDevice.Close();
            });
        }
    }

Testing method

 private void vStirrerTest(int pos)
    {
        //threadnr
        iPosRuehrerGrid = pos;
        Console.WriteLine("Thread {0} StirrerTest", pos);

        ftStatus = myFtdiDevice.CyclePort();

        UInt32 newFtdiDeviceCount = 0;
        do
        {
            // Wait for device to be re-enumerated
            // The device will have the same location since it has not been 
            // physically unplugged, so we will keep trying to open it until it succeeds
            ftStatus = myFtdiDevice.OpenByLocation(ftdiDeviceList[iPosRuehrerGrid].LocId);
            Console.WriteLine("try to open locid" + ftdiDeviceList[iPosRuehrerGrid].LocId  + " on device " + iPosRuehrerGrid);
            //ftStatus = myFtdiDevice.OpenByLocation(ftdiDeviceListOrig[iStirrerPosold[iPosRuehrerGrid]].LocId);
            Thread.Sleep(1000);
        } while (ftStatus != FTDI.FT_STATUS.FT_OK);

        // Close the device
        myFtdiDevice.Close();

        // Re-create our device list
        ftStatus = myFtdiDevice.GetNumberOfDevices(ref newFtdiDeviceCount);
        if (ftStatus != FTDI.FT_STATUS.FT_OK)
        {
            // Wait for a key press
            Console.WriteLine("Failed to get number of devices (error " + ftStatus.ToString() + ")");
            stemp = "Failed to get number of devices (error " + ftStatus.ToString() + ")";
            File.AppendAllText(slogfile, stemp);
            return;
        }

        // Re-populate our device list
        ftStatus = myFtdiDevice.GetDeviceList(ftdiDeviceList);
        bRepopulateList = true;
        vSearchStirrer();

The error occurs in the do loop. If I use only one device - and thus only one thread at a time, it takes an average of 5 runs until the device is opened again. However, if I attach another device and thus have 2 programming and 2 test threads, it does not manage to open the desired device.

I have looked at the DeviceList to make sure it is looking for the right device with the right ID - which it is.

Since I don't have any experience with the Backgrounworker yet, I'm not sure if I haven't forgotten something, which is why this error occurs.

0 Answers
Related