[国嵌攻略][114][自己动手写驱动]

头文件

<linux/cdev.h>

struct cdev

 

<linux/fs.h>

struct file_operations

 

<asm/uaccess.h>

copy_from_user();

copy_to_user();

 

memdev.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <asm/uaccess.h>

//全局变量
struct cdev memdev;   //字符设备
dev_t devnum;         //设备编号

int register0[5];   //设备0寄存器
int register1[5];   //设备1寄存器

//定位设备
loff_t mem_lseek(struct file *filp, loff_t offset, int whence){
    //设置位置
    loff_t newpos;
    
    switch(whence){
        case SEEK_SET:
            newpos = offset;
            break;
        
        case SEEK_CUR:
            newpos = filp->f_pos + offset;
            break;
        
        case SEEK_END:
            newpos = (5 *  sizeof(int)) + offset;
            break;
            
        default:
            newpos = 0;
            break;
    }
    
    //移动位置
    filp->f_pos = newpos;
    
    return newpos;
}

//读取设备
ssize_t mem_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos){
    //获取地址
    int *base;
    
    base = filp->private_data + *ppos;
    
    //读取数据
    copy_to_user(buf, base, size);
    
    //移动位置
    filp->f_pos += size;
    
    return size;
}

//写入设备
ssize_t mem_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos){
    //获取地址
    int *base;
    
    base = filp->private_data + *ppos;
    
    //写入数据
    copy_from_user(base, buf, size);
    
    //移动位置
    filp->f_pos += size;
    
    return size;
}

//打开设备
int mem_open(struct inode *node, struct file *filp){
    //获取次设备号
    int secnum;
    
    secnum = MINOR(node->i_rdev);
    
    //设置设备地址
    if(secnum == 0){
        filp->private_data = register0;
    }
    
    if(secnum == 1){
        filp->private_data = register1;
    }
    
    return 0;
}

//关闭设备
int mem_colse(struct inode *node, struct file *filp){
    return 0;
}

//设备方法
struct file_operations memfops = {
    .llseek  = mem_lseek,
    .read    = mem_read,
    .write   = mem_write,
    .open    = mem_open,
    .release = mem_colse
};

//驱动注册
static int memdev_init(){
    //注册设备结构
    cdev_init(&memdev, &memfops);
    
    //注册主设备号
    alloc_chrdev_region(&devnum, 0, 2, "memdev");
    
    //添加设备结构
    cdev_add(&memdev, devnum, 2);
    
    return 0;
}

//驱动注销
static void memdev_exit(){
    //注销设备结构
    cdev_del(&memdev);
    
    //注销主设备号
    unregister_chrdev_region(devnum, 2);
}

//驱动声明
MODULE_LICENSE("GPL");
MODULE_AUTHOR("D");
MODULE_DESCRIPTION("memdev");
MODULE_VERSION("v1.0");

module_init(memdev_init);
module_exit(memdev_exit);

 

read.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc, char **argv){
    //打开设备文件
    int fd;
    
    fd = open("/dev/memdev0", O_RDWR);
    
    //读取数据
    int num;
    
    read(fd, &num, sizeof(num));
    printf("num is %d\n", num);
    
    //关闭设备文件
    close(fd);
    
    return 0;
}

 

write.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char **argv){
    //打开设备文件
    int fd;
    
    fd = open("/dev/memdev0", O_RDWR);
    
    //写入数据
    int num;
    
    num = 2016;
    write(fd, &num, sizeof(num));
    
    //关闭设备文件
    close(fd);
    
    return 0;
}

 

posted @ 2016-03-07 15:47  盛夏夜  阅读(565)  评论(0编辑  收藏  举报