700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Linux---字符设备驱动程序设计

Linux---字符设备驱动程序设计

时间:2020-09-28 22:03:41

相关推荐

Linux---字符设备驱动程序设计

编写一个虚拟字符设备驱动程序char.c,

以内核模块的形式插入内核,编译方法与内核编译方法一致。创建设备节点,然后通过编写一个测试程序,功能:首先向设备中写入数据,再从设备中读出数据,并把数据显示在屏幕上。

4. 要求:设备名为:demo,主设务号为250,次设备号为0。

1、首先,要确保环境已经安装好了

开始写

写三个文件

char.c

Makefileps:M必须大写

test.c 用于测试

vi char.cvi Makefilevi test.c

这三个文件的具体代码我放在文末

写好了之后执行make命令

make

然后加载驱动程序

sudo insmod char.kolsmod //查看是否加载成功

必须使用管理员权限

在dev目录下创建设备文件

sudo mknod /dev/mychar c 250 0//要使用管理员权限 //1. 命令中的数字要和驱动程序定义的major,minor保持一致。//2. Mychar文件名与测试程序 中的名字一致

编译运行测试程序

gcc test.c -o testsudo ./test

char.c代码

#include<linux/module.h> #include<linux/kernel.h>#include<linux/init.h>#include<linux/fs.h>#include<linux/cdev.h>#include<asm/ioctl.h>#include<asm/io.h>#include<asm/uaccess.h>MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Bob Geng");MODULE_DESCRIPTION("a simple driver");#define N 128int major = 250;int minor = 0;struct cdev mycdev; //字符型结构体char buf[N] ={"hello world !!"};int char_open (struct inode * myinode, struct file *fp){printk("char is opened\n");return 0;}int char_release (struct inode *myinode, struct file *fp){printk("char is closeed\n");return 0;}static ssize_t char_read (struct file *filep, char __user *user_buf, size_t count, loff_t * off){ // 1. ssize_t :ssize_t是signed size_t;size_t: unsigned int//2. Off:当前文件的偏移量ssize_t ret =0;long num =0;printk("char_read is called\n");printk("count is %d\n",count);num = copy_to_user(user_buf,buf,count);if(num < 0 ){printk("copy_to_user is failed\n");return ret;}return ret;}ssize_t char_write (struct file *filep, const char __user *from, size_t count, loff_t *off){ssize_t ret =0; long num =0;printk("char_write is called \n");printk("count is %d\n",count);// if(count > N ) return -ENOMEM;if(count > N ) count = N ;num = copy_from_user(buf,from,count);if(num < 0 ){printk("copy_to_user is failed\n");return ret;}printk("from user is %s\n",buf);return ret; }struct file_operations fops={.owner = THIS_MODULE,.open = char_open,.release = char_release, .read = char_read, .write = char_write, };static int __init char_init(void){int ret;dev_t devno = MKDEV(major,minor);ret = register_chrdev_region(devno,1,"char"); //静态申请设备号if(ret < 0 ){printk("fail to get devno\n");return ret;}mycdev.owner = THIS_MODULE;cdev_init(&mycdev,&fops);ret = cdev_add(&mycdev,devno,1);if(ret < 0 ){printk("cdev_add fail to system\n");return ret;}printk("init_module\n");return 0;}static void __exit char_exit(void){dev_t devno = MKDEV(major,minor);cdev_del(&mycdev);unregister_chrdev_region(devno, 1);printk("cleanup_module\n");}module_init(char_init);module_exit(char_exit);

Makefile代码

ifeq ($(KERNELRELEASE),)KERNELDIR ?= /lib/modules/$(shell uname -r)/build #KERNELDIR ?= /home/linux/workdir/source-pack/linux-3.2-net/ (交叉编译)M=$(PWD) modulesPWD := $(shell pwd)modules:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesmodules_install:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_installclean:rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module* modules*.PHONY: modules modules_install cleanelseobj-m :=char.oendif

test.c代码

#include<stdio.h>#include<errno.h>#include<unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <stdlib.h>#include <fcntl.h>#include <sys/ioctl.h>#include <string.h>#define N 128char buf[N] ; int main(){int fd;if ( (fd = open("/dev/mychar",O_RDWR)) < 0){perror("open");exit(-1);}if(read(fd,buf,N ) < 0 ){perror("read");exit(-1);}printf("read from mychar is %s\n",buf);// memset(buf,0,sizeof(buf));//strcpy(buf,"goddbye\0");printf("please input second buf:\n");scanf("%s",buf);if(write(fd,buf,N+1) < 0){perror("write");exit(-1);}if(read(fd,buf,N ) < 0 ){perror("read");exit(-1);}printf("second read from mychar is %s\n",buf);getchar();printf("mychar is opened\n");close(fd);}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。