博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
字符设备驱动程序学习笔记三
阅读量:5013 次
发布时间:2019-06-12

本文共 4820 字,大约阅读时间需要 16 分钟。

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

转载于:https://www.cnblogs.com/retacn-yue/archive/2013/04/04/3263123.html

你可能感兴趣的文章
C#例子 易懂故事 接口 委托 事件 异步通知 好玩.
查看>>
[转]Windows Shell 编程 第十一章 【来源:http://blog.csdn.net/wangqiulin123456/article/details/7987992】...
查看>>
修改presto新版源码让他支持redash数据库
查看>>
Javascript的书写位置
查看>>
树-线索二叉树
查看>>
JAVA遇见HTML——Servlet篇:Servlet基础
查看>>
第二章 Vue快速入门--20 品牌案例-完成品牌列表的添加功能+ 21 品牌案例-根据Id完成品牌的删除...
查看>>
Java单例模式
查看>>
重温WCF之消息契约(MessageContract)(六)
查看>>
Excel2007制作直方图和正态分布曲线图
查看>>
android adb常用指令
查看>>
Android框架之路——GreenDao3.2.2的使用
查看>>
类方法WCF学习笔记-KnowTypeAttribute用法
查看>>
平台程序微信平台开发应用的签名
查看>>
程序卡OK6410裸板更新程序_update
查看>>
MYSQL用户名:root
查看>>
JavaScript 开发规范要求
查看>>
Devstack 安装OpenStack Pike版本(单机环境)
查看>>
Javascript 函数初探
查看>>
类的定义、声明使用
查看>>