`

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

 
阅读更多




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

分享到:
评论

相关推荐

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

    详细介绍了linux字符设备驱动程序,对各个名词做了自己的理解,在学习中的笔记,有错误还请海涵

    Linux 驱动学习笔记pdf文档

    ·Linux设备驱动程序学习(1)-字符设备驱动程序 ·Linux设备驱动程序学习(0)-设备驱动介绍& Hello, world!模块 ·Linux设备驱动程序学习(2)-调试技术 ·Linux设备驱动程序学习(3)-并发和竞态 ·Linux设备...

    linux设备驱动学习笔记

    Linux 设备驱动程序学习(0) -设备驱动介绍& Hello, world!模块 模块结构介绍 字符设备驱动程序 调试技术 并发和竞态 高级字符驱动程序操作 阻塞型 I/O 和休眠

    Linux字符驱动设备--学习笔记

    第三步:insmod加载模块,并生成设备节点mknod。(此步有两种方法); 第四步:编写测试文件test.c并编译成a.out后即可进行设备的读写测试。 在此,希望各位读者不要直接复制我的代码,至少按照我的代码敲一遍,关键...

    Linux学习笔记 第一版

     设备文件:设备文件是一种特别文件,Linux 系统用来标识各个设备驱动器,核心使用它们与硬件设备通信。有两类特别设备文件:字符设备文件和块设备文件。  符号链接:一种特殊文件,存放的数据是文件系统中通向...

    嵌入式Linux入门笔记(十年程序员精品推荐、让你看得懂的笔记、结合开发板例程精心讲解)

    简单的字符设备驱动实验…… 第二阶段在开发板上学习研究Linux. 一.MIZI Linux SDK for S3C2410开发环境及工具使用. 1.构造软件开发环境. 2.编译嵌入式Linux生成image…… 3.将嵌入式Linux的image下载到目标板… … ...

    整理后java开发全套达内学习笔记(含练习)

    abstract (关键字) 抽象 ['æbstrækt] access vt.访问,存取 ['ækses]'(n.... \ddd 1到3位8进制数指定Unicode字符输出(ddd) \uxxxx 1到4位16进制数指定Unicode字符输出(xxxx) \\ \ \' ' \" ...

    asp.net知识库

    VS2005 ASP.NET本地化学习笔记&感受 在自定义Server Control中捆绑JS文件 Step by Step 深度解析Asp.Net2.0中的Callback机制 使用 Web 标准生成 ASP.NET 2.0 Web 站点 ASP.NET 2.0基于SQLSERVER 2005的aspnetdb.mdf...

    若干源程序资料12.rar

    2012-06-11 21:32 318,464 实验42:L298电机驱动程序(ATme.rar 2012-06-11 21:07 13,091 嵌入式拼音输入法C代码.rar 2012-06-11 21:12 64,623 巴特沃斯、切比雪夫I和椭圆滤波器设计的源程序.zip 2012-06-11 21:29 ...

    图像处理工具 Hornil StylePix Pro 2.0.3.0 中文版.zip

    一种便携式版本的运行 Hornil StylePix 从可移动存储设备如USB闪存驱动器,闪存卡,或软盘(媒体)。要安装 Hornil StylePix 便携式,只要下载便携包,然后解压缩。要启动 Hornil StylePix 便携,只需双击您的便携 ...

Global site tag (gtag.js) - Google Analytics