Linux字符设备驱动
来源:互联网 发布:java事务的隔离级别 编辑:程序博客网 时间:2024/06/15 19:15
- 实现一组对外的访问接口, open、release、read、write将这些函数的实现赋值给file_operations这个结构体中。
- 实现对字符设备驱动程序的创建和初始化。
- 按照内核模块的编写方法去制定对应的入口函数和出口函数。入口函数实现对驱动程序的注册功能,需要调用驱动程序的初始化函数进行初始化操作。出口函数就是完成对程序的卸载;
- 编译对应的驱动程序源码,从而得到.ko文件,查看/proc/devices文件,从而判断对应的驱动程序是否注册成功,若成功,在/dev目录下将会看到创建对应的设备文件以及设备号,通过mknod命令实现
art.c
//art.c#include <stdlib.h>#include <stdio.h>#include <string.h>#include <sys/stat.h>#include <sys/types.h>#include <unistd.h>#include <fcntl.h>#define TEST_DEVICE_FILENAME "/dev/art_dev" //设备文件名#define BUFF_SIZE 1024int main(){ int fd,nwrite,nread; char buff[BUFF_SIZE]; //缓冲区 /* 打开文件 */ fd=open("/dev/art_dev",O_RDWR); if(fd<0){ perror("open"); exit(1); } do{ printf("向内核输入字符内容为('q'退出):"); memset(buff,0,BUFF_SIZE); if(fgets(buff,BUFF_SIZE,stdin)==NULL){ perror("error fgets"); break; } buff[strlen(buff)-1]='\0'; if(write(fd,buff,strlen(buff))<0) //向内核设备写入数据 { perror("error write"); break; } if(read(fd,buff,BUFF_SIZE)<0) //从内核设备读取数据 { perror("error write"); break; } else{ printf("从内核中读出字符内容为:%s\n\n",buff); } }while(strncmp(buff,"q",1)); close(fd); exit(0);}
art_dev.c
//art_dev.c#include <linux/module.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/kernel.h>#include <linux/slab.h>#include <linux/types.h>#include <linux/errno.h>#include <linux/cdev.h> #include <asm/uaccess.h>#define TEST_DEVICE_NAME "art_dev" #define BUFF_SIZE 1024// 全局变量 static struct cdev art_dev;unsigned int major = 0;//主设备号static char *data = NULL;//内核空间大小dev_t dev;//起始的设备编号/* 写函数 */static ssize_t art_write(struct file *file, const char *buffer, size_t count, loff_t *f_pos){ if(count<0) { return -EINVAL; } memset(data,0,BUFF_SIZE); count=(BUFF_SIZE>count) ?count:BUFF_SIZE; if(copy_from_user(data,buffer,count)) //将用户缓冲的数据复制到内核空间 { return -EFAULT; } return count;}/* 读函数 */ static ssize_t art_read( struct file *file, char *buf, size_t count, loff_t *f_pos){ int len; if(count<0) { return -EINVAL; } len=strlen(data); count=(len>count)?count:len; if(copy_to_user(buf,data,count)) //将内核缓冲的数据复制到用户空间 { return -EFAULT; } return count;}/* 打开函数 */static int art_open(struct inode *inode,struct file *file){ printk("This is open operation.\n"); /* 分配并初始化缓冲区 */ data=(char*)kmalloc(sizeof(char)*BUFF_SIZE,GFP_KERNEL); if(!data) { printk("malloc error!"); return -ENOMEM; } memset(data,0,BUFF_SIZE); return 0;}/* 关闭函数 */static int art_release(struct inode *inode,struct file *file){ printk("This is release operation.\n"); if(data) { kfree(data); //释放缓冲区 data=NULL; //防止出现野指针 } return 0;}/* 虚拟设备的file——operation结构 */static struct file_operations art_fops={ .owner=THIS_MODULE, .read=art_read, .write=art_write, .open=art_open, .release=art_release, };/* 创建、初始化字符设备,并且注册到系统 */static void art_setup_cdev( struct cdev *cdev, int minor, struct file_operations *fops){ int error; cdev_init(cdev,fops); cdev->owner=THIS_MODULE; cdev->ops=fops; error=cdev_add(cdev,dev,1); if(error) { printk(KERN_NOTICE"Error %d adding test %d",error,minor); }}//模块注册入口 static int __init _init_artmodule(void){ int result; dev=MKDEV(major,0); if(major) { //静态注册一个设备,设备号事先指定好,用cat/proc/devices来查看 result=register_chrdev_region(dev,1,TEST_DEVICE_NAME); } else { //动态分配一个设备号 result=alloc_chrdev_region(&dev,0,1,TEST_DEVICE_NAME); } if(result<0) { printk(KERN_WARNING"Test device:unable to get major %d\n",major); return result; } art_setup_cdev(&art_dev,0,&art_fops); printk("The major of the test device is %d\n",dev); return 0;}/* 卸载模块 */static void __exit _cleanup_artmodule(void){ cdev_del(&art_dev); unregister_chrdev_region(MKDEV(major,0),1); printk("Test device uninstalled.\n");}module_init(_init_artmodule);module_exit(_cleanup_artmodule);
MaKefile
ifeq ($(KERNELRELEASE),) KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules modules_install: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions .PHONE: modules modules_install clean else obj-m := art_dev.o endif
字符设备调试步骤
linux字符设备驱动设计与实现详细文档下载
360云盘下载,点击前复制密码 访问密码 4e86
1 0
- LINUX--字符设备驱动
- Linux字符设备驱动
- Linux字符设备驱动
- Linux字符设备驱动
- linux字符设备驱动
- linux字符设备驱动
- linux 字符设备驱动
- linux字符设备驱动
- linux 字符设备驱动
- Linux字符设备驱动
- linux字符设备驱动
- Linux字符设备驱动
- linux 字符设备驱动
- Linux字符设备驱动
- linux字符设备驱动
- Linux字符设备驱动
- Linux字符设备驱动
- Linux 字符设备驱动
- CityMaker研修之路 02 伟景行(CityMaker)的倾斜之路
- 社区轻量级
- hdu 1301(最小生成树kruskal)
- 给大一ACM队员的四个问题答复
- 如何通过Html生成JSON格式字符串
- Linux字符设备驱动
- 欢迎使用CSDN-markdown编辑器
- eclipse 第一个Java程序
- UBOOT 常用 COMMAND
- Tomcat下使用虚拟主机将项目部署成顶级域名
- 物体碰撞说明(当鼠标放在某一地方,显示此物体的Tag)
- CSS——CSS的三种书写方式 CSS选择器
- 我国设备管理的领导体制与组织形式
- Jquery tab插件wdScrollTab 在chrome中出现不兼容的问题