problem in copying bin file into buffer in my firmware download code
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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
Last edited by rohaanembedded; 07-10-2013 at 01:48 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);
}
}
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.
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
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.
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.
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.
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);
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.