字符设备驱动程序学习笔记三

来源:互联网 发布:windows卸载cuda8.0 编辑:程序博客网 时间:2024/05/17 13:38



memdev.h文件示例代码如下:
  #ifndef _MEMDEV_H
#define _MEMDEV_H


//采用静态分配设备号
#ifndef MEMDEV_MAJOR
#define MEMDEV_MAJOR 260
#endif


#ifndef MEMDEV_NR_DEVS
#define MEMDEV_NR_DEVS 2
#endif


#ifndef MEMEV_SIZE
#define MEMDEV_SIZE 4096
#endif


struct mem_dev{
        char *data;
        unsigned long size;
};


#endif




memdev.c文件示例代码如下:
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>


#include "memdev.h"


MODULE_LICENSE("GPL");
MODULE_AUTHOR("Retacn Yue");
MODULE_DESCRIPTION("memdev module");
MODULE_ALIAS("memdev module");


static int mem_major=MEMDEV_MAJOR;
module_param(mem_major,int,S_IRUGO);


struct mem_dev *mem_devp;
struct cdev cdev;


/*初始化*/
int mem_open(struct inode *inode,struct file *filp){
        struct mem_dev *dev;
        int num=MINOR(inode->i_rdev);


        if(num>MEMDEV_NR_DEVS){
                return -ENODEV;
        }
        dev=&mem_devp[num];
        filp->private_data=dev;
        return 0;
}


/*关闭释主资源*/
int mem_release(struct inode *inode,struct file *flip){
        return 0;
}


/*从字符设备读取数据*/
static ssize_t mem_read(struct file *filp,char __user *buff,size_t 


size,loff_t *poss){
        unsigned long p=*poss;
        unsigned int count=size;
        int ret=0;
        struct mem_dev *dev=filp->private_data;


        if(p>=MEMDEV_SIZE)
                return 0;
        if(count>MEMDEV_SIZE-p)
                count=MEMDEV_SIZE-p;
        if(copy_to_user(buff,(void*)(dev->data+p),count)){
                ret=-EFAULT;
        }else{
                *poss+=count;
                ret=count;
                printk(KERN_INFO "read %d bytes form %lu\n",count,p);
        }
     return 0;
}
/*向字符设备发送数据*/
static ssize_t mem_write(struct file *filp,const char __user 


*buf,size_t size,loff_t *poss){
        unsigned long p=*poss;
        unsigned int count=size;
        int ret=0;
        struct mem_dev *dev=filp->private_data;


        if(p>=MEMDEV_SIZE)
                return 0;
        if(count>MEMDEV_SIZE-p)
                count=MEMDEV_SIZE-p;
        if(copy_from_user(dev->data+p,buf,count)){
                ret=-EFAULT;
        }else{
                *poss+=count;
                ret=count;
                printk(KERN_INFO "write %d bytes from %lu\n",count,p);
        }
      return 0;
}
/*修改文件当前读写位置*/
static loff_t mem_llseek(struct file *filp,loff_t offset, int whence){
        loff_t newpos;


        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))
                return -EINVAL;


        filp->f_pos=newpos;
      return 0;
}
/*应用程序在设备上调用的所有操作*/
static const struct file_operations mem_fops={
        .owner=THIS_MODULE,
        .llseek=mem_llseek,
        .read=mem_read,
        .write=mem_write,
        .open=mem_open,
        .release=mem_release
};


/*初始化方法 :分配设备号
               字符设备注册
*/
static int memdev_init(void){
        int result;
        int i;
        dev_t devno=MKDEV(mem_major,0);


        /*静态分配*/
        if(mem_major){
                result=register_chrdev_region(devno,2,"memdev");
        }
        /*动态分配*/
        else{
                result=alloc_chrdev_region(&devno,0,2,"memdev");
                mem_major=MAJOR(devno);
        }
 if(result<0)
                return result;


        /*初始化*/
        cdev_init(&cdev,&mem_fops);
        cdev.owner=THIS_MODULE;
        cdev.ops=&mem_fops;


/*添加设备文件*/
        cdev_add(&cdev,MKDEV(mem_major,0),MEMDEV_NR_DEVS);


        mem_devp=kmalloc(MEMDEV_NR_DEVS * sizeof(struct 


mem_dev),GFP_KERNEL);
        if(!mem_devp){
                result=-ENOMEM;
                goto fail_malloc;
        }
        memset(mem_devp,0,MEMDEV_NR_DEVS * sizeof(struct mem_dev));


        for(i=0;i<MEMDEV_NR_DEVS;i++){
                mem_devp[i].size=MEMDEV_SIZE;
                mem_devp[i].data=kmalloc(MEMDEV_SIZE,GFP_KERNEL);
                memset(mem_devp[i].data,0,MEMDEV_SIZE);
        }
        return 0;
fail_malloc:
        unregister_chrdev_region(devno,2);
        return result;
}
static void memdev_exit(void){
        cdev_del(&cdev);
        kfree(mem_devp);
        unregister_chrdev_region(MKDEV(mem_major,0),2);
}




module_init(memdev_init);
module_exit(memdev_exit);




makefile文件示例代码如下:
ifneq ($(KERNELRELEASE),)
obj-m:=memdev.o
else
KERNELDIR:=/opt/FriendlyARM/mini6410/linux/linux-2.6.38
PWD:=$(shell pwd)
all:
        make -C $(KERNELDIR) M=$(PWD) modules ARCH=arm 


CROSS_COMPILE=arm-linux-
clean:
        rm -fr *.ko *.o *.mod.c *mod.o *.symvers
endif


编译:make 
生成memdev.ko文件下载到开发板/lib/modules/
加载模块
[root@FriendlyARM modules]# lnsmod memdev.ko
查看设备节点
[root@FriendlyARM modules]# cat /proc/devices
创建设备文件
[root@FriendlyARM modules]# cd /dev
[root@FriendlyARM dev]# mknod memdev0 c 260 0
  








测试字符设备驱动


示例代码如下:
/*测试字符设备驱动*/
int main(){
        int fd;
        char buf[4096];


        strcpy(buf,"this is  a example of charactar devices driver");
        printf("buf:%s\n",buf);


        fd=open("/dev/memdev0",O_RDWR);
        if(fd==-1){
                printf("open memdev failed!\n");
                return -1;
        }


        write(fd,buf,sizeof(buf));
        lseek(fd,0,SEEK_SET);
        strcpy(buf,"nothing");
        read(fd,buf,sizeof(buf));
        printf("buf:%s\n",buf);


        return 0;
}


编译:
[root@localhost memdev]# arm-linux-gcc -o memdevapp memdevapp.c
将生成的memdevapp下载到开发板,运行应用程序
[root@FriendlyARM plg]# ./memdev/app 
运行结果如下:
[root@FriendlyARM plg]# ./memdevapp 
buf:this is  a example of charactar devices driverwrite 4096 bytes from 


0
read 4096 bytes form 0


buf:this is  a example of charactar devices driver
原创粉丝点击