混杂设备驱动

混杂设备概念

在Linux驱动中把无法归类的五花八门的设备定义为混杂设备,所有混杂设备共享一个主设备号10,但次设备号不同。 所有的混杂设备形成了一个链表,对设备访问时内核根据次设备号查找对应的混杂设备,然后调用其file_operations结构中注册的文件操作接口进行操作。

驱动模型

描述结构

混杂设备在内核中用struct miscdevice 描述,其定义如下:

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;
};

驱动编写只需要关注填写三个字段:minor次设备号、name设备名、fops 设备操作集

注册驱动

混杂设备驱动通过如下函数注册:

int misc_register(struct miscdevice *misc);

注销驱动

通过如下函数注销驱动:

int misc_deregister(struct miscdevice *misc);

驱动模型思维导图

通过如上知识并结合模块的知识可以画出混杂设备驱动的思维导图:
混杂设备驱动模型

驱动范例

下面是笔者实现的基于混杂设备驱动的LED设备驱动代码:
驱动代码:


#include <linux/init.h>
#inlude <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
/*打开函数*/
int misc_open(struct inode *inode,struct file *file){
    led_con = ioremap(LEDCON,4);
    led_dat = ioremap(lEDDAT,4);
    writel(0x00000001,led_con);
    return 0;
}
/*控制函数*/
long misc_ioctl(struct file *file,unsigned int cmd,unsigned long arg){
    switch(cmd){
        //点亮led
        case 1: writel(0x01,led_dat);
                break;
        //熄灭led
        case 0: writel(0x00000000,led_dat);
                break;
        default:
                return -EINVAL;
    }
    return 0;

}
/*关闭函数*/
int misc_close(struct inode *inode, struct file *file){
    return 0;

}
/*定义操作函数集*/
struct file_operations misc_fops = {
    .open = misc_open,
    .unlocked_ioctl = misc_ioctl,
    .release = misc_close,
}; 
/*定义混杂设备驱动描述结构*/
struct miscdevice misc = {
    .minor = 100,
    .name = "misc",
    .fops = misc_fops,

};
/*模块加载函数*/
static int misc_init(void){
    misc_register(&misc);
    return 0;
}
/*模块卸载函数*/
static void misc_exit(void){
    misc_deregister(&misc);
}

MODULE_LICENSE("GPL");
module_init(misc_init);
module_exit(misc_exit);

调用驱动的应用程序测试代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdio.h>
int main(int argc,char *argv[]){
    int fd;
    int i=0;
    //因为驱动直接在/dev/目录下生成了设备节点misc ,因此应用程序可以直接打开该文件。
    fd = open("/dev/misc",O_RDWR);
    if(fd<0){
    printf("App open failed\n");
        return 0;
    }
    while(i++ < 4){
    ioctl(fd,0);
        sleep(1);
        ioctl(fd,1);
        sleep(1);
    }
    return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值