libftdi Archives

Subject: Segmentation fault

From: Lars Lockenvitz <l.lockenvitz@xxxxxxxxxxx>
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Date: Wed, 16 Sep 2009 08:30:57 +0200
Hello,

I try to scan every 5 seconds the usb bus for ftdi 2232 devices, to add or remove them from my list. And It works, but when I connect to devices I found and try again to look for 2232 devices
I get an "segmentation fault" at ftdi_init.

This is the code for that. At the first time this works, but If i have a connection to ftdi devices on bus it doesn't.
And I don't know why? Does someone else know why?

int scan_usb_heliosens()
{
  int num_devices = 0;
  struct ftdi_context ftdic;
  struct ftdi_device_list *devlist, *curdev;
  struct heliosens_usb *temp, *temp2;
  char tempmanu[128], tempdesc[128], tempserial[50];

  if(ftdi_init(&ftdic) < 0) {
    fprintf(stderr, "ftdi_init failed\n");
    return -1;
  }

  //USB Heliosens devices use all a FT2232 (VID=0x0403, PID=0x6010)
  if((num_devices = ftdi_usb_find_all(&ftdic, &devlist, 0x0403, 0x6010)) < 0) {
    fprintf(stderr, "ftdi_usb_find_all failed: %d (%s)\n", num_devices, ftdi_get_error_string(&ftdic));
    goto return_error;
  }

  if(num_devices > 0) {
    for (curdev = devlist; curdev != NULL; curdev = curdev->next) {
        if (ftdi_usb_get_strings(&ftdic, curdev->dev, tempmanu, sizeof(tempmanu)-1, tempdesc, sizeof(tempdesc)-1, tempserial, sizeof(tempserial)-1) < 0) {
            fprintf(stderr, "ftdi_usb_get_strings failed: (%s)\n", ftdi_get_error_string(&ftdic));
            goto return_error;
        }

        if(verbose) {
          fprintf(stdout, "Found Device Manufacturer: %s\tDescription: %s\n", tempmanu, tempdesc);
        }
 
        // Check if ftdi devices is a usb heliosens
        if(strncmp(MANUFACTURER,tempmanu, sizeof(tempmanu)-1)==0 && strncmp(DESCRIPTION,tempdesc, sizeof(tempdesc)-1)==0) {

          // Check if device is always known
          int device_known = FALSE;
          temp = devices;

          while(temp != NULL) {
            if( strncmp(temp->ident, tempserial, sizeof(tempserial)-1) == 0)
              device_known = TRUE;
            temp = temp->next;
          }

          if(device_known)
            continue;

          //Try to allocate ftdi_context's for found heliosens
          struct heliosens_usb *newdev;
          if((newdev = (struct heliosens_usb *)malloc(sizeof(struct ftdi_context))) == NULL) {
            fprintf(stderr, "Can not allocate memory for ftdi device\n");
            goto return_error;
          }

          // init the ftdi_context structure
          if(ftdi_init(&newdev->ftdic) < 0) {
            fprintf(stderr, "Can not init ftid_context\n");
            free(newdev);
            continue;
          }

          // Now let open and initialise this devices
          if(open_and_initialise_mpsse(&newdev->ftdic, curdev) < 0) {
            fprintf(stderr, "Can not open and initialise device\n" );
            close_and_free(newdev);
            continue;
          }
       
          // Calibrate and configure device if needed
          if(calibrate)
            run_calibrate(&newdev->ftdic);
          else if(conversion_mode != CONVERSION_MODE_4) //Mode 4 is reset value of the HCPL-0872
            set_config(&newdev->ftdic);
         
          // Add struct heliosens_usb (newdev) to list
          temp = devices;
          fprintf(stderr, "ident: %s | tempserial: %s\n", newdev->ident, tempserial);
          strncpy(newdev->ident, tempserial, sizeof(newdev->ident)-1);

          if(temp ==  NULL) { // add as first entry
            newdev->prev = NULL;
            newdev->next = NULL;
            temp = newdev;
            devices = temp;
          }
          else {  // add entry to end
            for(; temp->next != NULL; temp = temp->next);
            temp->next = newdev;
            newdev->prev = temp;
            newdev->next = NULL;
          }

          if(verbose)
            fprintf(stdout, "Device %s added\n", newdev->ident);
      }
    }
  }


  // Check if all devices in list are really available
  unsigned short status;
  temp = devices;

  while(temp != NULL) {
    temp2 = temp;
    temp = temp->next;
    if(ftdi_poll_modem_status(&temp2->ftdic, &status) < 0 ) {
      if(verbose)
        fprintf(stderr, "Removing device %s\n", temp2->ident);

      // Let's remove device from list
      if(temp2->prev == NULL && temp2->next == NULL) {  //only one entry
        devices = NULL;
      }
      if(temp2->prev == NULL) { //first entry
        temp2->next->prev = NULL;
      }
      else if(temp2->next == NULL) { //last entry
        temp2->prev->next = NULL;
      }
      else {
        temp2->prev->next = temp2->next;
        temp2->next->prev = temp2->prev;
      }

      close_and_free(temp2);
    }
  }   

  if(num_devices > 0)
    ftdi_list_free(&devlist);

  ftdi_deinit(&ftdic);
  return 1;

return_error:
  ftdi_deinit(&ftdic);
  return -1;
}


Regards
Lars


libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx


Current Thread