一个字符设备实例,以及自动建立设备节点

来源:互联网 发布:乐知英语怎么样 编辑:程序博客网 时间:2024/04/30 17:46

此文章改编自 yel617 在论坛的发言,此处声明,以示尊重。


#include <linux/module.h>

#include <linux/kernel.h>
#include <linux/init.h>

#include <linux/miscdevice.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
#include <linux/cdev.h>
#include <linux/kobject.h>

#include <linux/fs.h>
#include <linux/device.h>
#include <mach/io.h>
#include <mach/gpio.h>
#include <mach/board.h>
#include <mach/gpmc.h>
#include <mach/mux.h>
#include <asm/uaccess.h>

MODULE_LICENSE("Dual BSD/GPL");
struct cdev apple_cdev;
unsigned int apple_dev;
static char *data;
//static struct class *apple_class;

static ssize_t apple_read(struct file *file,char *buf,size_t count,loff_t *f_pos);
static ssize_t apple_write(struct file *file,const char *buffer,size_t count,loff_t *f_pos);

static int apple_open(struct inode *inode,struct file *file);
static int apple_release(struct inode *inode,struct file *file);

static int apple_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);

static struct file_operations apple_fops={
  .owner = THIS_MODULE,
  .open = apple_open,
  .release = apple_release,
  .read = apple_read,
  .write = apple_write,
  .ioctl = apple_ioctl,
};

static ssize_t apple_read(struct file *file,char *buf,size_t count,loff_t *f_pos)
{
    int len;
    if(count<0)
    {
        return -EINVAL;
    }
    len=strlen(data);
    if(len<count)      count=len;
    copy_to_user(buf,data,count+1);
    printk("read buf=%s\n",buf);
    printk("read data=%s\n",data);
    return count;
}

static ssize_t apple_write(struct file *file,const char *buffer,size_t count,loff_t *pos)
{   
    if(count<0)  return -EINVAL;
    kfree(data);
    data=(char *)kmalloc(sizeof(char)*(count+1),GFP_KERNEL);
    if(!data)        return -ENOMEM;
    copy_from_user(data,buffer,count+1);
    printk("write buffer=%s\n",buffer);
    printk("write data=%s\n",data);
    return count;
}

static int apple_open(struct inode *inode,struct file *file)
{
    printk("This is open(skull)\n");
    return 0;
}

static int apple_release(struct inode *inode,struct file *file)
{
    printk("This is released\n");
    return 0;
}

static int apple_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
    switch(cmd)
      {
          case 1: printk("There is 1 apple.\n"); break;
          case 2: printk("There is 2 apples\n"); break;
          case 3: printk("There is 3 apples\n"); break;
      }
  
}

static int __init apple_init(void)
{
   int ret;
   cdev_init(&apple_cdev,&apple_fops);
   apple_cdev.owner = THIS_MODULE;
   ret = alloc_chrdev_region(&apple_dev,0,1,"apple");
   if(ret < 0)
    {
       printk("apple register failure!\n");
       return -22;
    } 
   ret = cdev_add(&apple_cdev,apple_dev,1);
   if(ret < 0)
    {
       printk("apple_cdev register failure!\n");
       return -22;
    } 
   //apple_class=class_create(THIS_MODULE,"apple");
   //device_create(apple_class,NULL,apple_dev,NULL,"apple");
   return 0;
}

static void __exit apple_exit(void)
{
   unregister_chrdev_region(apple_dev,1);
   cdev_del(&apple_cdev);
   //device_destroy(apple_class,apple_dev);
   //class_destroy(apple_class);
}

module_init(apple_init);
module_exit(apple_exit);

应用:
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char *argv)
{
  int fd,num;
  char label[10];
  fd = open("/dev/apple",O_RDWR);
  if(fd != -1)
   {
      printf("Please enter the label attached to the Apple\n");
      scanf("%s",&label);
      write(fd,&label,10*sizeof(char));
      read(fd,&label,10*sizeof(char));
      printf("Please enter the number of apples\n");
      scanf("%d",&num);
      ioctl(fd,num);
      close(fd);
    }
   else
    {
       printf("Device open failure\n");
    } 

}

/dev下设备节点
要手动建立,也可以用这个自动建立
apple_class=class_create(THIS_MODULE,"apple");
device_create(apple_class,NULL,apple_dev,NULL,"apple");

此文章改编自 yel617 在论坛的发言,此处声明,以示尊重。

0 0