Linux character device-kernel-state data and user-state data transfer, linux
Linux character device-mutual transmission of kernel-mode data and user-mode data
_ IO, _ IOR, _ IOW, and _ IORW
For the ioctl number of devices supported by the system, you can find it in the header file under/usr/include. For your own devices, if you need to use the ioctl interface, define your own ioctl number. In the past 2.4, there was a problem that everyone defined their own ioctl number randomly, which caused a high possibility of repetition. One disadvantage is that it is difficult to manage, and the other is that it is easy to cause errors. For example, if you want to open a serial port device, the network port is opened through open, if an ioctl Number of the serial port is the closing operation of the network port, this will cause an error. In section 2.6, we recommend that you use _ IO, _ IOR, _ IOW, and _ IORW to define your own ioctl number. These macros take into account the length of the third parameter, the magic number of the device, as well as the Operation direction, can avoid 2.4 Problems
: _ IO (type, nr) (for commands without parameters ),
_ IOR (type, nre, datatype) (for reading data from the driver ),
_ IOW (type, nr, datatype) (for writing data ),
_ IOWR (type, nr, datatype) (For bidirectional transmission ).
The type and number members are passed as parameters,
And the size member is obtained by applying the sizeof to the datatype parameter.
Int ioctl (int fd, int request,.../* void * arg */)
The third parameter is always a pointer, but the pointer type depends on the request parameter. We can divide network-related requests into 6 categories:
Set interface operations
File Operations
Interface operation
ARP high-speed cache operations
Route table operations
Stream System
First, write an example of intercommunication between kernel-state data and user-state data and an APP
Manual installation steps:
Insmod my_char_dev.ko
No more device node installation required
Then test the app.
./My_char_dev_app 1
1 # include <linux/module. h> 2 # include <linux/init. h> 3 # include <linux/io. h> 4 # include <linux/fs. h> 5 # include <asm/device. h> // The following three headers are the 6 # include <linux/device. h> 7 # include <linux/cdev. h> 8 # include "my_cdev.h" 9 # include <asm/uaccess. h> 10 11 12 struct cdev; 13 dev_t devno; // here is the 14 struct class * cdev_class; 15 int param required for dynamically allocating device numbers and creating device nodes; 16 int my_cdev_open (struct inode * n Ode, struct file * filp) 17 {18 printk ("my_cdev_open sucess! \ N "); 19 return 0; 20} 21 22 long my_cdev_ioctl (struct file * filp, unsigned int cmd, unsigned long arg) 23 {24 int rc =-1; 25 26 switch (cmd) 27 {28 case LED_ON: 29 rc = copy_from_user (& param, (int _ user *) arg, 4); 30 if (0! = Rc) 31 {32 printk ("copy_from_user failed. \ n "); 33 break; 34} 35 printk (" Param is % d. \ n ", param); 36 printk (" CMD test: LED_ON is set! \ N "); 37 return 0; 38 case LED_OFF: 39 printk (" CMD test: LED_OFF is set! \ N "); 40 param = 1000; 41 rc = copy_to_user (int _ user *) arg, & param, 4); 42 if (0! = Rc) 43 {44 printk ("copy_to_user failed. \ n "); 45} 46 param = 0; 47 return 0; 48 default: 49 return-EINVAL; 50} 51} 52 53 struct file_operations my_cdev_fops = 54 {55. open = my_cdev_open, 56. unlocked_ioctl = my_cdev_ioctl, 57 58}; 59 60 static int my_cdev_init (void) 61 {62 int ret; 63/** dynamically allocate device numbers */64 ret = alloc_chrdev_region (& devno, 0, 1, "my_chardev"); 65 if (ret) 66 {67 printk ("alloc_chrd Ev_region fail! \ N "); 68 unregister_chrdev_region (devno, 1); 69 return ret; 70} 71 else 72 {73 printk (" alloc_chrdev_region sucess! \ N "); 74} 75/** description structure initialization */76 cdev_init (& cdev, & my_cdev_fops ); 77/** description structure registration */78 ret = cdev_add (& cdev, devno, 1); 79 if (ret) 80 {81 printk ("cdev add fail. \ n "); 82 unregister_chrdev_region (devno, 1); 83 return ret; 84} 85 else 86 {87 printk (" cdev add sucess! \ N "); 88} 89 90 cdev_class = class_create (THIS_MODULE," my_chardev "); 91 if (IS_ERR (cdev_class) 92 {93 printk (" Create class fail! \ N "); 94 unregister_chrdev_region (devno, 1); 95 return-1; 96} 97 else 98 {99 printk (" Create class sucess! \ N "); 100} 101 102 device_create (cdev_class, NULL, devno, 0," my_chardev "); 103 104 105 return 0; 106} static void my_cdev_exit (void) 107 {108 device_destroy (cdev_class, devno); 109 class_destroy (cdev_class); 110 cdev_del (& cdev); 111 degrees (devno, 1); 112 printk ("my_cdev_exit sucess! \ N "); 113} 114 module_init (my_cdev_init); 115 module_exit (my_cdev_exit); 116 MODULE_LICENSE (" GPL "); 117 MODULE_AUTHOR (" YEFEI "); 118 MODULE_DESCRIPTION ("YEFEI Driver ");
1 #ifndef __MY_CDEV_H__2 #define __MY_CDEV_H__3 4 #define LED_MAGIC 'L'5 #define LED_ON _IOW(LED_MAGIC,0,int)6 #define LED_OFF _IOR(LED_MAGIC,1,int *)7 8 #endif
1 #include <sys/stat.h> 2 #include <sys/types.h> 3 #include <sys/ioctl.h> 4 #include <fcntl.h> 5 #include <stdio.h> 6 #include "my_cdev.h" 7 8 int main(int argc,char *argv[]) 9 {10 int fd;11 int cmd;12 long ret = 0;13 unsigned long param = 0;14 if(argc < 2)15 {16 printf("Please enter secend param!\n");17 return 0;18 }19 cmd = atoi(argv[1]);20 fd = open("/dev/my_chardev",O_RDWR);21 if(fd < 0)22 {23 printf("Open dev/my_chardev fail!\n");24 close(fd);25 return 0;26 }27 switch(cmd)28 {29 case 1:30 param = 500;31 ret = ioctl(fd,LED_ON,¶m);32 break;33 case 2:34 ret = ioctl(fd,LED_OFF,¶m);35 printf("ret is %d. read data is %d.\n",ret,param);36 break;37 default:38 break;39 }40 close(fd);41 return 0;42 }
1 obj-m := my_char_dev.o2 KDIR := /home/win/dn377org/trunk/bcm7252/linux/3 all:4 make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm5 clean:6 rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.bak *.order