Chinaunix首页 | 论坛 | 博客
  • 博客访问: 279440
  • 博文数量: 109
  • 博客积分: 2116
  • 博客等级: 大尉
  • 技术积分: 1062
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-22 15:38
文章分类

全部博文(109)

文章存档

2013年(2)

2011年(16)

2010年(90)

2009年(1)

我的朋友

分类: 嵌入式

2010-08-10 11:16:41

完成一个简单驱动的实验。

 

步骤:

1 编辑驱动源文件drv_example.c。编写Makefile文件。编译。

看到make的过程中,出现了两个警告,那是内核升级造成的,可以不管。

2 加载编译好的驱动模块。

命令: insmod  drv_example.ko

对比上面两幅截图,可以看出驱动模块已经加载到内核当中了。

3 编译写好的测试文件test.c。并执行

可以看出测试成功!

4 卸载驱动。

命令:rmmod drv_example

 

注:初次加载需要/dev目录下创建设备节点

命令:mknod /dev/drv_example c 254 0

c表示字符设备,254为主设备号,0为次设备号。

 

源代码来自顶嵌:

1 drv_example.c

#include

#include

#include

#include

#include

#include     /* size_t */

#include     /*copy_to_user/copy_from_user*/

#include "drv_example.h"

#define DRIVER_NAME "drv_example"

static  int device_major_number =   0;

 

MODULE_LICENSE("GPL");

 

struct example_device {

    int usage;

    char *data;

    int new_msg;

};

 

struct example_device exampledev;

 

 

/* This function handles open for the character device */

 

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

{

    printk ("example_chrdev_open:OK!\n");

    return 0;

}

 

/* This function handles close for the character device */

 

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

{

    printk ("example_chrdev_release:OK!\n");

    return 0;

}

 

/* This function handles read for the character device */

static ssize_t  example_chrdev_read(struct file *f, char __user *buf, size_t size, loff_t* off)

{

    int length;

    int count=size;

   

    printk ("example_chrdev_read:OK!\n");   

    if(count<0)

       return -EINVAL;

    if(exampledev.usage)

        return -EBUSY;

    exampledev.usage=1;

    if(exampledev.data ==0 )

        return 0;

    length = strlen(exampledev.data);

    if(length < count)

       count=length;

    copy_to_user(buf,exampledev.data,count+1);

    exampledev.new_msg = 0;

    exampledev.usage = 0;

 

     return count;

}

 

/* This function handles write for the character device */

static ssize_t example_chrdev_write(struct file *f, const char *buf, size_t size,loff_t* off)

{

    int count=size;

   

    printk ("example_chrdev_write:OK!\n");

    if(count<0)

       return -EINVAL;

    if(exampledev.usage|exampledev.new_msg)

        return -EBUSY;

    exampledev.usage = 1;

    kfree(exampledev.data);

    exampledev.data = kmalloc(sizeof(char)*(count + 1),GFP_KERNEL);

    if(!exampledev.data)

        return -ENOMEM;

    copy_from_user(exampledev.data, buf, count + 1);

    exampledev.usage = 0;

    exampledev.new_msg = 1;

    return count;

}

 

 

/* This function handles ioctl for the character device */

static int example_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)

{

    /* See which ioctl we are doing */

    switch (cmd) {

    case IOCTL_1:

        printk(KERN_NOTICE "Do task 1:OK! \n");

        break;

    case IOCTL_2:

        printk(KERN_NOTICE "Do task 2::OK! \n");

        break;

    default:

         printk(KERN_NOTICE "No task \n");

        break;

    }

    return 0;

}

/* File operations struct for character device */

 

static  struct file_operations example_fops = {

    .owner      = THIS_MODULE,

    .open       = example_chrdev_open,

    .release    = example_chrdev_release,

    .read       = example_chrdev_read,

    .write      = example_chrdev_write,

    .ioctl      = example_chrdev_ioctl,

};

 

 

 

static int __init example_init (void)

{

    int Rv = 0;

    device_major_number = register_chrdev(0, DRIVER_NAME, &example_fops);

    printk(KERN_ALERT "example_init:OK! \n");

    printk(KERN_ALERT "The example device major number is %d ! \n",device_major_number);

    return Rv;

}

 

static void __exit example_cleanup( void )

{

    unregister_chrdev( device_major_number, DRIVER_NAME );

    printk(KERN_ALERT "example_cleanup:OK! \n");

}

 

module_init (example_init);

module_exit (example_cleanup);

2 drv_example.h

#ifndef DRV_EXAMPLE_H

#define DRV_EXAMPLE_H

 

enum IOCTL_FUNCTIONS

{

    IOCTL_1=1,

    IOCTL_2,

};

 

#endif

3 Makefile

#Hello world module example Makefile

ifneq ($(KERNELRELEASE),)

    obj-m :=drv_example.o

else

    #KERNELDIR ?= /home/mike/linux-2.6.10

    KERNELDIR=/lib/modules/$(shell uname -r)/build

    PWD := $(shell pwd)

default:

    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:

    rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c

endif

4 test.c

#include

#include

#include

#include

 

#define MAX_LENGTH 100

int main( int argc, char *argv[] )

{

    int     DeviceHandle = -1;

    char str[MAX_LENGTH];

    char buf[MAX_LENGTH];

    char *p;

    /*Test open operation*/

    if((DeviceHandle=open("/dev/drv_example", O_RDWR )) <= 0 )

    {

        printf("Open ioctl device is failed! \n");

        return 0;

    }

    printf("please enter the words(max char num:%d):\n", MAX_LENGTH - 1);

    p = fgets(str, MAX_LENGTH, stdin);

   

    /*Test write operation*/

    write(DeviceHandle, p, strlen(p));

    /*Test read operation*/

    read(DeviceHandle, buf, MAX_LENGTH - 1);

    printf("Get strings from drv_example:\n%s\n", buf);

    /*Test ioctl operation*/

    ioctl(DeviceHandle, 1, &argv[1], NULL);

    ioctl(DeviceHandle, 2, &argv[1], NULL);

    /*Test release operation*/

    close(DeviceHandle);

   

    return 0;      

}

 

 

 

阅读(561) | 评论(0) | 转发(0) |
0

上一篇:hello驱动

下一篇:mm驱动

给主人留下些什么吧!~~