|
2#
楼主 |
发表于 2018-4-24 17:31:15
|
只看该作者
test.c
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include<linux/cdev.h>
- struct cdev chrdev3;
- unsigned int TestMajor=0;
- unsigned int TestMinor=0;
- dev_t dev_no;
- int testopen(struct inode *inode, struct file *file)
- {
- //LED输出
- printk("led init \n");
- }
- int testclose (struct inode *inode, struct file *file);
- {
- printk("close");
- return 0;
- }
- ssize_t testwrtie(struct file *, char __user *usr, size_t len, loff_t *offf)
- {
- char buf[12];
- copy_from_user(buf,usr,);
- buf[12];
- //if(buf[]=='1')
- // led点明
- printk(,buf);
- }
- ssize_t testread(struct file *, char __user *usr, size_t len, loff_t *);
- {
- char buf='r';
- read_led;
- copy_to_user(usr,buf,);
- }
- struct file_operations fops= --->结构体初始化 .---???????????????
- { .owner=THIS_MODULE,
- .open=testopen,
- .write=testwrite,
- .release=testclose,
- }
- static int __init test_init(void) //入口函数
- {
- printk("hello world!\n"); //相当于printf()
- int ret;
- dev_no =MKDEV(TestMajor,TestMinor)
- if(dev_no>0)
- {
- ret=register_chrdev_region(dev_no, 1,"chrdev_test");//静态注册设备号
- }
- else //动态申请设备号
- {
- alloc_chrdev_region(&dev_no,TestMinor, 1,"chrdev_test");
- }
- if(ret<0)
- {
- return ret;
- }
- cdev_init(&chrdev3,&fops);
- cdev.owner=THIS_MODULE;
- cdev_add(&chrdev3,dev_no,1);
- return 0;
- }
- static void __exit test_exit(void) //出口函数
- {
- unregister_chrdev_region(dev_no, 1);
- cdev_del(&chrdev3);
- }
- module_init(test_init); //驱动的入口 #insmod *.ko
- module_exit(test_exit); //驱动的出口 #rmmod *.ko
- //#modinfo *.ko 可以查看module的信息
- MODULE_AUTHOR("fbx@GEC");
- MODULE_DESCRIPTION("the first module of drivers");
- MODULE_LICENSE("GPL");
- MODULE_VERSION("V1.0");
复制代码
---------------------------------------------------------------------
8.linux用户空间与内核空间交互函数。
8.1将内核空间数据copy用户空间
unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
8.2用户空间数据copy内核空间
unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) ---> write
练习:应用调用write写一个字符到内核空间,内核那驱动程序的.write---》 PRINTK();
应用调用read把一个数据从内核读到用户,用户空间打印出来
chrdev.c
- 1 #include<linux/module.h>
- 2 #include<linux/kernel.h>
- 3 #include<linux/cdev.h>
- 4 #include<linux/fs.h>
- 5 #include<linux/kdev_t.h>
- 6 #include<linux/types.h>
- 7 #include<linux/uaccess.h>
- 8 #include<linux/string.h>
- 9 struct cdev chrdev;
- 10 unsigned int TestMajor=0;
- 11 unsigned int TestMinor=0;
- 12 dev_t dev_no;
- 13 int ret;
- 14
- 15 int testopen(struct inode *inode,struct file *file)
- 16 {
- 17 printk("cdev init\n");
- 18 return 0;
- 19
- 20 }
- 21 ssize_t testwrite(struct file *file, const char __user *usr, size_t len, loff_t *off)
- 22 {
- 23 char buf[12];
- 24
- 25 copy_from_user(buf,usr,strlen(usr));
- 26 printk("%s\n",buf);
- 27
- 28 }
- 29 ssize_t testread(struct file *file, char __user *usr, size_t len, loff_t *off)
- 30 {
- 31 char *buf = "hello,user!";
- 32 copy_to_user(usr,buf,20);
- 33
- 34
- 35 }
- 36 int testrelease(struct inode *inode, struct file *file)
- 37 {
- 38 printk("close\n");
- 39 return 0;
- 40
- 41 }
- 42
- 43 struct file_operations fops=
- 44 {
- 45 .owner=THIS_MODULE,
- 46 .open = testopen,
- 47 .write = testwrite,
- 48 .read = testread,
- 49 .release = testrelease,
- 50 };
- 51 static int __init test_init(void)
- 52 {
- 53 dev_no = MKDEV(TestMajor,TestMinor);
- 54 if(dev_no>0)
- 55 {
- 56 ret = register_chrdev_region(dev_no,1,"chrdev_test");
- 57 }
- 58 else
- 59 {
- 60 alloc_chrdev_region(&dev_no,0,1,"chrdev_test");
- 61 }
- 62 if(ret<0)
- 63 {
- 64 return ret;
- 65 }
- 66 cdev_init(&chrdev,&fops);
- 67 chrdev.owner=THIS_MODULE;
- 68 cdev_add(&chrdev,dev_no,1);
- 69 return 0;
- 70 }
- 71
- 72 static int __exit test_exit(void)
- 73 {
- 74 unregister_chrdev_region(dev_no,1);
- 75 cdev_del(&chrdev);
- 76
- 77 return 0;
- 78 }
- 79
- 80 module_init(test_init);
- 81 module_exit(test_exit);
- 82
- 83
- 84 MODULE_AUTHOR("FENG");
- 85 MODULE_DESCRIPTION("the first module of char drivers");
- 86 MODULE_LICENSE("GPL");
- 87 MODULE_VERSION("V1.0");
- 复制代码
- 7.字符设备的调试
- 7。1安装驱动
- [@GEC2103 /]# insmod chrdev.ko
- 7.2查看分配的设备号
- [@GEC2103 /]# cat /proc/devices
- 250 chrdev_test
- 7.3手动创建设备文件
- mknod /dev/chrdev c 250 0
- [@GEC2103 /]# ls /dev/chrdev -l
- crw-r--r-- 1 0 0 250, 0 Jan 1 00:45 /dev/chrdev
- 7.4应用程序来/dev/chrdev设备文件,等效操作设备文件对应那个设备
- int main()
- {
- fd=open("/dev/chrdev",O_RDWR);
- write(fd,usrbuf,sizeof(usrbuf))
- close(fd);
- }
- --------------------------------------------------------------------------------
- test.c
- 复制代码
- 1 #include<stdio.h>
- 2 #include <sys/stat.h>
- 3 #include <fcntl.h>
- 4 #include <errno.h>
- 5 #include <unistd.h>
- 6 #include <string.h>
- 7
- 8 int main()
- 9 {
- 10 char buf[20];
- 11 char buf1[20];
- 12 int fd = open("/dev/chrdev_test",O_RDWR);
- 13 if(fd<0)
- 14 perror("open() error!\n");
- 15 bzero(buf1,20);
- 16 strcpy(buf1,"hello kernel!");
- 17 write(fd,buf1,strlen(buf1)+1);
- 18 sleep(1);
- 19 read(fd,buf,20);
- 20 printf("%s\n",buf);
- 21 }
- 复制代码
- 9。字符设备设计老的方法
- 优点:比新简洁,比较好理解.
- 1.使用函数
- 1)注册字符设备
- static inline int register_chrdev(unsigned int major, const char *name,const struct file_operations *fops);
- 参数:
- major--->主设备号,如果major>0,静态注册
- =0 动态分配
- name-->设备名称 /proc/devices
- fops-->文件操作集
- 返回值:
- major >0 成功:0
- 失败:负数
- major =0 成功:分配后主设备号
- 失败:负数
- 2)注销字符设备
- static inline void unregister_chrdev(unsigned int major, const char *name)
- major->主设备号
- name-->设备名称
- 2.使用旧方法设计字符设备驱动的流程
- 2.1unsigned int Testmajor =0;//251
- 2.2定义文件操作集
- int testopen(struct inode *inode, struct file *file)
- {
- }
- int testclose (struct inode *inode, struct file *file);
- {
- }
- ssize_t testwrtie(struct file *, char __user *, size_t, loff_t *)
- {
- }
- struct file_operations fops= --->结构体初始化 .---???????????????
- { .owner=THIS_MODULE,
- .open=testopen,
- .write=testwrite,
- .release=testclose,
- }
- 2.3注册一个字符设备
- ret=register_chrdev(Testmajor,"chrdev_test",&fops);//注册字符设备到内核
- if(ret<0)
- {
- printk("register error")
- }
- if(Testmajor==0)
- {
- Testmajor =ret;
- }
- 复制代码
- 1 #include<linux/module.h>
- 2 #include<linux/kernel.h>
- 3 #include<linux/cdev.h>
- 4 #include<linux/fs.h>
- 5 #include<linux/kdev_t.h>
- 6 #include<linux/types.h>
- 7 #include<linux/uaccess.h>
- 8 #include<linux/string.h>
- 9
- 10 dev_t dev_no = 0;
- 11 int ret;
- 12
- 13 int testopen(struct inode *inode,struct file *file)
- 14 {
- 15 printk("cdev init\n");
- 16 return 0;
- 17
- 18 }
- 19 ssize_t testwrite(struct file *file, const char __user *usr, size_t len, loff_t *off)
- 20 {
- 21 char buf[12];
- 22
- 23 copy_from_user(buf,usr,len);
- 24 printk("%s\n",buf);
- 25
- 26 }
- 27 ssize_t testread(struct file *file, char __user *usr, size_t len, loff_t *off)
- 28 {
- 29 char buf[20] = "hello,user!";
- 30 copy_to_user(usr,buf,len);
- 31
- 32
- 33 }
- 34 int testrelease(struct inode *inode, struct file *file)
- 35 {
- 36 printk("close\n");
- 37 return 0;
- 38
- 39 }
- 40
- 41 struct file_operations fops=
- 42 {
- 43 .owner=THIS_MODULE,
- 44 .open = testopen,
- 45 .write = testwrite,
- 46 .read = testread,
- 47 .release = testrelease,
- 48 };
- 49 static int __init test_init(void)
- 50 {
- 51 ret = register_chrdev(dev_no,"chrdev_test",&fops);
- 52 if(ret < 0)
- 53 {
- 54 printk("register error!\n");
- 55 }
- 56 if(dev_no==0)
- 57 {
- 58 dev_no = ret;
- 59 }
- 60
- 61 return 0;
- 62 }
- 63
- 64 static int __exit test_exit(void)
- 65 {
- 66 unregister_chrdev(dev_no,"chrdev_test");
- 67
- 68 return 0;
- 69 }
- 70
- 71 module_init(test_init);
- 72 module_exit(test_exit);
- 73
- 74
- 75 MODULE_AUTHOR("FENG");
- 76 MODULE_DESCRIPTION("the first module of char drivers");
- 77 MODULE_LICENSE("GPL");
- 78 MODULE_VERSION("V1.0");
复制代码
|
|