【Linux-MISC设备】

1. MISC设备

  1. MISC设备的主设备号为10.
  2. MISC设备会自动创建cdev,不需要再手动创建。
  3. MISC设备是基于platform的.

MISC驱动的编写的核心就是初始化miscdevice结构体变量,然后用misc_register函数向内核注册,然后使用misc_deregister函数删除注册.

  1. 如果设置MISC结构体中的minor是255的话是自动分配设备号。

2. MISC蜂鸣器实验

  1. 设备树添加
beep{
		compatible = "alientek,beep";
		pinctrl-names = "default";
		pinctrl-0 =  <&pinctrl_beep>;
		beep-gpios=<&gpio5 1 GPIO_ACTIVE_HIGH>;
		status = "okay";
	};
  1. 驱动文件编写

 驱动编写的思路就是先写paltform平台模板,随后就是关于MISC设备模板流程,最后就是自己设备信息的添加,例如节点信息,gpio号等等.

#define MISCBEEP_NAME "miscbeep"
#define MISCBEEP_MINOR  144
#define BEEPON  1
#define BEEPOFF 0
//添加设备的信息,注意这里是用户自定义的结构体,里面的信息是自主要添加的
struct miscbeep_dev {
    struct device_node *nd;
    int beep_gpio;
};
struct miscbeep_dev miscbeep;
//fops文件操作函数
static int miscbeep_release(struct inode *inode, struct file *file)
{
	printk("Close ok\r\n");
	return 0;
}
//fops文件操作函数
static int miscbeep_open(struct inode *inode, struct file *file)
{
	printk("Open ok\r\n");
    file->private_data = &miscbeep;
	return 0;
}
//fops文件操作函数
static ssize_t miscbeep_write(struct file *file, const char __user *buffer,size_t count, loff_t *pos)
{
    int ret = 0;
    unsigned char databuf[1];
	struct miscbeep_dev *dev=file->private_data;
    ret = copy_from_user(databuf,buffer,count);
    if(ret<0){
        return -EINVAL;
    }
    if(databuf[0]==BEEPON){
        gpio_set_value(dev->beep_gpio,0);
    }
    if(databuf[0]==BEEPOFF){
        gpio_set_value(dev->beep_gpio,1);
    }
	return 0;
}
//fops文件操作函数集
static struct file_operations miscbeep_fops = {
    .owner = THIS_MODULE,
    .open = miscbeep_open,
    .write = miscbeep_write,
    .release = miscbeep_release,

};
//将要注册的设备,包含必要的信息例如设备号,名字,文件操作合集,
//注意这里的结构体是内核定义的
static struct miscdevice beep_miscdev = {
    .minor = MISCBEEP_MINOR,
    .name = MISCBEEP_NAME,
    .fops = &miscbeep_fops,
};
//paltform平台设备与驱动匹配成功后执行的函数
static int  miscbeep_probe(struct platform_device *dev)
{
    int ret = 0;
    /*1.初始化蜂鸣器IO*/
     miscbeep.nd = dev->dev.of_node;
     miscbeep.beep_gpio = of_get_named_gpio(miscbeep.nd,"beep-gpios",0);
     if(miscbeep.beep_gpio < 0){
         ret = -EINVAL;
         goto fail_findgpio;
     }
     ret = gpio_request(miscbeep.beep_gpio,"beep-gpio");
     if(ret){
         printk("cant't request %d gpio",miscbeep.beep_gpio);
         ret = -EINVAL;
         goto fail_findgpio;
     }
     ret = gpio_direction_output(miscbeep.beep_gpio,1);/*输出高电平*/
     if(ret<0){
         goto fail_setoutput;
     }
    /*2.MISC驱动注册*/
    ret = misc_register(&beep_miscdev);
    if(ret<0){
        goto fail_setoutput;
    }
    return 0;
fail_setoutput:
    gpio_free(miscbeep.beep_gpio);
fail_findgpio:
    return ret;
}

//paltform平台设备与驱动匹配成功后,移除驱动后要执行的函数
static int miscbeep_remove(struct platform_device *dev)
{
    gpio_set_value(miscbeep.beep_gpio,1);
    gpio_free(miscbeep.beep_gpio);

    misc_deregister(&beep_miscdev);
    return 0;
}
/*paltform匹配表*/
static const struct of_device_id beep_of_match[]={
    {.compatible = "alientek,beep",},
    {/**/}
};
//paltform平台设备驱动定义结构体
static struct platform_driver miscbeep_driver = {
    .driver = {
        .name = "imx6ull-beep",
        .of_match_table = beep_of_match,/*设备树匹配表*/
    },
    .probe = miscbeep_probe,
    .remove = miscbeep_remove,
};
/*驱动入口和出口函数*/
static int __init miscbeep_init(void)
{
    return platform_driver_register(&miscbeep_driver);
}
static void __exit miscbeep_exit(void)
{
    platform_driver_unregister(&miscbeep_driver);
}
module_init(miscbeep_init);
module_exit(miscbeep_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("WYJ");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值