驅動代碼:
#include <linux/kernel.h>#include <linux/module.h>#include <linux/cdev.h>#include <linux/fs.h>#include <linux/device.h>#include <linux/uaccess.h>#include <linux/string.h>struct message_to_app_dev{struct cdev* pcdev;dev_t devno;struct class *message_class;};static int message_open(struct inode *node, struct file *filp){printk("message_open()++\n");printk("message_open()--\n");return 0;}static int message_release(struct inode *node, struct file *filp){printk("message_release()++\n");printk("message_release()--\n");return 0;}static ssize_t message_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr){char temp_buffer [20];int print_size = 0;printk("message_wirte()++\n");if(len > 20)print_size = 20;elseprint_size = len;printk("print_size = %d; len = %d\n", print_size, len);if(copy_from_user(temp_buffer, buf, print_size))return -EFAULT;printk("writing data:%s", temp_buffer);printk("message_wirte()--\n");return print_size;}static ssize_t message_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr){ char *temp_buffer = "Hello message_read !\n"; int print_size = 0; printk("message_read()++\n");if(len > strnlen(temp_buffer,20))print_size = strnlen(temp_buffer,20);elseprint_size = len;printk("print_size = %d; len = %d\n", print_size, len);if(copy_to_user(buf, temp_buffer, print_size))return -EFAULT;printk("%s", temp_buffer);printk("message_read()--\n");return print_size;}struct file_operations meassage_operatons ={.owner = THIS_MODULE,.open = message_open,.release = message_release,.write = message_write,.read = message_read,};struct message_to_app_dev message_dev;static int __init message_to_app_init(void){struct message_to_app_dev * dev;printk("message_to_app_init(void)++\n");dev = &message_dev;alloc_chrdev_region(&dev->devno, 0, 1, "message_to_app");dev->pcdev = cdev_alloc();cdev_init(dev->pcdev, &meassage_operatons);cdev_add(dev->pcdev, dev->devno, 1);dev->message_class = class_create(THIS_MODULE, "message_class");if(IS_ERR(dev->message_class)) { printk("Err: failed in creating class./n"); return -1; }device_create(dev->message_class, NULL, dev->devno, NULL, "message");printk("message_to_app_init(void)--\n");return 0;}static void __exit message_to_app_exit(void){struct message_to_app_dev *dev = &message_dev;printk("message_to_app_exit(void)++\n");device_destroy(dev->message_class, dev->devno);class_destroy(dev->message_class); cdev_del(dev->pcdev);unregister_chrdev_region(dev->devno, 1); printk("message_to_app_exit(void)--\n");}module_init(message_to_app_init);module_exit(message_to_app_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("Driver Monkey");MODULE_DESCRIPTION("Test message to App");
測試程式:
#include<stdio.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<sys/select.h>#include<unistd.h>#include<signal.h>#include<string.h>unsigned int flag;void sig_handler(intsig){ printf("<app>%s\n",__FUNCTION__); flag=1;}int main(void){char r_buf[20];char *w_buf = "hello write!\n";int r_count = 0;int fd;int f_flags;flag=0;fd=open("/dev/message",O_RDWR);if(fd<0){perror("open");return-1;}r_count=read(fd, r_buf, 20);printf("r_count = %d\n", r_count);printf("app read:\n%s", r_buf);write(fd, w_buf, strlen(w_buf));close(fd);return 0;}