Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7687752
  • 博文数量: 961
  • 博客积分: 15795
  • 博客等级: 上将
  • 技术积分: 16612
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-07 14:23
文章分类

全部博文(961)

文章存档

2016年(1)

2015年(61)

2014年(41)

2013年(51)

2012年(235)

2011年(391)

2010年(181)

分类: 嵌入式

2011-01-19 19:43:33

  1. #ifndef _MEMDEV_H_
  2. #define _MEMDEV_H_

  3. #ifndef MEMDEV_MAJOR
  4. #define MEMDEV_MAJOR 251 /*预设的mem的主设备号*/
  5. #endif

  6. #ifndef MEMDEV_NR_DEVS
  7. #define MEMDEV_NR_DEVS 2 /*设备数*/
  8. #endif

  9. #ifndef MEMDEV_SIZE
  10. #define MEMDEV_SIZE 4096
  11. #endif

  12. /*mem设备描述结构体*/
  13. struct mem_dev
  14. {
  15.   char *data;
  16.   unsigned long size;
  17. };

  18. #endif /* _MEMDEV_H_ */
  1. #include <linux/module.h>
  2. #include <linux/types.h>
  3. #include <linux/fs.h>
  4. #include <linux/errno.h>
  5. #include <linux/mm.h>
  6. #include <linux/sched.h>
  7. #include <linux/init.h>
  8. #include <linux/cdev.h>
  9. #include <asm/io.h>
  10. #include <asm/system.h>
  11. #include <asm/uaccess.h>
  12. #include <linux/device.h> /* device_create()*/

  13. #include "memdev.h"

  14. static int mem_major = MEMDEV_MAJOR;

  15. module_param(mem_major, int, S_IRUGO);

  16. struct mem_dev *mem_devp; /*设备结构体指针*/

  17. struct cdev cdev;

  18. /*文件打开函数*/
  19. int mem_open(struct inode *inode, struct file *filp)
  20. {
  21.     struct mem_dev *dev;
  22.     
  23.     /*获取次设备号*/
  24.     int num = MINOR(inode->i_rdev);

  25.     if (num >= MEMDEV_NR_DEVS)
  26.             return -ENODEV;
  27.     dev = &mem_devp[num];
  28.     
  29.     /*将设备描述结构指针赋值给文件私有数据指针*/
  30.     filp->private_data = dev;
  31.     
  32.     return 0;
  33. }

  34. /*文件释放函数*/
  35. int mem_release(struct inode *inode, struct file *filp)
  36. {
  37.   return 0;
  38. }

  39. /*读函数*/
  40. static ssize_t mem_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
  41. {
  42.   unsigned long p = *ppos;
  43.   unsigned int count = size;
  44.   int ret = 0;
  45.   struct mem_dev *dev = filp->private_data; /*获得设备结构体指针*/

  46.   /*判断读位置是否有效*/
  47.   if (p >= MEMDEV_SIZE)
  48.     return 0;
  49.   if (count > MEMDEV_SIZE - p)
  50.     count = MEMDEV_SIZE - p;

  51.   /*读数据到用户空间*/
  52.   if (copy_to_user(buf, (void*)(dev->data + p), count))
  53.   {
  54.     ret = - EFAULT;
  55.   }
  56.   else
  57.   {
  58.     *ppos += count;
  59.     ret = count;
  60.     
  61.     printk(KERN_INFO "read %d bytes(s) from %d\n", count, p);
  62.   }

  63.   return ret;
  64. }

  65. /*写函数*/
  66. static ssize_t mem_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)
  67. {
  68.   unsigned long p = *ppos;
  69.   unsigned int count = size;
  70.   int ret = 0;
  71.   struct mem_dev *dev = filp->private_data; /*获得设备结构体指针*/
  72.   
  73.   /*分析和获取有效的写长度*/
  74.   if (p >= MEMDEV_SIZE)
  75.     return 0;
  76.   if (count > MEMDEV_SIZE - p)
  77.     count = MEMDEV_SIZE - p;
  78.     
  79.   /*从用户空间写入数据*/
  80.   if (copy_from_user(dev->data + p, buf, count))
  81.     ret = - EFAULT;
  82.   else
  83.   {
  84.     *ppos += count;
  85.     ret = count;
  86.     
  87.     printk(KERN_INFO "written %d bytes(s) from %d\n", count, p);
  88.   }

  89.   return ret;
  90. }

  91. /* seek文件定位函数 */
  92. static loff_t mem_llseek(struct file *filp, loff_t offset, int whence)
  93. {
  94.     loff_t newpos;

  95.     switch(whence) {
  96.       case 0: /* SEEK_SET */
  97.         newpos = offset;
  98.         break;

  99.       case 1: /* SEEK_CUR */
  100.         newpos = filp->f_pos + offset;
  101.         break;

  102.       case 2: /* SEEK_END */
  103.         newpos = MEMDEV_SIZE -1 + offset;
  104.         break;

  105.       default: /* can't happen */
  106.         return -EINVAL;
  107.     }
  108.     if ((newpos<0) || (newpos>MEMDEV_SIZE))
  109.         return -EINVAL;
  110.         
  111.     filp->f_pos = newpos;
  112.     return newpos;

  113. }

  114. /*文件操作结构体*/
  115. static const struct file_operations mem_fops =
  116. {
  117.   .owner = THIS_MODULE,
  118.   .llseek = mem_llseek,
  119.   .read = mem_read,
  120.   .write = mem_write,
  121.   .open = mem_open,
  122.   .release = mem_release,
  123. };

  124. /*设备驱动模块加载函数*/
  125. static int memdev_init(void)
  126. {
  127.     struct class *myclass;
  128.   int result;
  129.   int i;

  130.   dev_t devno = MKDEV(mem_major, 0);

  131.   /* 静态申请设备号*/
  132.   if (mem_major)
  133.     result = register_chrdev_region(devno, 2, "memdev");
  134.   else /* 动态分配设备号 */
  135.   {
  136.     result = alloc_chrdev_region(&devno, 0, 2, "memdev");
  137.     mem_major = MAJOR(devno);
  138.   }
  139.   
  140.   if (result < 0)
  141.     return result;

  142.   /*初始化cdev结构*/
  143.   cdev_init(&cdev, &mem_fops);
  144.   cdev.owner = THIS_MODULE;
  145.   cdev.ops = &mem_fops;
  146.   
  147.   /* 注册字符设备 */
  148.   cdev_add(&cdev, MKDEV(mem_major, 0), MEMDEV_NR_DEVS);
  149.    
  150.   /* 为设备描述结构分配内存 */
  151.   mem_devp = kmalloc(MEMDEV_NR_DEVS * sizeof(struct mem_dev), GFP_KERNEL);
  152.   if (!mem_devp) /* 申请失败 */
  153.   {
  154.     result = - ENOMEM;
  155.     goto fail_malloc;
  156.   }
  157.   memset(mem_devp, 0, sizeof(struct mem_dev));
  158.   
  159.   /*为设备分配内存*/
  160.   for (i=0; i < MEMDEV_NR_DEVS; i++)
  161.   {
  162.         mem_devp[i].size = MEMDEV_SIZE;
  163.         mem_devp[i].data = kmalloc(MEMDEV_SIZE, GFP_KERNEL);
  164.         memset(mem_devp[i].data, 0, MEMDEV_SIZE);
  165.   }
  166.   /*自动创建设备文件*/
  167.     myclass = class_create(THIS_MODULE,"test_char"); /*在sys下创建类目录/sys/class/test_char*/
  168.     device_create(myclass, NULL, MKDEV(mem_major,0), NULL, "memdev0");
  169.   return 0;

  170.   fail_malloc:
  171.   unregister_chrdev_region(devno, 1);
  172.   
  173.   return result;
  174. }

  175. /*模块卸载函数*/
  176. static void memdev_exit(void)
  177. {
  178.   cdev_del(&cdev); /*注销设备*/
  179.   kfree(mem_devp); /*释放设备结构体内存*/
  180.   unregister_chrdev_region(MKDEV(mem_major, 0), 2); /*释放设备号*/
  181. }

  182. MODULE_AUTHOR("David Xie");
  183. MODULE_LICENSE("GPL");

  184. module_init(memdev_init);
  185. module_exit(memdev_exit);
  1. #include <stdio.h>

  2. int main()
  3. {
  4.     FILE *fp0 = NULL;
  5.     char Buf[4096];
  6.     
  7.     /*初始化Buf*/
  8.     strcpy(Buf,"Mem is char dev!");
  9.     printf("BUF: %s\n",Buf);
  10.     
  11.     /*打开设备文件*/
  12.     fp0 = fopen("/dev/memdev0","r+");
  13.     if (fp0 == NULL)
  14.     {
  15.         printf("Open Memdev0 Error!\n");
  16.         return -1;
  17.     }
  18.     
  19.     /*写入设备*/
  20.     fwrite(Buf, sizeof(Buf), 1, fp0);
  21.     
  22.     /*重新定位文件位置(思考没有该指令,会有何后果)*/
  23.     fseek(fp0,0,SEEK_SET);
  24.     
  25.     /*清除Buf*/
  26.     strcpy(Buf,"Buf is NULL!");
  27.     printf("BUF: %s\n",Buf);
  28.     
  29.     
  30.     /*读出设备*/
  31.     fread(Buf, sizeof(Buf), 1, fp0);
  32.     
  33.     /*检测结果*/
  34.     printf("BUF: %s\n",Buf);
  35.     
  36.     return 0;    

  37. }
阅读(2594) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~