`
hyshucom
  • 浏览: 806301 次
文章分类
社区版块
存档分类
最新评论

Linux内核学习-misc杂项设备驱动

 
阅读更多

Linux里面的misc杂项设备是主设备号为10的驱动设备,它的注册跟使用比较的简单,所以比较适用于功能简单的设备。

它有自己的设备结构体:

struct miscdevice {
int minor;
const char *name;
const struct file_operations *fops;
struct list_head list;
struct device *parent;
struct device *this_device;
const char *nodename;
mode_t mode;
};
它在头文件linux/miscdevice.h里面有定义,

其中minor是misc设备的副设备号,misc设备主要依赖minor去区分,如果设置为MISC_DYNAMIC_MINOR则表示系统自动分配未使用的minor

nodename是在/dev下面创建的设备驱动节点,

fops是驱动主体处理函数入口指针

主要使用到的函数有:

int misc_register(struct miscdevice * misc);
int misc_deregister(struct miscdevice *misc);

misc01.c文件

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
/////////////////////////////////////////////////
MODULE_LICENSE("Dual BSD/GPL");
int open_state = 0;
/////////////////////////////////////////////////
int misc01_open(struct inode *inode, struct file *filp)
{
    if (open_state == 0)
    {
        open_state = 1;
        printk("misc01 open!\n");
        return 0;
    }
    printk("misc01 has been open!\n");
    return -1;
}

int misc01_release(struct inode *inode, struct file *filp)
{
    if (open_state == 1)
    {
        open_state = 0;
        printk("misc01 release!\n");
        return 0;
    }
    printk("misc01 has not been open yet!\n");
    return -1;
}

ssize_t misc01_read(struct file *filp, char *buf,
        size_t count, loff_t fpos)
{
    printk("misc01 read!\n");
    return 0;
}

ssize_t misc01_write(struct file *filp, char *buf,
        size_t count, loff_t fpos)
{
    printk("misc01 write!\n");
    return 0;
}

int misc01_ioctl(struct inode *inode, struct file *filp,
        unsigned int cmd, unsigned long arg)
{
    printk("ioctl is called!\n");
    printk("cmd:%d arg:%d\n", cmd, arg);
    return 0;
}
/////////////////////////////////////////////////
struct file_operations fops = 
{
    .owner      =   THIS_MODULE,
    .open       =   misc01_open,
    .release    =   misc01_release,
    .write      =   misc01_write,
    .read       =   misc01_read,
    .ioctl      =   misc01_ioctl
};

struct miscdevice dev = 
{
    .minor  =   MISC_DYNAMIC_MINOR,
    .fops    =   &fops,
    .name   =   "misc01",
    .nodename = "misc01_node"
};

int setup_misc01(void)
{
    
    return misc_register(&dev);
}
/////////////////////////////////////////////////
static int __init misc01_init(void)
{
    printk("misc01 init!\n");
    return setup_misc01();
}

static void __exit misc01_exit(void)
{
    printk("misc01 exit!\n");
    misc_deregister(&dev);
}

/////////////////////////////////////////////////
module_init(misc01_init);
module_exit(misc01_exit);


Makefile文件

#Makefile
obj-m	:=	misc01.o
PWD		:=	$(shell pwd)
K_DIR	:=	/lib/modules/$(shell uname -r)/build

all:
	$(MAKE) -C $(K_DIR) M=$(PWD) modules
clean:
	$(MAKE) -C $(K_DIR) M=$(PWD) clean
test:misc01_test.o
	gcc -o $@ {1}lt;


misc01_test.c文件

#include <stdio.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
/////////////////////////////////////////////////
int main(int argc, char **argv)
{
    int fd;
    fd = open("/dev/misc01_node", O_RDONLY);
    if (fd < 0)
    {
        printf("open /dev/misc01_node failed!\n");
        printf("%s\n", strerror(errno));
        return -1;
    }
    
    printf("open /dev/misc01_node ok!\n");
    if (ioctl(fd, 6) != 0)
    {
        printf("ioctl failed!\n");
        printf("%s\n", strerror(errno));
    }
    else
        printf("ioctl ok!\n");
    close(fd);
    return 0;
}


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics