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? |
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.
|
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. |
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:
|
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. |
Thanks! This works!
Quote:
|
All times are GMT -5. The time now is 10:26 AM. |