07 Linux字符驱动---read/write/ioctl
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了07 Linux字符驱动---read/write/ioctl相关的知识,希望对你有一定的参考价值。
1. mycdev.c
1 #include <linux/init.h> 2 #include <linux/module.h> 3 #include <linux/cdev.h> 4 #include <linux/fs.h> 5 #include <linux/device.h> 6 #include <linux/err.h> 7 #include <linux/uaccess.h> 8 #include <asm-generic/ioctl.h> 9 #include "cmd.h" 10 11 #define MAX 1024 12 13 struct mycdev 14 { 15 int len; 16 char kbuf[MAX]; 17 struct cdev cdev; 18 }; 19 20 struct mycdev mycdev; 21 struct class *cls; 22 23 int mycdev_open(struct inode *inode, struct file *file) 24 { 25 printk("Call mycdev_open()\n"); 26 return 0; 27 } 28 29 ssize_t mycdev_read(struct file *file,char __user *ubuf,size_t size,loff_t *offset) 30 { 31 int len; 32 33 printk("Call mycdev_read()\n"); 34 35 if(size >= mycdev.len) 36 len = mycdev.len; 37 else 38 len = size; 39 40 if(copy_to_user(ubuf,mycdev.kbuf,len) != 0) 41 { 42 printk("copy_to_user() error\n"); 43 return -EFAULT; 44 } 45 46 return len; 47 } 48 49 ssize_t mycdev_write(struct file *file,const char __user *ubuf,size_t size,loff_t *offset) 50 { 51 printk("call mycdev_write()\n"); 52 53 if(size >= MAX) 54 return -1; 55 56 if(copy_from_user(mycdev.kbuf,ubuf,size) != 0) 57 { 58 printk("Fail to copy_from_user()"); 59 return -EFAULT; 60 } 61 62 mycdev.len = size; 63 mycdev.kbuf[size] = ‘\0‘; 64 printk("write : %s\n",mycdev.kbuf); 65 66 return size; 67 } 68 69 long mycdev_unlocked_ioctl(struct file *file,unsigned int cmd, unsigned long arg) 70 { 71 int ret = 0; 72 73 switch(cmd) 74 { 75 case CMD_CDEV_CLEAN: 76 memset(mycdev.kbuf,0,MAX); 77 printk("CMD_CLEN\n"); 78 break; 79 80 case CMD_SET_CDEV_LEN: 81 mycdev.len = arg; 82 printk("CMD_SET\n"); 83 break; 84 85 case CMD_GET_CDEV_LEN: 86 put_user(mycdev.len,(unsigned long *)arg); 87 printk("CMD_GET\n"); 88 break; 89 90 default: 91 printk("INvalid\n"); 92 ret = -EINVAL; 93 break; 94 } 95 96 return ret; 97 } 98 99 struct file_operations fops = { 100 .owner = THIS_MODULE, 101 .open = mycdev_open, 102 .read = mycdev_read, 103 .write = mycdev_write, 104 .unlocked_ioctl = mycdev_unlocked_ioctl, 105 }; 106 107 int mycdev_init(void) 108 { 109 int ret = 0; 110 dev_t dev; 111 struct device *device; 112 113 ret = alloc_chrdev_region(&dev, 0, 1, "mycdev"); 114 if (ret != 0) 115 { 116 printk("alloc_chrdev_region() error\n"); 117 goto err_alloc_chrdev_region; 118 } 119 120 cdev_init(&(mycdev.cdev), &fops); 121 122 ret = cdev_add(&(mycdev.cdev), dev, 1); 123 if (ret != 0) 124 { 125 printk("cdev_add() error\n"); 126 goto err_cdev_add; 127 } 128 129 cls = class_create(THIS_MODULE, "mycdev"); 130 if (IS_ERR(cls)) 131 { 132 ret = PTR_ERR(cls); 133 printk("class_create() error\n"); 134 goto err_class_create; 135 } 136 137 device = device_create(cls, NULL, dev, NULL, "mycdev"); 138 if (IS_ERR(device)) 139 { 140 ret = PTR_ERR(device); 141 printk("device_create() error\n"); 142 goto err_device_create; 143 } 144 145 printk("mycdev_init()\n"); 146 return 0; 147 148 err_device_create: 149 class_destroy(cls); 150 151 err_class_create: 152 cdev_del(&(mycdev.cdev)); 153 154 err_cdev_add: 155 unregister_chrdev_region(dev, 1); 156 157 err_alloc_chrdev_region: 158 return ret; 159 } 160 161 void mycdev_exit(void) 162 { 163 dev_t dev = mycdev.cdev.dev; 164 165 device_destroy(cls, dev); 166 class_destroy(cls); 167 cdev_del(&(mycdev.cdev)); 168 cdev_del(&(mycdev.cdev)); 169 unregister_chrdev_region(dev, 1); 170 171 printk("mycdev_exit()\n"); 172 return; 173 } 174 175 module_init(mycdev_init); 176 module_exit(mycdev_exit); 177 178 MODULE_LICENSE("GPL"); 179 MODULE_AUTHOR("GNB");
2. cmd.h
1 #ifndef _CMD_H_ 2 #define _CMD_H_ 3 4 #define CMD_TYPE ‘k‘ 5 #define CMD_CDEV_CLEAN _IO(CMD_TYPE,0x10) 6 #define CMD_SET_CDEV_LEN _IOW(CMD_TYPE,0x11,int) 7 #define CMD_GET_CDEV_LEN _IOR(CMD_TYPE,0x12,int) 8 9 #endif
3. test.c
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <sys/types.h> 4 #include <sys/stat.h> 5 #include <fcntl.h> 6 #include <sys/ioctl.h> 7 #include "cmd.h" 8 9 int main(int argc, const char *argv[]) 10 { 11 int n; 12 int fd; 13 int pid; 14 int len; 15 char buf[1024]; 16 char *string = "hello word\n"; 17 18 fd = open("/dev/mycdev_device",O_RDWR); 19 printf("fd = %d\n",fd); 20 21 n = write(fd,string,strlen(string)); 22 printf("n = %d\n",n); 23 24 n = read(fd,buf,sizeof(buf)); 25 printf("n = %d\n",n); 26 27 ioctl(fd,CMD_CDEV_CLEAN); 28 ioctl(fd,CMD_SET_CDEV_LEN,100); 29 ioctl(fd,CMD_GET_CDEV_LEN,&len); 30 printf("len = %d\n",len); 31 32 return 0; 33 }
以上是关于07 Linux字符驱动---read/write/ioctl的主要内容,如果未能解决你的问题,请参考以下文章