Chinaunix首页 | 论坛 | 博客
  • 博客访问: 403520
  • 博文数量: 77
  • 博客积分: 3149
  • 博客等级: 中校
  • 技术积分: 828
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-25 11:48
文章存档

2012年(5)

2011年(2)

2010年(11)

2009年(44)

2008年(15)

我的朋友

分类: LINUX

2008-12-04 11:03:22

笔者注:以下代码经简单修改,均调试通过

Kernel 2.6  demo 驱动程序

/**************************************************************

       demo.c

       linux driver example for UP-netarm3000 & UP-netarm2410

       It can be compiled for x86 PC

       author: zou jian-guo

       date:   2004-8-20

 

***************************************************************/

 

#include

#include

 

#include

#include    /* printk() */

#include    /* kmalloc() */

#include        /* everything... */

#include     /* error codes */

#include     /* size_t */

#include

#include     /* O_ACCMODE */

#include     /* COPY_TO_USER */

#include      /* cli(), *_flags */

 

#include

#define CDRIVER_NAME     "demo"

int CDRIVER_MAJOR=0;

int CDRIVER_MINOR=0;

static int MAX_BUF_LEN=1024;

static char drv_buf[1024];

static int WRI_LENGTH=0;

int dev_count=1;

 

dev_t demo_dev;

struct cdev *demo_cdev;

/*************************************************************************************/

static void do_write(void)

{

       int i;

       int len = WRI_LENGTH;

       char tmp;

       for(i = 0; i < (len>>1); i++,len--){

              tmp = drv_buf[len-1];

              drv_buf[len-1] = drv_buf[i];

              drv_buf[i] = tmp;

       }

}

/*************************************************************************************/

static ssize_t  demo_write(struct file *filp,const char *buffer, size_t count)

{

       if(count > MAX_BUF_LEN)count = MAX_BUF_LEN;

       copy_from_user(drv_buf , buffer, count);

       WRI_LENGTH = count;

       printk(KERN_INFO"user write data to driver\n");

       do_write();    

       return count;

}

/*************************************************************************************/

static ssize_t  demo_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)

{

       if(count > MAX_BUF_LEN)

              count=MAX_BUF_LEN;

       copy_to_user(buffer, drv_buf,count);

       printk("user read data from driver\n");

        return count;

}

/*************************************************************************************/

static int demo_ioctl(struct inode *inode, struct file *file,

                 unsigned int cmd, unsigned long arg)

{

       switch(cmd){

              case 1:printk("runing command 1 \n");break;

              case 2:printk("runing command 2 \n");break;

              default:

                     printk("error cmd number\n");break;

       }

       return 0;

}

/*************************************************************************************/

static int demo_open(struct inode *inode, struct file *file)

{

       try_module_get(THIS_MODULE);

       //MOD_INC_USE_COUNT;

       sprintf(drv_buf,"device open sucess!\n");

       printk("device open sucess!\n");

       return 0;

}

/*************************************************************************************/

static int  demo_release(struct inode *inode, struct file *filp)

{

       //MOD_DEC_USE_COUNT;

       module_put(THIS_MODULE);

       printk("device release\n");

       return 0;

}

 

/*************************************************************************************/

static struct file_operations demo_fops = {

       .owner =THIS_MODULE,

       .write =demo_write,     

       .read  =demo_read,     

       .ioctl =demo_ioctl,

       .open  =demo_open,

       .release=demo_release,

};

/*************************************************************************************/

 

/*************************************************************************************/

static int __init demo_init(void)

{

   int result;

   struct class *demo_class;

    if(CDRIVER_MAJOR){

       demo_dev=MKDEV(CDRIVER_MAJOR,CDRIVER_MINOR);

       result=register_chrdev_region(demo_dev,dev_count,CDRIVER_NAME);

   }

   else

   {

       result=alloc_chrdev_region(&demo_dev,CDRIVER_MINOR,dev_count,CDRIVER_NAME);

       CDRIVER_MAJOR=MAJOR(demo_dev);

   }

 

  if(result<0)

   {

       printk(KERN_ERR"Can not get major %d\n",CDRIVER_MAJOR);

       return -1;

   }

  

   demo_cdev=cdev_alloc();

   if(demo_cdev!=NULL)

   {

       cdev_init(demo_cdev,&demo_fops);

       demo_cdev->ops=&demo_fops;

       demo_cdev->owner=THIS_MODULE;

       if(cdev_add(demo_cdev,demo_dev,dev_count))

              printk(KERN_NOTICE"Something is wrong adding demo_cdev!\n");

       else

              printk("Success adding demo_cdev!\n");

   }

   else

   {

      printk(KERN_ERR"Register demo_dev error!\n");

       return -1;

   }

 

   demo_class=class_create(THIS_MODULE,"demo");

   class_device_create(demo_class,NULL,MKDEV(CDRIVER_MAJOR,0),NULL,"demo");

  

   return 0;

 

/*

   }

    int  result;

    result = register_chrdev(demo_MAJOR, "demo", &demo_fops);

    if (result < 0)

    {

       printk("Unable to register demo device!\n");

        return result;

}

else

{

       printk("initialized \n");

       return 0;

}

*/

}

 

/*************************************************************************************/

static void __exit  demo_exit(void)

{

           /*

       int ret;

       ret=unregister_chrdev(demo_MAJOR, "demo");

       if(ret<0)

       printk("Unable to unregister demo device!\n");

       else

       printk(" demo unloaded\n");

       */

 

 

       cdev_del(demo_cdev);

       unregister_chrdev_region(demo_dev,dev_count);

       printk(" demo unloaded\n");

 

}

 

/*************************************************************************************/

module_init(demo_init);

module_exit(demo_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("xuyuanchao @ict.ac.cn");

MODULE_DESCRIPTION("DEMO DRIVER!");

 

 

 

 

 

 

 

Kernel 2.4  demo 驱动程序

/**************************************************************

       demo.c

       linux driver example for UP-netarm3000 & UP-netarm2410

       It can be compiled for x86 PC

       author: zou jian-guo

       date:   2004-8-20

 

***************************************************************/

 

 

//#define CONFIG_DEVFS_FS

 

 

#ifndef __KERNEL__

#  define __KERNEL__

#endif

#ifndef MODULE

#  define MODULE

#endif

 

 

#include

#include

#include

 

#include

#include    /* printk() */

#include    /* kmalloc() */

#include        /* everything... */

#include     /* error codes */

#include     /* size_t */

#include

#include     /* O_ACCMODE */

#include     /* COPY_TO_USER */

#include      /* cli(), *_flags */

 

#define DEVICE_NAME              "demo"

#define demo_MAJOR 254

#define demo_MINOR 0

static int MAX_BUF_LEN=1024;

static char drv_buf[1024];

static int WRI_LENGTH=0;

 

/*************************************************************************************/

/*逆序排列缓冲区数据*/

static void do_write()

{

 

       int i;

       int len = WRI_LENGTH;

       char tmp;

       for(i = 0; i < (len>>1); i++,len--){

              tmp = drv_buf[len-1];

              drv_buf[len-1] = drv_buf[i];

              drv_buf[i] = tmp;

       }

}

/*************************************************************************************/

static ssize_t  demo_write(struct file *filp,const char *buffer, size_t count)

{

       if(count > MAX_BUF_LEN)count = MAX_BUF_LEN;

       copy_from_user(drv_buf , buffer, count);

       WRI_LENGTH = count;

       printk("user write data to driver\n");

       do_write();    

       return count;

}

/*************************************************************************************/

static ssize_t  demo_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)

{

       if(count > MAX_BUF_LEN)

              count=MAX_BUF_LEN;

       copy_to_user(buffer, drv_buf,count);

       printk("user read data from driver\n");

       return count;

}

/*************************************************************************************/

static int demo_ioctl(struct inode *inode, struct file *file,

                 unsigned int cmd, unsigned long arg)

{

       printk("ioctl runing\n");

       switch(cmd){

              case 1:printk("runing command 1 \n");break;

              case 2:printk("runing command 2 \n");break;

              default:

                     printk("error cmd number\n");break;

       }

       return 0;

}

/*************************************************************************************/

static int demo_open(struct inode *inode, struct file *file)

{

       sprintf(drv_buf,"device open sucess!\n");

       printk("device open sucess!\n");

       return 0;

}

/*************************************************************************************/

static int  demo_release(struct inode *inode, struct file *filp)

{

       MOD_DEC_USE_COUNT;

       printk("device release\n");

       return 0;

}

 

/*************************************************************************************/

static struct file_operations demo_fops = {

       owner:    THIS_MODULE,

       write:      demo_write,  

       read:       demo_read,    

       ioctl:       demo_ioctl,

       open:       demo_open,

       release:    demo_release,

};

/*************************************************************************************/

 

#ifdef CONFIG_DEVFS_FS

static devfs_handle_t  devfs_demo_dir, devfs_demoraw;

#endif

 

/*************************************************************************************/

static int __init demo_init(void)

{

#ifdef CONFIG_DEVFS_FS

       devfs_demo_dir = devfs_mk_dir(NULL, "demo", NULL);

       devfs_demoraw = devfs_register(devfs_demo_dir, "0", DEVFS_FL_DEFAULT,

                     demo_MAJOR, demo_MINOR, S_IFCHR | S_IRUSR | S_IWUSR,

                     &demo_fops, NULL);

#else

       int  result;

    SET_MODULE_OWNER(&demo_fops);

    result = register_chrdev(demo_MAJOR, "demo", &demo_fops);

    if (result < 0) return result;

//    if (demo_MAJOR == 0) demo_MAJOR = result; /* dynamic */

#endif

       printk(DEVICE_NAME " initialized\n");

       return 0;

}

 

/*************************************************************************************/

static void __exit  demo_exit(void)

{

    unregister_chrdev(demo_MAJOR, "demo");

    //kfree(demo_devices);

       printk(DEVICE_NAME " unloaded\n");

}

 

/*************************************************************************************/

module_init(demo_init);

module_exit(demo_exit);

 

测试程序

#include

#include

#include

#include

#include

 

 

void showbuf(char *buf);

int MAX_LEN=32;

 

int main()

{

       int fd;

       int i;

       char buf[255];

      

       for(i=0; i

              buf[i]=i;

       }

 

       fd=open("/dev/demo",O_RDWR);

       if(fd < 0){

              printf("####DEMO  device open fail####\n");

              return (-1);

       }

       printf("write %d bytes data to /dev/demo \n",MAX_LEN);

       showbuf(buf);

       write(fd,buf,MAX_LEN);

 

       printf("Read %d bytes data from /dev/demo \n",MAX_LEN);

       read(fd,buf,MAX_LEN);

       showbuf(buf);

      

       ioctl(fd,1,NULL);

       ioctl(fd,4,NULL);

       close(fd);

       return 0;

 

}

 

 

void showbuf(char *buf)

{

       int i,j=0;

       for(i=0;i

              if(i%4 ==0)

                     printf("\n%4d: ",j++);

              printf("%4d ",buf[i]);

       }

       printf("\n*****************************************************\n");

}

 

阅读(2020) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~