宋宝华 《Linux设备驱动开发详解》示例代码之基本字符设备驱动
来源:互联网 发布:三维重建软件有哪些 编辑:程序博客网 时间:2024/06/12 18:52
最简单的字符设备驱动代码
scull.c
#include <linux/fs.h>#include <linux/kernel.h>#include <linux/cdev.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/gfp.h>#include <asm/uaccess.h>#defineSCULL_MAJOR252#define SCULL_NAME"scull"#define MAX_DATA0x1000staticint scull_major = SCULL_MAJOR;struct scull_dev {struct cdev cdev;char data[MAX_DATA];struct semaphore sem;};MODULE_LICENSE("Dual BSD/GPL");MODULE_AUTHOR("BG2BKK");structscull_dev *scull_devp;intscull_open(struct inode *inode, struct file *filp){struct scull_dev *dev = container_of(inode->i_cdev, struct scull_dev, cdev);filp->private_data = dev;printk(KERN_ALERT "open the scull device\n");return 0;}intscull_release(struct inode *inode, struct file *filp){printk(KERN_ALERT "close the scull device\n");return 0;}ssize_tscull_read(struct file *filp, char __user *buf, size_t count, loff_t *f_ops){struct scull_dev *dev = filp->private_data;unsigned longp = *f_ops;unsigned intcnt = count;int ret = 0;if(down_interruptible(&dev->sem))return -ERESTARTSYS;if(copy_to_user(buf, dev->data,cnt)){ret = -EFAULT;} else {*f_ops += cnt;ret = cnt;printk(KERN_ALERT "read %u bytes from %lu\n",cnt, p);}up(&dev->sem);printk(KERN_ALERT "read %d bytes\n",count);return ret;}ssize_t scull_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_ops){struct scull_dev *dev = filp->private_data;unsigned long p = *f_ops;unsigned int cnt = count;int ret = 0;if(down_interruptible(&dev->sem))return -ERESTARTSYS;if(copy_from_user(dev->data,buf, cnt))ret = -EFAULT;else {*f_ops += cnt;ret = cnt;printk(KERN_ALERT "written %u bytes from %lu\n",cnt, p);}up(&dev->sem);printk(KERN_ALERT "write %d bytes\n",count);return ret;}structfile_operations scull_fops = {.owner=THIS_MODULE,.open=scull_open,.release=scull_release,.write=scull_write,.read=scull_read,};staticvoidscull_setup_cdev(struct scull_dev *dev, int index){int err, devno = MKDEV(scull_major, index);cdev_init(&dev->cdev, &scull_fops);dev->cdev.owner = THIS_MODULE;err = cdev_add(&dev->cdev, devno, 1);if(err)printk(KERN_NOTICE "ERROR %d adding scull_dev %d", err, index);}intscull_init(void){int result;dev_tdevno = MKDEV(scull_major,0);if(scull_major)result = register_chrdev_region(devno, 1, "scull");else {result = alloc_chrdev_region(&devno, 0, 1, "scull");scull_major = MAJOR(devno);}if(result < 0)return result;scull_devp = kmalloc(sizeof(struct scull_dev), GFP_KERNEL);if(!scull_devp){result = -ENOMEM;goto fail_malloc;}memset(scull_devp, 0 , sizeof(struct scull_dev));scull_setup_cdev(scull_devp, 0);init_MUTEX(&scull_devp->sem);printk(KERN_ALERT "init scull device\n");return 0;fail_malloc:unregister_chrdev_region(devno, 1);return result;}voidscull_cleanup(void){cdev_del(&scull_devp->cdev);kfree(scull_devp);unregister_chrdev_region(MKDEV(scull_major, 0), 1);printk(KERN_ALERT "clean scull device\n");}module_init(scull_init);module_exit(scull_cleanup);测试代码
/************************************************************************* *fileName: test.c *description: test the myscull.c *author: Hzc *create time: 2007-04-20 *modify info: -*************************************************************************/#include <stdio.h>#include <fcntl.h>#include <sys/ioctl.h>#include <sys/types.h>/* device path */char path[] = "/dev/scull";char buf[10];char rbuf[10];int i;int t = 1;intmain (){ int f = open (path, O_RDWR); for (i = 0; i < 10; i++) { buf[i] = i; printf("buf[%d] = %d\n",i,buf[i]); }printf("write %d bytes\n",write (f, buf, 10));// close (f);////// f = open (path, O_RDONLY);// if (f == -1)// {// printf ("device open error 2!\n");// return 1;// } printf ("Read the string from device...\n");printf("read %d bytes\n",read (f, rbuf, 10)); for (i = 0; i < 10; i++) { printf ("%d\n", rbuf[i]); } close (f);}Makefile
#KERNEL_DIR := /home/huang/linux-2.6.18/KERNEL_DIR := /lib/modules/$(shell uname -r)/buildPWD:= $(shell pwd)obj-m := scull.odefault:$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modulestest: test.cgcc $< -o $@.o -gclean:rm -rf *.o *.ko *~ *.order *.symvers *.markers *.mod.c
测试脚本
1 load_scull.sh
#!/bin/sh/sbin/insmod scull.komknod /dev/scull c 252 0
2 unload_scull.sh
#!/bin/sh/sbin/rmmod scull.korm /dev/scull -f
3 test.sh
#!/bin/shmake cleanmake make testsudo ./unload_scullsudo ./load_scullsudo ./test.o
- 宋宝华 《Linux设备驱动开发详解》示例代码之基本字符设备驱动
- 宋宝华 《Linux设备驱动开发详解》示例代码之fifo字符设备驱动
- 宋宝华 《Linux设备驱动开发详解》之基本字符设备驱动misc版本
- 宋宝华 《Linux设备驱动开发详解》示例代码之second设备
- Linux设备驱动开发详解--笔记6--字符设备驱动
- linux字符设备驱动示例
- Linux设备驱动之《字符设备驱动》
- Linux设备驱动之字符设备驱动
- Linux设备驱动之字符设备驱动
- Linux设备驱动之字符设备驱动
- Linux设备驱动之字符设备驱动
- Linux设备驱动之字符设备驱动
- linux设备驱动之字符设备驱动
- Linux设备驱动开发详解总结(一)之字符设备驱动结构
- Linux驱动开发之字符设备
- linux驱动开发之字符设备框架
- linux驱动开发之字符设备框架
- linux中秒字符设备驱动(宋宝华设备驱动开发详解第10章)
- ThinkPHP分页的实现
- Android Studio使用教程(一)
- Java程序优化的一些最佳实践
- 排它平方数
- linux 3.4.10 内核内存管理源代码分析2:伙伴系统
- 宋宝华 《Linux设备驱动开发详解》示例代码之基本字符设备驱动
- getopt_long() 参数详解
- Java中的equals学习小结
- 在WYSIWYG模块中为Drupal 7配置CKEditor 4
- 如何将sql 执行的错误消息 记录到本地文件中
- Math.Round() -- c# 与 java的区别
- php初学4-变量范围
- Linux驱动之与硬件通信
- 黑马程序员JAVA基础-封装