实现一个简单的Linux字符设备驱动
实现一个简单的Linux字符设备驱动
步骤1: 编写驱动程序
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/kernel.h>
- #include <linux/cdev.h>
- #include <linux/fs.h>
- #include <linux/kdev_t.h>
- #include <asm/uaccess.h>
- #include <linux/device.h>
- #define DEVICE_NAME "cdev_zhangwei"
- int number_of_devices = 1;
- struct cdev mydev;
- dev_t dev = 0;
- char data[128] = "/0"; // the data of my device
- struct class *myclass;
- static int mydev_open(struct inode *inode, struct file *file)
- {
- pr_info("mydev driver open!/n");
- return 0;
- }
- static int mydev_release(struct inode *inode, struct file *file)
- {
- pr_info("mydev driver released!/n");
- return 0;
- }
- ssize_t mydev_write(struct file *file, const char __user *buf, size_t count, loff_t *f_pos)
- {
- ssize_t ret = 0;
- pr_info("mydev_write!/n");
- pr_info("writing %d bytes/n", count);
- if (count > 127)
- return -ENOMEM;
- if (count < 0)
- return -EINVAL;
- if (copy_from_user(data, buf, count)) {
- ret = -EFAULT;
- }
- else {
- data[127] = ''/0'';
- pr_info("kernel received: %s/n", data);
- ret = count;
- }
- return ret;
- }
- static ssize_t mydev_read(struct file* filp, char* buf, size_t len,loff_t* off)
- {
- if( copy_to_user(buf,data,len) )
- {
- return -EFAULT;
- }
- return len;
- }
- struct file_operations mydev_fops = {
- .owner = THIS_MODULE,
- .open = mydev_open,
- .read = mydev_read,
- .write = mydev_write,
- .release = mydev_release
- };
- static int __init mydev_init(void)
- {
- int result, error;
- result = register_chrdev(0, DEVICE_NAME, &mydev_fops);
- pr_info("udev_cdev: get major number: %d/n", result);
- dev = MKDEV(result, 0);
- myclass = class_create(THIS_MODULE, "mydev_class");
- device_create(myclass, NULL, dev, NULL, DEVICE_NAME);
- return 0;
- }
- static void __exit mydev_exit(void)
- {
- cdev_del(&mydev);
- unregister_chrdev_region(dev, number_of_devices);
- device_destroy(myclass, dev);
- class_destroy(myclass);
- pr_info("Goodbye cdev!/n");
- }
- module_init(mydev_init);
- module_exit(mydev_exit);
- MODULE_LICENSE("GPL");
- MODULE_DESCRIPTION("Simple cdev udev driver test");
步骤2: 编译,形成ko文件,然后利用insmod命令插入内核。 (最好利用makefile进行编译,网上有文章专门有介绍)
步骤3:创建设备节点: mknod /dev/your_name c 主设备号 次设备号
次设备号这里填0, 主设备号可以利用 cat /proc/devices 查看
步骤4:编写用户程序(测试咱们的驱动是否可行), 如以下代码,这个嘛,简单的用gcc命令编译就好了
- #include <stdio.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <fcntl.h>
- int main (void)
- {
- int fd,len;
- pid_t pid;
- char buff[] = "This is from userspace zhangwei fight it!";
- char buff_read[100] ;
- fd = open ("/dev/cdev_zhangwei", O_RDWR);
- if (fd < 0) {
- perror("open failed");
- exit(0);
- }
- pid = fork();
- if(pid>0)
- {
- len = write (fd, buff, sizeof(buff));
- printf ("son Write returns %d/n",len );
- }
- else // parent
- {
- //waitpid(pid);
- printf ("read returns %d/n", read(fd,buff_read,len) );
- printf("buff_read = %s/n",buff_read);
- }
- close (fd);
- return 0;
- }
到了这里,对字符设备驱动就有一个直观的印象了。
评论暂时关闭