linux 字符设备(一)
发布时间:2020-12-14 00:38:09 所属栏目:Linux 来源:网络整理
导读:字符设备驱动代码编写 一、驱动模块代码编写 #include linux/init.h#include linux/cdev.h#include linux/module.h#include linux/fs.h#include linux/device.h #include linux/kernel.h#include linux/types.h#include asm/uaccess.hstatic int data;static
字符设备驱动代码编写一、驱动模块代码编写#include <linux/init.h> #include <linux/cdev.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/device.h> #include <linux/kernel.h> #include <linux/types.h> #include <asm/uaccess.h> static int data; static int chr_open (struct inode * inode,struct file * file){ printk("character device openn"); return 0; } static int chr_release (struct inode * inode,struct file * file){ printk("character device closen"); return 0; } ssize_t chr_read (struct file * file,char __user * buf,size_t size,loff_t * offset){ if(copy_to_user(buf,&data,sizeof(data))){ printk("copy failedn"); return -EFAULT; } return sizeof(data); } ssize_t chr_write (struct file * file,const char __user * buf,loff_t * offset){ if(copy_from_user(&data,buf,sizeof(data))){ printk("copy failedn"); return -EFAULT; } return sizeof(data); } /* file_operations 用来存储驱动内核模块提供的对设备进行各种操作的函数的指针。 * 该结构体的每个域都对应着驱动内核模块用来处理某个被请求的事务的函数的地址。 */ static struct file_operations chr_fop = { .open = chr_open,.release = chr_release,.read = chr_read,.write = chr_write,}; static struct cdev *my_chr_cdev; static struct class *chr_class; static dev_t device; /* 驱动模块的入口函数 */ static int chr_test_init(void){ if (device){ /* 静态申请设备号 */ register_chrdev_region(device,1,"chr_dev"); }else{ /* 动态申请设备号 */ alloc_chrdev_region(&device,"chr_dev"); } /* 申请空间 */ my_chr_cdev = cdev_alloc(); /* 注册字符设备驱动 */ cdev_init(my_chr_cdev,&chr_fop); cdev_add(my_chr_cdev,device,1); /* 创建设备节点 */ chr_class = class_create(THIS_MODULE,"mydev"); class_device_create(chr_class,NULL,"mydev"); return 0; } /* 驱动模块的退出函数 */ static void chr_test_exit(void){ /* 删除设备节点 */ class_device_destroy(chr_class,device); class_destroy(chr_class); /* 注销字符设备驱动 */ cdev_del(my_chr_cdev); /* 释放空间 */ cdev_put(my_chr_cdev); /* 释放设备号和相应的设备名 */ unregister_chrdev_region(device,1); } /* 这个宏将 chr_test_init 函数修饰为模块的入口函数 */ module_init(chr_test_init); /* 这个宏将 chr_test_exit 函数修饰为模块的退出函数 */ module_exit(chr_test_exit); /* 遵循GPL协议 */ MODULE_LICENSE("GPL"); 二、编写Makefile#内核源码树路径 KERN_DIR = /work/system/kernel/source/linux-2.6.22.6 #目标文件 obj-m += first.o all: make -C $(KERN_DIR) M=`pwd` modules clean: make -C $(KERN_DIR) M=`pwd` modules clean 三、测试应用程序#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> int buf; int main(int argc,char** argv){ int fd; if((fd = open("/dev/mydev",O_RDWR))<0){ printf("open device failedn"); return -1; } /* 将数据写到驱动程序,再读出来验证 */ for(int i=0; i<10; i++){ write(fd,&i,sizeof(i)); read(fd,&buf,sizeof(buf)); printf("read the data is:%dn",buf); sleep(1); } close(fd); return 0; } 四、编译测试1、编译内核驱动将源代码和Makefile考到linux系统,然后执行 2、编译测试程序编译 3、测试插入内核模块 五、小结(在设备驱动中常用的命令) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |