一、基础知识

misc驱动是用来代替字符设备驱动的手动申请设备号、初始化cdev、添加、创建类、创建设备等等步骤的,只需要用misc_register函数就可以完成以上操作,卸载也是只需要misc_deregister函数即可完成一键卸载

想要使用misc驱动的话,要包含miscdevice.h,使用结构体struct miscdevice。
misc驱动的主设备号都是10

二、驱动程序

#include <linux/ide.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>/********************************************************************* miscbeep.c* 作者:张亚胜* 版本:V1.0* 描述:采用MISX的beep驱动程序* 其他:无* 网站:www.s123.xyz* 日志:出版V1.0 2020/8/12 张亚胜创建* ******************************************************************/
#define MISCBEEP_NAME  "miscbeep"   /* 设备名字 */
#define MISCBEEP_MINOR  144          /* 子设备号 */
#define BEEP_OFF        0            /* 关 */
#define BEEP_ON         1            /* 开 *//* miscbeep设备结构体 */
struct miscbeep_dev{dev_t dev_id;           /* 设备号 */struct cdev cdev;       /* 字符设备 */struct class *class;    /* mdev 自动节点文件使用 */struct device *device;  /* class使用 */struct device_node *nd; /* 设备节点 */int beep_gpio;          /* beep gpio 编号 */
};struct miscbeep_dev miscbeep;   /* beep设备 */static int beep_open(struct inode *inode,struct file *filp)
{filp->private_data = &miscbeep;    /* 设置私有数据 */return 0;
}static ssize_t beep_write(struct file *filp,const char __user *buf,size_t cnt,loff_t *offt)
{int retval = 0;unsigned char databuf[1];unsigned char beepstat;struct miscbeep_dev *dev = filp->private_data;retval = copy_from_user(databuf,buf,cnt);if(retval<0){printk("kernel write failed!\r\n");return -EFAULT;}beepstat = databuf[0];if(beepstat == BEEP_ON){gpio_set_value(dev->beep_gpio,0);}else if(beepstat == BEEP_OFF){gpio_set_value(dev->beep_gpio,1);}return 0;
}static struct file_operations miscbeep_fops = {.owner = THIS_MODULE,.open = beep_open,.write = beep_write,
};static struct miscdevice beep_miscdev = {.minor = MISCBEEP_MINOR,//子设备号.name = MISCBEEP_NAME,//字符设备名称 会在/dev/生成文件.fops = &miscbeep_fops,
};/* 当驱动和设备匹配成功后此函数就会执行 */
static int miscbeep_probe(struct platform_device *dev)
{int ret = 0;printk("beep driver and device was matched!\r\n");/* 设置beep所用的gpio *///获取设备节点miscbeep.nd = of_find_node_by_path("/gpiobeep");if(miscbeep.nd == NULL){printk("neep node not find!\r\n");return -EINVAL;}/* 获取设备树中的gpio属性 得到gpio编号 */miscbeep.beep_gpio = of_get_named_gpio(miscbeep.nd,"beep-gpio",0);if(miscbeep.beep_gpio < 0){printk("can't get beep-gpio!\r\n");return -EINVAL;}/* 设置引脚为输出 默认输出高电平 关闭beep */    ret = gpio_direction_output(miscbeep.beep_gpio,1);if(ret < 0){printk("can't set gpio!\r\n");}/* 使用misc注册字符设备 */ret = misc_register(&beep_miscdev);if(ret < 0){printk("misc device register failed!\r\n");return -EFAULT;}return 0;
}static int miscbeep_remove(struct platform_device *dev)
{/* 注销设备的时候关闭beep */gpio_set_value(miscbeep.beep_gpio,1);/* 注销misc设备驱动 */misc_deregister(&beep_miscdev);return 0;
}/* 匹配列表 */
static const struct of_device_id beep_of_match[] = {{.compatible = "atkalpha-gpiobeep"},{ /* Sentinel */ },
};/* platform驱动结构体 */
static struct platform_driver beep_driver = {.driver = {.name = "imx6ul-beep",  /* 驱动名称 不采用设备树的匹配方式*/.of_match_table = beep_of_match,    /* 设备树匹配表 */},.probe = miscbeep_probe,.remove = miscbeep_remove,
};static int __init beep_init(void)
{return platform_driver_register(&beep_driver);
}static void __exit beep_exit(void)
{platform_driver_unregister(&beep_driver);
}module_init(beep_init);
module_exit(beep_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("zys");

三、测试程序

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
/********************************************************************* 文件名:miscbeepApp.c* 作者:张亚胜* 版本:V1.0* 描述:miscbeep测试文件* 其他:使用方法:./miscbeepApp /dev/miscbeep 0 //写0 关*                ./miscbeepApp /dev/miscbeep 1 //写1 开* 网站:www.s123.xyz* 日志:出版V1.0 2020/8/12 张亚胜创建* ******************************************************************//*
* @description : main 主程序
* @param - argc : argv 数组元素个数
* @param - argv : 具体参数
* @return : 0 成功;其他 失败
*/
int main(int argc, char *argv[])
{int fd,retval;char *filename;char buf[100];if(argc != 3){printf("params err!\r\n");return -1;}filename = argv[1];fd = open(filename,O_RDWR);if(fd<0){printf("file %s open failed!\r\n", argv[1]);return -1;}buf[0] = atoi(argv[2]);retval = write(fd,buf,1);if(retval < 0){printf("BEEP Control Failed!\r\n");close(fd);return -retval;}retval = close(fd);if(retval<0){printf("file %s close failed!\r\n", argv[1]);return -retval;}return 0;
}

四、测试



linux驱动开发 | misc驱动相关推荐

  1. Linux驱动开发 -- touch驱动注册

    Linux i2c驱动开发 – touch 驱动 文章目录 Linux i2c驱动开发 -- touch 驱动 前言 一.i2c 驱动框架 二.Linux的MODULE声明 1. MODULE相关声明 ...

  2. 解析Linux内核源码中数据同步问题丨C++后端开发丨Linux服务器开发丨Linux内核开发丨驱动开发丨嵌入式开发丨内核操作系统

    剖析Linux内核源码数据同步 1.pdflush机制原理 2.超级块同步/inode同步 3.拥塞及强制回写技术 视频讲解如下,点击观看: 解析Linux内核源码中数据同步问题丨C++后端开发丨Li ...

  3. Linux驱动开发——串口设备驱动

    Linux驱动开发--串口设备驱动 一.串口简介 串口全称叫做串行接口,通常也叫做 COM 接口,串行接口指的是数据一个一个的顺序传输,通信线路简单.使用两条线即可实现双向通信,一条用于发送,一条用于 ...

  4. Linux嵌入式驱动开发02——驱动编译到内核

    文章目录 全系列传送门 make menuconfig图形化配置界面 1. 怎么进入到make menuconfig图形化界面? 2. make menuconfig图形化界面的操作 3. 退出 4. ...

  5. STM32MP157驱动开发——SPI驱动

    STM32MP157驱动开发--SPI驱动 一.简介 1.SPI介绍 2.STM32MP1 SPI介绍 3. ICM-20608 简介 4.Linux下的SPI框架 二.驱动开发 1)IO 的 pin ...

  6. linux驱动开发音频设备驱动,linux驱动开发—基于Device tree机制的驱动编写

    摘要:媒介 Device Tree是一种用去描绘硬件的数据布局,类似板级描绘说话,发源于OpenFirmware(OF).正在现在遍及应用的kernel 2.6.x版本中,对分歧仄台.分歧硬件,往] ...

  7. Linux 设备驱动开发思想 —— 驱动分层与驱动分离

    前面我们学习I2C.USB.SD驱动时,有没有发现一个共性,就是在驱动开发时,每个驱动都分层三部分,由上到下分别是: 1.XXX 设备驱动 2.XXX 核心层 3.XXX 主机控制器驱动 而需要我们编 ...

  8. linux摄像头内核驱动开发,怎么在Linux下开发摄像头驱动

    无根之木不活,无基之楼不立,无论是学习哪个领域知识,基础是重中之重. 针对学习linux驱动,我们来仔细谈谈: 个人认为C语言和数据结构就是重中之重!Linux系统最优秀的地方就在于内核.无论是进程调 ...

  9. I.MX6ULL ARM驱动开发---网络设备驱动框架

    引言   网络驱动是 linux 里面驱动三巨头之一,linux 下的网络功能非常强大,嵌入式 linux 中也常常用到网络功能.前面我们已经讲过了字符设备驱动和块设备驱动,本章我们就来学习一下 li ...

最新文章

  1. D - Silver Cow Party POJ - 3268
  2. python数据文件读写
  3. 如何正确选择开源数据库?你需要这的5个技巧
  4. CentOs 7.2下ELK日志分析系统搭建
  5. python调用父类对象的几个方法
  6. 适用于无服务器Java开发人员的AWS Lambda:它为您带来了什么?
  7. angular html清除元素,在Angular js中单击时删除HTML元素
  8. const变量初始化问题
  9. qt给qdialog加一个滚动条_这些小程序技巧,你敢说你一个用不到?
  10. 深圳 计算机网络与管理,深圳计算机网络管理员路由与交换班
  11. 哈希表,设计哈希集合,
  12. 关于linux下进程、线程和任务的一种阐述
  13. MD5算法在PB中的实现(转载自 - 阿多米 - 博客园)
  14. 基于Sentence-Bert的检索式问答系统
  15. 研华数字量输入输出模块通讯——ADAM4050
  16. 射频day4:史密斯圆图
  17. matlab回归分析结果输出,科学网—回归分析的MATLAB和R程序实现 - 王福昌的博文...
  18. 烟雾传感器(mq-2)使用详细教程(基于树莓派3b+实现)
  19. 如何升级或更换PC的无线卡
  20. 从前端开始——01网页三剑客(html)

热门文章

  1. xmind基础教程-视图
  2. docker安装calibre
  3. ㊙ 女士尽量不要称爱人为“老公”
  4. 深圳java工资一般多少,写给正在求职的Java开发
  5. 阿里巴巴Java开发规范线程池_阿里巴巴java编程规范.pdf
  6. Choerodon猪齿鱼微服务后端环境变量方案
  7. Linux下安装Oracle11G详细过程
  8. 把.app文件打包ipa 利用Payload 打包ipa
  9. 时空序列预测:SimVP: Simpler yet Better Video Prediction解读
  10. Android逆向之旅—Hook神器Xposed使用详解