字符设备驱动程序实例
2.6内核设备驱动程序(2.6/call/dev/call_dev.c)
01 #include <linux/init.h> 02 #include <linux/module.h> 03 #include <linux/kernel.h> 04 #include <linux/fs.h> 05 #include <linux/errno.h> 06 #include <linux/types.h> 07 #include <linux/fcntl.h> 08 09 #define CALL_DEV_NAME "calldev" 10 #define CALL_DEV_MAJOR 240 11 12 int call_open (struct inode *inode, struct file *filp) 13 { 14 int num = MINOR (inode ->i_rdev); //利用MINOR宏,获取次设备号 15 16 printk ("call open -> minor : %d\n", num ); 17 18 return 0; 19 } 20 21 loff_t call_llseek (struct file *filp, loff_t off, int whence ) 22 { 23 printk ("call llseek -> off : %08X, whenec : %08X\n", off, whence ); 24 return 0x23; 25 } 26 27 ssize_t call_read (struct file *filp, char *buf, size_t count, loff_t *f_pos ) 28 { 29 printk ("call read -> buf : %08X, count : %08X\n", buf, count ); 30 return 0x33; 31 } 32 33 ssize_t call_write (struct file *filp, const char *buf, size_t count, loff_t *f_pos ) 34 { 35 printk ("call write -> buf : %08X, count : %08X\n", buf, count ); 36 return 0x43; 37 } 38 39 int call_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) 40 { 41 42 printk ("call ioctl -> cmd : %08X, arg : %08X\n", cmd, arg ); 43 return 0x53; 44 } 45 46 int call_release (struct inode *inode, struct file *filp) 47 { 48 printk ("call release \n" ); 49 return 0; 50 } 51 52 struct file_operations call_fops = 53 { 54 .owner = THIS_MODULE, 55 .llseek = call_llseek, 56 .read = call_read, 57 .write = call_write, 58 .ioctl = call_ioctl, 59 .open = call_open, 60 .release = call_release, 61 }; 62 63 int call_init (void) //call_init()函数利用register_chrdev()函数吧字符设备驱动程序注册到内核上。最后的变量值代入设备驱动程序的file_operations结构体 变量call_fops的地址。 64 { 65 int result; 66 67 printk ("call call_init \n"); 68 69 result = register_chrdev (CALL_DEV_MAJOR, CALL_DEV_ NAME, &call_fops); 70 if (result < 0) return result; 71 72 return 0; 73 } 74 75 void call_exit (void) 76 { 77 printk ("call call_exit \n"); 78 unregister_chrdev (CALL_DEV_MAJOR, CALL_DEV_NAME); 79 } 80 81 module_init (call_init); 82 module_exit (call_exit); 83 84 MODULE_LICENSE ("Dual BSD/GPL");
应用程序(2.6/call/app/call_app.c) 01 #include <stdio.h> 02 #include <sys/types.h> 03 #include <sys/stat.h> 04 #include <sys/ioctl.h> 05 #include <fcntl.h> 06 #include <unistd.h> 07 08 #define DEVICE_FILENAME "/dev/calldev" 09 10 int main ( ) 11 { 12 int dev; 13 char buff [128]; 14 int ret; 15 16 printf ( "1) device file open\n"); 17 18 dev = open ( DEVICE_FILENAME, O_RDWR |O_NDELAY ); // 打开/dev/calldev设备文件 19 if ( dev >= 0 ) 20 { 21 printf ( "2) seek function call\n"); 22 23 ret = lseek ( dev, 0x20, SEEK_SET); 24 printf ("ret = %08X\n", ret); 25 26 printf ( "3) read function call\n"); 27 28 ret = read ( dev, 0x30, 0x31 ); 29 printf ("ret = %08X\n", ret); 30 31 printf ( "4) write function call\n"); 32 ret = write ( dev, 0x40, 0x41 ); 33 printf ("ret = %08X\n", ret); 34 35 printf ( "5) ioctl function call\n"); 36 ret = ioctl ( dev, 0x51, 0x52 ); 37 printf ("ret = %08X\n", ret); 38 39 printf ( "6) device file close\n"); 40 ret = close ( dev ); 41 printf ("ret = %08X\n", ret); 42 } 43 44 return 0; 45 }
执行方法:
# mknod /dev/calldev c 240 32
# make
# insmod call_dev.ko
# gcc -o call_app call_app.c
# ./call_app
# dmesg
# rmmod call_dev