LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   problem in copying bin file into buffer in my firmware download code (https://www.linuxquestions.org/questions/programming-9/problem-in-copying-bin-file-into-buffer-in-my-firmware-download-code-4175469103/)

rohaanembedded 07-10-2013 01:46 AM

problem in copying bin file into buffer in my firmware download code
 
dear sir i am trying to download the firmware file in to my cypress USBcontroller FX2LP.but i think i am facing problem in copying that bin file in buf and dowloading it to the FX2LP
please help me i am pasting my whole code i have tried to print the buf len aslo but it doesnt match with the size of file
please help me
firmware doest get dowloaded in IC i am using some cyusb and its API of control transfer for doing this any more information needed please let me know

Code:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "../../include/cyusb.h"



unsigned int DownloadFirmware();


int main (void)
{

unsigned int a = 0;

a = DownloadFirmware();

if(a == 1)
{
printf("\nsuccessful fd\n");
}

}


unsigned int DownloadFirmware()
{

        cyusb_handle *h;
        int size, r;
        int a, b, c, flag;
        int Sum = 0, Done = 0;
        const char *cbuf;
        const char *filename = "/home/usb/FPR/firmware/fw.bix";
        unsigned char *buf = NULL;
        const char *cBuf;
        unsigned char *ptr;
        unsigned char num_bytes = 0;
        unsigned short address = 0;
        unsigned char reset = 0;
        FILE *fp;  /* file pointer */
       



        struct libusb_device_descriptor desc;


        a = cyusb_open();

        if ( a < 0 ) {
              printf("Error opening library\n");
              return -1;
          }
        else if ( a == 0 ) {
                  printf("No device foundd\n");
          }

        h = cyusb_gethandle(0);
        b = cyusb_get_device_descriptor(h, &desc);

        if(b){
          printf("error getting device descriptor\n");
          return -2;
        }



                struct stat st;
                stat(filename, &st);
                size = st.st_size;
               
                printf("size of file = %d\n", size);       
       
                buf = (unsigned char*)malloc(size+1);               



//L                printf("\n%d", sizeof(buf));

        /* open file for read */
              if ((fp = fopen("/home/usb/FPR/firmware/fw.bix", "rb"))==NULL){
                      printf("Cannot open file \n");
                }     

                fread(buf, size, 1 ,fp);

                cBuf = (const char*) buf;

                int len = strlen(cBuf);

                printf("\nBuf_len_aftr_Write = %d\n",len);       
               
               
                while(len!=0)
                {               
                printf("%c", *cBuf);
                len--;
                }

                int orglen = size;

                while(orglen!=0)
                {
                printf("%c", *buf);
                orglen--;
                }

       
                fclose(fp);

        if(buf)
        printf("file copied");       


        int ChunkSize = 4000; // seem to sending 4000 but not 5000 at one time
        int BlockSize = size;
        int entry = 0;
        reset = 1;
        sleep(1);


        reset = 0;

        r = cyusb_control_transfer(h, 0x40, 0xA0, 0xE600, 0x00, &reset, 0x01, 1000);
        if (!r) {
          printf("Error in control_transfer\n");
          return r;
        }

        sleep(1);
        sleep(1);
       
        ptr = buf;
       
        while(!Done)
        {


                        if(BlockSize < ChunkSize){
                                address += ChunkSize;
                  //            buf = buf+ChunkSize;
                                ptr = ptr + ChunkSize;
                                ChunkSize = BlockSize;
                                flag = 1;
                                }


        r = cyusb_control_transfer(h, 0x40, 0xA0, address, 0x00, ptr, ChunkSize, 0);

                printf("\nturn no. %d\n", r);
                if (!r) {
                  printf("Error in control_transfer. . .\n");
                  return r;
                }


                              //  buf = buf+ChunkSize;
                                ptr = ptr + ChunkSize;
                                BlockSize -= r;
                                Sum += r;
                                if(Sum == size)
                                Done = 1;
        printf("\nsum =  %d\n", Sum);

        }


        sleep(1);


                reset = 1;
                        r = cyusb_control_transfer(h, 0x40, 0xA0, 0xE600, 0x00, &reset, 0x01, 1000);

                reset = 0;
                        r = cyusb_control_transfer(h, 0x40, 0xA0, 0xE600, 0x00, &reset, 0x01, 1000);
       
        sleep(2);



        if(Done == 1){
        return 1;
        free(buf);
        }
}

how can i copy perfectly in buf and dowload this firmware

Thanks & regards
rohan

adelabarra 07-11-2013 06:06 AM

Dear rohaanembedded:
Do you have any error messages?

Alejandro

rohaanembedded 07-11-2013 07:05 AM

Dear sir,
Thanks for rply I get no error sir but by tried some things and right know i am getting right buffer filling but every time my control transfer is also returning the right no. of bytes sennt but after complition no effect on the device.
the firmware i have chnages the VendorID and ProductID After firmware download

any specific information needed plz let me know.

do you know about cyusb wrapper its usb wrapper just like libusb actuallya developed on the same for cypress USBcontroller IC's

pasting my edited code:

Code:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "../../include/cyusb.h"



unsigned int DownloadFirmware();


int main (void)
{

unsigned int a = 0;

a = DownloadFirmware();

if(a == 1)
{
printf("\nsuccessful fd\n");
}

}


unsigned int DownloadFirmware()
{

        cyusb_handle *h;
        int size, r;
        int a, b, c, flag;
        int Sum = 0, Done = 0;
        const char *cbuf;
        const char *filename = "/home/usb/FPR/firmware/fw.bix";
        unsigned char *buf = NULL;
        const char *cBuf;
        unsigned char *ptr;
        unsigned short address = 0;
        unsigned char reset;
        FILE *fp;  /* file pointer */
       



        struct libusb_device_descriptor desc;


        a = cyusb_open();

        if ( a < 0 ) {
              printf("Error opening library\n");
              return -1;
          }
        else if ( a == 0 ) {
                  printf("No device foundd\n");
          }

        h = cyusb_gethandle(0);
        b = cyusb_get_device_descriptor(h, &desc);

        if(b){
          printf("error getting device descriptor\n");
          return -2;
        }


/*
//to get length of the file

                struct stat st;
                stat(filename, &st);
                size = st.st_size;
               
                printf("size of file = %d\n", size);       
       
                buf = (unsigned char*)malloc(size+1);               

*/


        /* open file for read */
              if ((fp = fopen("/home/usb/FPR/firmware/fw.bix", "rb"))==NULL){
                      printf("Cannot open file \n");
                }     

                int fileLen;

                //Get file length
                fseek(fp, 0, SEEK_END);
                fileLen=ftell(fp);
                fseek(fp, 0, SEEK_SET);


                printf("\nfileLen = %d\n", fileLen);

                buf = (unsigned char*)malloc(fileLen);


                fread(buf, fileLen, 1 ,fp);

                cBuf = (const char*) buf;
               
                int len = strlen(cBuf);

                printf("\nBuf_len_aftr_Write = %d\n",len);       
               
               
                int orglen = fileLen;
/*
                printf("\n\n");

                while(orglen!=0)
                {
                printf("%0x", *buf);
                orglen--;
                buf++;
                }
*/

        printf("\n\n");
       
                fclose(fp);

        if(buf)
        printf("\nfile copied to buf\n");       


        int ChunkSize = 4000; // seem to sending 4000 but not 5000 at one time
        int BlockSize = fileLen;
        int entry = 1;
        reset = 1;
        sleep(1);


        reset = 0;

        r = cyusb_control_transfer(h, 0x40, 0xA0, 0xE600, 0x00, &reset, 0x01, 1000);
        if (!r) {
          printf("Error in control_transfer\n");
          return r;
        }

        sleep(2);
       
        ptr = buf;
       
        while(!Done)
        {


                                if(BlockSize < ChunkSize){
                                        ChunkSize = BlockSize;
                                //        ptr += ChunkSize;
                                //        address += ChunkSize;
                                }
                               


        r = cyusb_control_transfer(h, 0x40, 0xA0, address, 0x00, ptr, ChunkSize, 1000);

                printf("\nbytes written in %d transfer = %d\n", entry, r);
                if (!r) {
                  printf("Error in control_transfer. . .\n");
                  return r;
                }

                       

                                address += ChunkSize;
                                ptr += ChunkSize;
                                BlockSize = BlockSize - r;
                       
                       
                        Sum = Sum + r;
                       
                        entry++;
                       
                        if(Sum == fileLen){
                                Done = 1;
                                }


                        printf("\n sum = %d\n", Sum);                       
                        usleep(5000);
               

        }


                reset = 1;
                        r = cyusb_control_transfer(h, 0x40, 0xA0, 0xE600, 0x00, &reset, 0x01, 1000);

                reset = 0;
                        r = cyusb_control_transfer(h, 0x40, 0xA0, 0xE600, 0x00, &reset, 0x01, 1000);
       
//        sleep(2);



        if(Done == 1){
        return 1;
        free(buf);
        }
}

THanks & Regards
rohaan

ta0kira 07-11-2013 07:10 AM

There have been several threads related to similar problems lately. Don't use buffered input if you're just reading binary data, and don't use string functions because binary data contains null characters. Use open, read, and write, and use the return value of read as the size of the buffered data. fopen, etc. is only necessary if you want libc to handle text parsing.

Kevin Barry

rohaanembedded 07-11-2013 07:41 AM

Quote:

Originally Posted by ta0kira (Post 4988362)
There have been several threads related to similar problems lately. Don't use buffered input if you're just reading binary data, and don't use string functions because binary data contains null characters. Use open, read, and write, and use the return value of read as the size of the buffered data. fopen, etc. is only necessary if you want libc to handle text parsing.

Kevin Barry

Dear Kevin sir,
thanks for ur tome sir,

Code:

ssize_t read(int fd, void *buf, size_t count);
the read fuctn you have suggsted takes the arguement of fd as int but what i am getting is FILE * (file pointer) from the fuction
Code:

fp = fopen(const char *path, const char *mode);
how to implement your suggstion can i have more detail information please

Regards,
rohan

rohaanembedded 07-11-2013 08:33 AM

Dear sir i have tried this with open() and read() but its not making any chnage plz give suggstions

Code:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "../../include/cyusb.h"



unsigned int DownloadFirmware();


int main (void)
{

unsigned int a = 0;

a = DownloadFirmware();

if(a == 1)
{
printf("\nsuccessful fd\n");
}

}


unsigned int DownloadFirmware()
{

        cyusb_handle *h;
        int size, r;
        int a, b, c, flag;
        int Sum = 0, Done = 0;
        const char *cbuf;
        unsigned char *buf = NULL;
        const char *cBuf;
        unsigned char *ptr;
        unsigned short address = 0;
        unsigned char reset;
        FILE *fp;  /* file pointer */
        int fp_int;


        struct libusb_device_descriptor desc;


        a = cyusb_open();

        if ( a < 0 ) {
              printf("Error opening library\n");
              return -1;
          }
        else if ( a == 0 ) {
                  printf("No device foundd\n");
          }

        h = cyusb_gethandle(0);
        b = cyusb_get_device_descriptor(h, &desc);

        if(b){
          printf("error getting device descriptor\n");
          return -2;
        }



//to get length of the file

                struct stat st;
                stat(filename, &st);
                size = st.st_size;
               
                printf("size of file = %d\n", size);       
       
                buf = (unsigned char*)malloc(size+1);               




        /* open file for read */
//              if ((fp_int = open("/home/syntec_usb/syntec_FPR/syntec_firmware/fw.bix", "rb"))==NULL){
//                      printf("Cannot open file \n");
//                }     


                fp_int = open("/home/usb/FPR/firmware/fw.bix", O_RDONLY);

                if(fp_int==NULL){
                printf("error in the opening file");
                }


                int fileLen;

                fileLen = size;


               
//                fp_int =(int) fp;
               

                read(fp_int, buf, fileLen);

                cBuf = (const char*) buf;
               
                int len = strlen(cBuf);

                printf("\nBuf_len_aftr_Write = %d\n",len);       
               
               
                int orglen = fileLen;

        printf("\n\n");
       


        if(buf)
        printf("\nfile copied to buf\n");       


        int ChunkSize = 4000; // seem to sending 4000 but not 5000 at one time
        int BlockSize = fileLen;
        int entry = 1;
        reset = 1;
        sleep(1);


        reset = 0;

        r = cyusb_control_transfer(h, 0x40, 0xA0, 0xE600, 0x00, &reset, 0x01, 1000);
        if (!r) {
          printf("Error in control_transfer\n");
          return r;
        }

        sleep(2);
       
        ptr = buf;
       
        while(!Done)
        {


                                if(BlockSize < ChunkSize){
                                        ChunkSize = BlockSize;
                                //        ptr += ChunkSize;
                                //        address += ChunkSize;
                                }
                               


        r = cyusb_control_transfer(h, 0x40, 0xA0, address, 0x00, ptr, ChunkSize, 1000);

                printf("\nbytes written in %d transfer = %d\n", entry, r);
                if (!r) {
                  printf("Error in control_transfer. . .\n");
                  return r;
                }

                       

                                address += ChunkSize;
                                ptr += ChunkSize;
                                BlockSize = BlockSize - r;
                       
                       
                        Sum = Sum + r;
                       
                        entry++;
                       
                        if(Sum == fileLen){
                                Done = 1;
                                }


                        printf("\n sum = %d\n", Sum);                       
                        usleep(5000);
               

        }


                reset = 1;
                        r = cyusb_control_transfer(h, 0x40, 0xA0, 0xE600, 0x00, &reset, 0x01, 1000);

                reset = 0;
                        r = cyusb_control_transfer(h, 0x40, 0xA0, 0xE600, 0x00, &reset, 0x01, 1000);
       
//        sleep(2);



        if(Done == 1){
        return 1;
        free(buf);
        }
}

Regards
rohaan

ta0kira 07-11-2013 07:35 PM

  1. -1 is the error return for open, not NULL.
  2. You're still using strlen; get rid of that and replace it with the return value of read. Additionally, that value indicates the number of valid bytes. If you just assume that read completely filled the buffer, you could be using invalid data.
  3. You need a loop that keeps reading until: read returns 0, or -1 with errno set to something other than EAGAIN or EINTR; or, the sum of all read returns is equal to the file size. This is because you don't always get everything at once when reading.
Kevin Barry

rohaanembedded 07-12-2013 12:51 AM

Quote:

Originally Posted by ta0kira (Post 4988742)
  1. -1 is the error return for open, not NULL.
  2. You're still using strlen; get rid of that and replace it with the return value of read. Additionally, that value indicates the number of valid bytes. If you just assume that read completely filled the buffer, you could be using invalid data.
  3. You need a loop that keeps reading until: read returns 0, or -1 with errno set to something other than EAGAIN or EINTR; or, the sum of all read returns is equal to the file size. This is because you don't always get everything at once when reading.
Kevin Barry

Dear sir i tried as u suggsted but my read call is giving me -1 return. and stops the reading.

i have done somthing like this, please do let me know where i am makin mistake. THe file size i know its 8192bytes so i have taken it hard coded in read call. like, size = read(fp_int, buf, 8192);

Code:

 
              fp_int = open("/home/usb/FPR/firmware/fw.bix", O_RDONLY);

                if(fp_int == -1){
                printf("error in the opening file");
                }


/*
                //Get file length
                fseek(fp, 0, SEEK_END);
                fileLen=ftell(fp_int);
                fseek(fp, 0, SEEK_SET);
*/


                while(size!=0)
                {
                        size = read(fp_int, buf, 8192);
                        fileLen = fileLen + size;
                        printf("\nfileLen = %d", fileLen);
                        printf("\nReading turns. . .\n");
                        if(size < 0){
                        break;
                        }
                }


        printf("\nfileLen = %d\n", fileLen);


                close(fp_int);

Regards
rohan

ta0kira 07-12-2013 02:25 PM

read shouldn't return -1 unless there's an error. Are you reading from a regular file? Also, the return value of read doesn't correspond to a size when that value is -1, so you shouldn't add it to the total in that case. In addition to breaking out of the loop, print strerror(errno) to see what the error is. As I implied before, certain errors merely mean that you need to try the call again (e.g. EINTR and EAGAIN.) The hard-coding doesn't help anything, and in fact you might as well just skip retrieving the file size, since it's redundant.

Kevin Barry


All times are GMT -5. The time now is 12:16 PM.