From 8b56cc412b926a25f9b9abd07d052f295c2fc498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergi=20Hern=C3=A0ndez=20Juan?= <shernand@iri.upc.edu> Date: Thu, 5 Jul 2012 09:21:23 +0000 Subject: [PATCH] Solved a problem when multiple processes using the FTDIServer were executed concurrently. The information returnes by the FT_GetDeviceInfoList() function was incomplete and generated errors. Now the bus is rescaned at random intervals when there are such conditions to refresh the device list. Solved a problem when the FTDI device could not be properly opened. The device was not destroyed and therefore the internal resources were not freed, which make it impossible to create the device classes again (the events were not properly removed from the server). --- src/examples/test_ftdi.cpp | 27 +++++++++++++++++++++++---- src/usb_ftdi/ftdiserver.cpp | 32 ++++++++++++++++++++++++++------ 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/examples/test_ftdi.cpp b/src/examples/test_ftdi.cpp index ad031e3..c3e26de 100644 --- a/src/examples/test_ftdi.cpp +++ b/src/examples/test_ftdi.cpp @@ -2,6 +2,7 @@ #include "ftdiserver.h" #include "ftdiexceptions.h" #include <stdio.h> +#include <stdlib.h> /** \example test_ftdi.cpp * @@ -49,6 +50,7 @@ int main(int argc, char *argv[]) CFTDIServer *ftdi_server=CFTDIServer::instance(); CFTDI *ftdi_device=NULL; TFTDIconfig ftdi_config; + int count=15; ftdi_config.baud_rate = 115200; ftdi_config.word_length = 8; @@ -58,16 +60,33 @@ int main(int argc, char *argv[]) ftdi_config.write_timeout = 1000; ftdi_config.latency_timer = 16; + try{ std::cout << (*ftdi_server) << std::endl; if(ftdi_server->get_num_devices()>0) { - ftdi_device=ftdi_server->get_device(ftdi_server->get_serial_number(0)); - ftdi_device->config(&ftdi_config); - std::cout << (*ftdi_device) << std::endl; - ftdi_device->close(); + while(ftdi_device==NULL && count>0) + { + try{ + ftdi_device=ftdi_server->get_device(ftdi_server->get_serial_number(atoi(argv[1]))); + }catch(CException &e){ + std::cout << e.what() << std::endl; + count--; + } + } + if(count==0) + std::cout << "Device not available" << std::endl; + else + { + ftdi_device->config(&ftdi_config); + std::cout << (*ftdi_device) << std::endl; + ftdi_device->close(); + } } if(ftdi_device!=NULL) delete ftdi_device; + }catch(CException &e){ + std::cout << e.what() << std::endl; + } } diff --git a/src/usb_ftdi/ftdiserver.cpp b/src/usb_ftdi/ftdiserver.cpp index bb1e65d..c3b54a4 100644 --- a/src/usb_ftdi/ftdiserver.cpp +++ b/src/usb_ftdi/ftdiserver.cpp @@ -1,12 +1,18 @@ #include "ftdiexceptions.h" #include "ftdiserver.h" #include "ftd2xx.h" +#include <stdlib.h> CFTDIServer *CFTDIServer::pinstance=NULL; CFTDIServer::CFTDIServer() { + struct timeval time; + this->scan_bus(); + // initialize the random number generator + gettimeofday(&time,NULL); + srand(time.tv_usec); } CFTDIServer::CFTDIServer(const CFTDIServer& object) @@ -196,11 +202,13 @@ std::string& CFTDIServer::get_description(unsigned int index) CFTDI *CFTDIServer::get_device(std::string& serial_desc) { std::string dev_name; - CFTDI *ftdi_device; + CFTDI *ftdi_device=NULL; unsigned int i=0; if(serial_desc.size()==0) { + usleep(((double)rand()/RAND_MAX)*100000); + this->scan_bus(); /* handle exceptions */ throw CFTDIServerException(_HERE_,"Invalid serial number or description - empty string.\n"); } @@ -210,15 +218,27 @@ CFTDI *CFTDIServer::get_device(std::string& serial_desc) { if(this->devices[i].serial_number==serial_desc || this->devices[i].description==serial_desc) { - dev_name="FTDI_"; - dev_name+=serial_desc; - ftdi_device=new CFTDI(dev_name); - ftdi_device->open((void *)&serial_desc); + try{ + dev_name="FTDI_"; + dev_name+=serial_desc; + ftdi_device=new CFTDI(dev_name); + ftdi_device->open((void *)&serial_desc); + }catch(CException &e){ + if(ftdi_device!=NULL) + { + delete ftdi_device; + ftdi_device=NULL; + } + usleep(((double)rand()/RAND_MAX)*100000); + this->scan_bus(); + throw; + } return ftdi_device; } } } - + usleep(((double)rand()/RAND_MAX)*100000); + this->scan_bus(); return NULL; } -- GitLab