LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 09-24-2009, 11:29 AM   #1
intermilan
LQ Newbie
 
Registered: Sep 2009
Posts: 4

Rep: Reputation: 0
fread can not pass the exact "count" ...


I'm trying to read from a device from a user application using:

int* frame = (int*) malloc( 83 * sizeof(int));
FILE *ICAP;
ICAP = fopen("/dev/icap0", "w+b"); // The deivce is opened OK. "w+b" should mean "read and write, binary".
fread(frame, sizeof(int), 83, ICAP);


The device read operation is defined as:
static ssize_t hwicap_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)

However, inside the hwicap_read function, the value of count is 0x400, not 0x53 as I passed to fread.

Why "count" in the hwicap_read function can not get the value as fread is called?
 
Old 09-24-2009, 12:18 PM   #2
AngTheo789
Member
 
Registered: Sep 2009
Posts: 110

Rep: Reputation: 24
You should post the code fragment - maybe that reveals something. By the way, fread should return the actual value it did read, unregarded what you passed in count.
 
Old 09-24-2009, 12:53 PM   #3
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Slackware 10.1/10.2/12, Ubuntu 12.04, Crunchbang Statler
Posts: 3,786

Rep: Reputation: 282Reputation: 282Reputation: 282
There is a dedicated programming section here at LQ. Future programming related questions fit better in there.

The count in hwicap_read probably defines the max size of the buffer __user *buf and not the number of chars to read.
 
Old 09-25-2009, 10:28 AM   #4
intermilan
LQ Newbie
 
Registered: Sep 2009
Posts: 4

Original Poster
Rep: Reputation: 0
Thanks for your reply.

The user application:

FILE *ICAP;
printf("Open ICAP ...\n");
ICAP = fopen("/dev/icap0", "r+b");
if (ICAP == NULL)
{
fprintf(stderr, "/dev/icap0 does not exist!\n");
return 1;
}

//read icap
int byte_read;
byte_read = fread(frame, sizeof(*frame), frame_to_read, ICAP);


Driver code: (I do not whether it is helpful)
static ssize_t
hwicap_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
struct hwicap_drvdata *drvdata = file->private_data;
ssize_t bytes_to_read = 0;
u32 *kbuf;
u32 words;
u32 bytes_remaining;
int status;

kbuf = (u32 *) get_zeroed_page(GFP_KERNEL);
printk("<1>\t Get new data from the ICAP\n");
if (!kbuf) {
status = -ENOMEM;
goto error;
}

words = ((count + 3) >> 2);
bytes_to_read = words << 2;

if (bytes_to_read > PAGE_SIZE)
bytes_to_read = PAGE_SIZE;

/* Ensure we only read a complete number of words. */
bytes_remaining = bytes_to_read & 3;
bytes_to_read &= ~3;
words = bytes_to_read >> 2;

printk("<1>\t\t Try to get configuration of %x words\n", words);

status = drvdata->config->get_configuration(drvdata,
kbuf, words);

/*test kernel buffer
int i;
for (i=0; i<words; i++)
printk("<1>\t\t kbuf data at offset %x is %x\n", i, kbuf[i]);
*/

/* If we didn't read correctly, then bail out. */
printk("<1>\t\t Get configuration with status %d\n",status);
if (status) {
free_page((unsigned long)kbuf);
goto error;
}
/* If we fail to return the data to the user, then bail out. */
printk("<1>\t\t Begin copy_to_user %x bytes\n", bytes_to_read);
if (copy_to_user(buf, kbuf, bytes_to_read)) {
free_page((unsigned long)kbuf);
status = -EFAULT;
goto error;
}
printk("<1>\t\t Finish copy_to_user\n");
memcpy(drvdata->read_buffer,
kbuf,
bytes_remaining);
drvdata->read_buffer_in_use = bytes_remaining;
free_page((unsigned long)kbuf);
}
error:
mutex_unlock(&drvdata->sem);
return status;
}


You mentioned " fread should return the actual value it did read, unregarded what you passed in count". However, this device can not return arbitrary bytes. Indeed, before the device read, there is a device write which tells the device how many bytes it should fetch out for next read, so I must control how many bytes to read out with a parameter (otherwise, the device is going to be an abnormal state. This seems weired, but it is a Xilinx FPGA core hooked up as a Linux device and it behaves like this). But it seems that I can't do it with count? Then what should I do?


Quote:
Originally Posted by AngTheo789 View Post
You should post the code fragment - maybe that reveals something. By the way, fread should return the actual value it did read, unregarded what you passed in count.
 
Old 09-25-2009, 11:27 AM   #5
Guttorm
Senior Member
 
Registered: Dec 2003
Location: Trondheim, Norway
Distribution: Debian and Ubuntu
Posts: 1,263

Rep: Reputation: 297Reputation: 297Reputation: 297
Hi

The fopen/fread functions do buffered io, so it can read more to fill a buffer. Either use setvbuf to make it unbuffered, or use open/read instead.
 
Old 09-27-2009, 11:02 PM   #6
intermilan
LQ Newbie
 
Registered: Sep 2009
Posts: 4

Original Poster
Rep: Reputation: 0
Thanks! This works!

Quote:
Originally Posted by Guttorm View Post
Hi

The fopen/fread functions do buffered io, so it can read more to fill a buffer. Either use setvbuf to make it unbuffered, or use open/read instead.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Minimum post count for the "* of the Year Awards" Polls? rocket357 LQ Suggestions & Feedback 6 01-27-2009 10:53 AM
Pass "yes" or "no" to the shell script say_hi_ravi Programming 3 02-14-2008 12:58 AM
Error when using 'find' -- "WARNING: Hard link count is wrong..." xGreenmanx Linux - Software 6 03-11-2006 07:35 PM
UT: "fread failed: BufferCount = -248172 Error=1" occurs after gfx card change SBing Linux - Games 2 07-04-2004 05:40 PM
I can't logon with the "user" and "pass"...help! bseven Linux - Newbie 5 11-08-2002 02:45 PM


All times are GMT -5. The time now is 02:30 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration