当前位置:编程学习 > C/C++ >>

一个简单的字符设备驱动

1.字符设备驱动源码


[cpp]
#include<linux/module.h>  
#include<linux/init.h>  
#include<linux/types.h>  
#include<linux/fs.h>  
#include<linux/errno.h>  
#include<linux/mm.h>  
#include<linux/sched.h>  
#include<linux/cdev.h>  
#include<asm/io.h>  
#include<asm/system.h>  
#include<asm/uaccess.h>  
 
#include<linux/slab.h> /*kmalloc头文件*/  
#include<linux/semaphore.h>/*信号量头文件*/  
 
#define MEMDEV_MAJOR 251 /*预设的mem的主设备号*/  
#define MEMDEV_NUM 2     /*设备数*/  
#define MEMDEV_SIZE 1024 /*分配的内存大小*/  
 
struct mem_dev 

    unsigned int size; 
    char *data; 
    struct semaphore sem; 
}; 
 
static int mem_major = MEMDEV_MAJOR; /*预设的mem的主设备号*/ 
struct cdev mem_cdev; 
struct mem_dev *mem_devp; /*设备结构体指针*/ 
 
/*文件打开函数*/ 
static int 
mem_open(struct inode *inode,struct file *filp) 

    struct mem_dev *dev; 
    unsigned int num; 
    printk("mem_open.\n"); 
 
    num= MINOR(inode->i_rdev); /*获得次设备号*/ 
    if(num>(MEMDEV_NUM-1)) 
    return -ENODEV; 
     
    dev = &mem_devp[num]; 
    filp->private_data = dev; /*将设备结构保存为私有数据*/ 
     
    return 0; 

 
/*关闭时调用*/ 
static int 
mem_release(struct inode *inode,struct file *filp) 

    printk("mem_release.\n"); 
    return 0; 

 
/*读函数*/ 
static ssize_t 
mem_read(struct file *filp,char __user *buf,size_t size,loff_t *ppos) 

    int ret = 0; 
    struct mem_dev *dev; 
    unsigned long p; 
    unsigned long count; 
     
    printk("mem_read.\n"); 
     
    dev = filp->private_data; /*获得设备结构*/ 
    count = size; 
    p = *ppos; 
     
    /*检查偏移量和数据大小的有效性*/ 
    if(p > MEMDEV_SIZE) 
        return 0; 
    if(count >(MEMDEV_SIZE-p)) 
        count = MEMDEV_SIZE - p; 
    if(down_interruptible(&dev->sem)) /*锁定互斥信号量*/ 
        return -ERESTARTSYS; 
    /*读取数据到用户空间*/ 
    if(copy_to_user(buf,dev->data+p,count)) 
    { 
        ret = -EFAULT; 
        printk("copyfrom user failed\n"); 
    } 
    else 
    { 
        *ppos +=count; 
        ret = count; 
        printk("read %d bytes from dev\n",count); 
    } 
        up(&dev->sem); /*解锁互斥信号量*/ 
        return ret; 

 
/*写函数*/ 
static ssize_t 
mem_write(struct file *filp,const char __user *buf,size_t size,loff_t *ppos) 

    int ret = 0; 
    struct mem_dev *dev; 
    unsigned long p; 
    unsigned long count; 
     
    printk("mem_write.\n"); 
    dev = filp->private_data; 
    count = size; 
     
    p = *ppos; 
    if(p>MEMDEV_SIZE) 
    { 
        return 0; 
    } 
    if(count >(MEMDEV_SIZE- p)) 
    count = MEMDEV_SIZE - p; 
    if(down_interruptible(&dev->sem)) 
        return -ERESTARTSYS; 
    if(copy_from_user(dev->data+p,buf,count)) 
    { 
        ret = -EFAULT; 
        printk("copyfrom user failed\n"); 
    } 
    else 
    { 
        *ppos+=count; 
        ret = count; 
        printk("writed %d bytes to dev\n",count); 
    } 
    up(&dev->sem); 
 
    return ret; 

 
/*修改文件当前的读写位置*/ 
static loff_t 
mem_llseek(struct file *filp,loff_t offset,int whence) 

    int newpos; 
    printk("mem_llsek.\n"); 
    switch(whence) 
    { 
        case 0 : 
            newpos =offset; 
            break; 
        case 1: 
            newpos = filp->f_pos +offset; 
            break; 
        case 2: 
            newpos = MEMDEV_SIZE - 1 +offset; 
            break; 
        default : 
            return -EINVAL; 
    } 
    if((newpos<0)||(newpos>(MEMDEV_SIZE - 1))) 
        return -EINVAL; 
    filp->f_pos = newpos; 
    return newpos; 

 
/*文件操作结构体*/ 
static const struct file_operations mem_fops ={ 
   

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,