深入浅出LDD-2-用户对模块的调用

来源:互联网 发布:淘宝秋装新款女装 编辑:程序博客网 时间:2024/06/01 14:00

/***************************************************************************************************
                                    设备驱动程序
* globalvar.c
* 功    能:实现全局变量的读写
*           使用用户程序调用驱动模块的函数。

* 特    点:
            需要手动加入节点,方法如下:
                    cat    /proc/devices        查找要加入的设备名字(name)及设备号(unm)
                    mknod  /dev/name c num 0    加入
                加入了节点,在用户程序user.c才能找到该设备
            固定分配设备号。
* 编译环境: SUSELinux 虚拟机
* 实 验 者:张永辉 2012年8月xx日
***************************************************************************************************/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/uaccess.h>

MODULE_LICENSE("GPL");
#define MAJOR_NUM 1024              //主设备号

static ssize_t globalvar_read (struct file *, char *,       size_t, loff_t*);
static ssize_t globalvar_write(struct file *, const char *, size_t, loff_t*);

static int     global_var = 0;      //设备的全局变量

static ssize_t globalvar_read(struct file *filp, char *buf, size_t len, loff_t *off)
{
    //将global_var从内核空间复制到用户空间
    if ( copy_to_user(buf, &global_var, sizeof(int)))
    {
        return - EFAULT;
    }
    printk("globalvar_read enter ,the data is %d\n",global_var);
    return sizeof(int);
}

static ssize_t globalvar_write(struct file *filp, const char *buf, size_t len, loff_t *off)
{
    //将用户空间的数据复制到内核空间的global_var
    if (copy_from_user(&global_var, buf, sizeof(int)))
    {
        return - EFAULT;
    }
    printk("globalvar_write enter ,the data is %d\n",global_var);
    return sizeof(int);
}

//初始化字符设备驱动的file_operations结构体 read: globalvar_read, write: globalvar_write,
struct file_operations globalvar_fops =
{
    .write  = globalvar_write,
    .read   = globalvar_read,
};

static int __init globalvar_init(void)
{
    int ret;

    ret = register_chrdev(MAJOR_NUM, "globalvar", &globalvar_fops); //注册设备驱动
    if (ret)
    {
        printk("globalvar register failure");
    }else
    {
        printk("globalvar register success");
    }
    return ret;
}

//注销设备驱动
static void __exit globalvar_exit(void)
{
    unregister_chrdev(MAJOR_NUM, "globalvar");
}

module_init(globalvar_init);
module_exit(globalvar_exit);

/***************************************************************************************************
* Makefile
***************************************************************************************************/
obj-m := globalvar.o                                    #模块编译的目标必须以obj-m 这样的形式指出
KERNELDIR ?= /lib/modules/$(shell uname -r)/build       #模块的编译必须指定内核源代码的路径

PWD := $(shell pwd)
modules:
 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules            #本行开头必须使用 Tab 键
modules_install:
 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

clearn:
 rm -rf *.o *.ko *mod.o [mM]odule* .*.cmd .tmp_versions

/***************************************************************************************************
                                    使用方法
共三个文件:globalvar.c 驱动代码
             Makefile       用于编译驱动
             user.c         用户程序,会使用globalvar驱动。

放到同一目录,做如下操作
    #make                           编译驱动
    #insmod globalvar.ko            安装驱动
    #lsmod                          查看都有哪些驱动,是否成功安装
    #cat    /proc/devices           查找globalvar的设备号(此处是1024)
    #mknod  /dev/globalvar 1024 0   将设备加入节点
    #gcc user.c                     编译用户程序
    #./a.out                        执行用户程序,处会执行成功
     ...
    #rmmod globalvar.ko             卸载驱动
    #./a.out                        执行用户程序,处会执行失败,以为没有globalvar模块了。
     ...

张永辉  2012年8月28日  suseLinux验证通过。
***************************************************************************************************/
#include <stdio.h>
#include <sys/stat.h>       //获得文件的属性,它可以返回一个结构,里面包含文件全部属性
#include <fcntl.h>          //设备驱动程序接口是由结构说明,它定义在fcntl.h中
#include <sys/types.h>      //类型 clock_t,dev_t,off_t,ptrdiff,size_t,ssize_t,time_t

int main(void)
{
    int fd, num;

    fd = open("/dev/globalvar", O_RDWR, S_IRUSR | S_IWUSR);
    printf("fd = %d \n",fd);

    if (fd != -1 )
    {
        read(fd, &num, sizeof(int));
        printf("The globalvar is %d\n", num);

        printf("Please input the num written to globalvar\n");
        scanf("%d", &num);

        write(fd, &num, sizeof(int));
        read(fd, &num, sizeof(int));
        printf("The globalvar is %d\n", num);

        close(fd);
    }else
    {
        printf("Device open failure\n");
    }
    return 0;
}

 

原创粉丝点击