world leader in high performance signal processing
Trace: » basic-vfs-read-write

Device Driver ... Read/Write Functions

These functions are used to read and write data to a device. The kernel system call adds two extra parameters (filep and loff_t) to the original user call.

In the following examples the device driver will read and write to a small buffer in kernel space to simulate data transfer to an actual device.

// small buffer used by our demonstration driver
#define SCMD_SIZE 32
static char scmd_data[SCMD_SIZE];

Read/Write parameters

The parameters for the read and write functions are almost the same.

filep    - the kernel allocated driver structure   
buf      - the user space buffer                   
count    - the number of bytes to transfer         
lofft    - the offset of the first byte to transfer

Return value

The return value is the actual count of data written to or read from the device.
For a read a return value of 0 is used to indicate that no more data is available.
For a write a return value of zero indicates that no data was written.

Driver Read Function

The Read Function transfers count chars from the device into a user space buffer (buf):

static ssize_t scmd_read(struct file *filep, char *buf, size_t  count, 
                           loff_t * f_pos) 
{                             
     int pos;                                                            
     int size;                                                           
 
     pos = *f_pos;                                                       
     size = SCMD_SIZE;                                                   
 
     /* check limits */                                                  
     if (pos >= size) pos = size-1;                                      
     if ((pos + count) >= size) count = (size - pos) - 1;                
 
     /* copy count from kernel buffer to user space buffer */            
     /* copy_to_user returns 0 on success */                             
     if (copy_to_user(buf,&scmd_data[pos],count))                        
        return -EFAULT;                                                  
     pos += count;                                                       
     //filep->f_pos = pos; // Note this is deprecated                            
     *f_pos = pos;  // new for 2.6 Kernel                                
     return count;                                                       
  }                                                                      
 

Driver Write Function

The write function transfers count chars from user space to the device

static ssize_t scmd_write(struct file *filep,                    
                            const char *buf, size_t  count,        
                            loff_t * f_pos) 
{                      
     int pos;                                                      
     int size;                                                     
 
     pos = *f_pos;                                                 
     size = SCMD_SIZE;                                             
 
     /* check limits */                                            
     if (pos >= size) pos = size;                                  
     if ((pos + count) >= size) count = (size - pos) - 1;          
 
     /* copy count from a user space buffer to the kernel buffer */
     /* copy_from_user returns 0 on success */                    
     if (copy_from_user(&scmd_data[pos],buf,count))               
        return -EFAULT;                                           
     pos += count;                                                
     //filep->f_pos = pos;  // Note Deprecated                    
     *f_pos = pos; // new for 2.6 Kernel                          
     return count;                                                
  }

Transferring Data

The Linux kernel provides a pair of functions to carry out data transfer between user space and kernel space.

These functions provide a check that the user space is valid.

They return the number of un copied bytes should an error in the count or buffer be detected. The driver should return such an error to the user code.

The kernel will automatically handle any page swapping required to map the user data space.

#include <linux/uaccess.h>