N22 key驱动

一、platform自动匹配

  1. 定义一个 platform_driver,告诉内核:我是一个正规驱动
  2. 内核会自动去设备树里找匹配的硬件(compatible)
  3. 找到后自动调用 probe 函数
  4. probe 里:
    • 读取设备树地址
    • ioremap 映射寄存器
    • 注册 misc 设备
  5. 设备拔掉 → remove
  6. 驱动卸载 → 自动清理
  7. 应用层通过 /dev/led 控制亮灭

它是标准 Linux 驱动结构,内核统一管理。

内核自动匹配,只看 compatible,不关心路径。

这是 Linux 驱动最核心思想:驱动与设备分离。
copy_to_user:内核 → 用户

copy_from_user:用户 → 内核

cs 复制代码
字符串替换
:%s/led/key/g

二、key驱动(linux/of_irq.h)

cs 复制代码
#include <linux/init.h>
#include <linux/printk.h>
#include <linux/kdev_t.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/export.h>
#include <asm/uaccess.h>
#include <asm/string.h>
#include <asm/io.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/of_irq.h>
#include <linux/wait.h>
#include <linux/sched.h>

#define DEV_NAME "key"
static unsigned int irq_key_num;
#define key_ON 0
#define key_OFF 1
static int arg = 100;
static wait_queue_head_t wq;
static int condition;

static irqreturn_t key_irq_handler(int dev_num, void * dev)
{
	condition = 1;
	wake_up_interruptible(&wq);
	printk("dev_num = %d  dev = %d\n", dev_num, *(int *)dev);
	return IRQ_HANDLED;
}

static int open(struct inode * node, struct file * file)
{
	printk("key  open...\n");
	return 0;
}

static ssize_t read(struct file * file, char __user * buf, size_t len, loff_t * offset)
{
	condition = 0;
	wait_event_interruptible(wq, condition);
	//copy_to_user();
	printk("key  read...\n");
	return 0;
}

static int close(struct inode * node, struct file * file)
{
	printk("key  close...\n");
	return 0;
}

static struct file_operations fops = 
{
	.owner = THIS_MODULE,
	.open = open,
	.read = read,
	.release = close
};

static struct miscdevice misc = 
{
	.minor = MISC_DYNAMIC_MINOR,
	.name = DEV_NAME,
	.fops = &fops
};

static int probe(struct platform_device * pdev)
{
	struct device_node * pnode;

	int ret = misc_register(&misc);
	if(IS_ERR_VALUE(ret))
		goto err_misc;

	pnode = of_find_node_by_path("/pt_key");
	if(IS_ERR(pnode))
	{
		ret = PTR_ERR(pnode);
		goto err_find_node;
	}

	irq_key_num = irq_of_parse_and_map(pnode, 0);
	if(irq_key_num < 0)
	{
		ret = irq_key_num;
		goto err_of_parse;
	}

	ret = request_irq(irq_key_num, key_irq_handler, IRQF_TRIGGER_FALLING, "key_irq", &arg);
	if(ret < 0)
		goto err_request_irq;

	init_waitqueue_head(&wq);

    printk("probe   key misc_register    ##############\n");
    return 0;

err_request_irq:
	disable_irq(irq_key_num);
	free_irq(irq_key_num, &arg);
	printk("key err_request_irq\n");
err_of_parse:
	printk("key err_of_parse\n");
err_find_node:
	printk("of_find_node_by_path  err\n");
err_misc:
	printk("key  probe faikey  ret = %d\n", ret);
	misc_deregister(&misc);
	return ret;
}

static int remove(struct platform_device * pdev)
{
	disable_irq(irq_key_num);
	free_irq(irq_key_num, &arg);
	misc_deregister(&misc);
    printk("remove  key misc_deregister    ##############\n");

	return 0;
}
	
static const struct of_device_id match_table[] = 
{
	[0] = {.compatible = "pt-key"}
};

static struct platform_driver drv = 
{
	.probe = probe,
	.remove = remove,
	.driver = 
	{
		.name = DEV_NAME,
		.of_match_table = match_table
	}
};

static int __init key1_init(void)
{
	int ret = platform_driver_register(&drv);
	if(ret < 0)
		goto err_reg;

	printk("platform_driver_register  ...\n");
	return 0;

err_reg:
	printk("platform_driver_register  faikey ret = %d\n", ret);
	platform_driver_unregister(&drv);
	return ret;
}

static void __exit key1_exit(void)
{
	platform_driver_unregister(&drv);
	printk("platform_driver_unregister  ...\n");
}

module_init(key1_init);
module_exit(key1_exit);
MODULE_LICENSE("GPL");
相关推荐
阿里云大数据AI技术5 小时前
阿里云 EMR AI 助手正式发布:从问答工具到全栈智能运维助手
运维·人工智能
你好潘先生11 小时前
别再记命令了,用 yeero do 说句人话就能跑脚本,而且不烧 token
服务器·python·命令行
orion571 天前
Missing Semester Class1:course overview and introduction of shell
linux
SkyWalking中文站1 天前
认识 Horizon UI · 6/17:Trace 探索器
运维·监控·自动化运维
用户120487221611 天前
Linux驱动编译与加载
linux·嵌入式
程序员老赵1 天前
服务器文件不想 SFTP 上传?Docker 跑个 File Browser,浏览器就能管理
服务器·docker·开源
火车叼位1 天前
写给初级开发者:SSL、SSH、HTTPS 与证书体系全解析
运维
vivo互联网技术1 天前
从 10 分钟到 1 秒:ES 深度分页任意跳页的三轮优化实战
服务器·数据库·redis·elasticsearch·深度分页
用户805533698031 天前
Input 子系统架构:Core、Handler、Driver 三层是怎么协作的
linux·嵌入式