☰
SR501驱动代码
2026/10/15 21:28:02 网站建设 项目流程

设备树节点

可以查看一下设备树中其他节点是如何写的(100ask_imx6ull-14x14.dts)

先简单的写一个sr501设备节点

sr501{ compatible = "100ask,sr501"; gpios = <&gpio4 19 GPIO_ACTIVE_HIGH>; };

关于如何设置gpio属性,可以通过grep来查找

grep "gpio4" * -nrw | grep imx6ull

基础框架

#include <linux/module.h> #include <linux/poll.h> #include <linux/fs.h> #include <linux/errno.h> #include <linux/miscdevice.h> #include <linux/kernel.h> #include <linux/major.h> #include <linux/mutex.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <linux/stat.h> #include <linux/init.h> #include <linux/device.h> #include <linux/tty.h> #include <linux/kmod.h> #include <linux/gfp.h> #include <linux/gpio/consumer.h> #include <linux/platform_device.h> #include <linux/of_gpio.h> #include <linux/of_irq.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/slab.h> #include <linux/fcntl.h> #include <linux/timer.h> #include <linux/workqueue.h> #include <asm/current.h> static ssize_t sr501_drv_read(struct file *file, char __user *buf, size_t size, loff_t *offset) { return 0; } static unsighed int sr501_drv_poll (struct file *fp, poll_table * wait) { return 0; } static struct file_operation sr501_drv = { .owner = THIS_MODULE, .read = sr501_drv_read, .poll = sr501_drv_poll, }; static irqreturn_t sr501_isr(int irq, void *dev_id) { return IRQ_WAKE_THREAD; } static int sr501_probe(struct platform_device *pdev) { printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__); return 0; } static int sr501_remove(struct platform_device *pdev) { printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__); return 0; } static const struct of_device_id ask100_sr501[] = { { .compatible = "100ask,sr501" }, {}, } static struct platform_driver sr501_driver = { .probe = sr501_probe, .remove = sr501_remove, .driver = { .name = "100ask_sr501", .of_match_table = ask100_sr501, } } static int __init sr501_init(void) { int err; printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__); err = platform_driver_register(&sr501s_driver); return err; } static void __eixt sr501_exit(void) { printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__); platform_driver_unregister(&sr501s_driver); } module_init(sr501_init); module_exit(sr501_exit); MODULE_LICENSE("GPL");

上机实验

编译设备树

export ARCH=arm export CROSS_COMPILE=arm-buildroot-linux-gnueabihf- export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin make dtbs

编译.c文件,并将两个文件传到开发板上去并且安装驱动,通过dmesg来查看

简易代码

#include <linux/module.h> #include <linux/poll.h> #include <linux/fs.h> #include <linux/errno.h> #include <linux/miscdevice.h> #include <linux/kernel.h> #include <linux/major.h> #include <linux/mutex.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <linux/stat.h> #include <linux/init.h> #include <linux/device.h> #include <linux/tty.h> #include <linux/kmod.h> #include <linux/gfp.h> #include <linux/gpio/consumer.h> #include <linux/platform_device.h> #include <linux/of_gpio.h> #include <linux/of_irq.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/slab.h> #include <linux/fcntl.h> #include <linux/timer.h> #include <linux/workqueue.h> #include <asm/current.h> static int major; static struct class *sr501_class; static wait_queue_head_t sr501_wq; static struct gpio_desc *sr501_gpio; static int irq; static int sr501_data = 0; static ssize_t sr501_drv_read(struct file *file, char __user *buf, size_t size, loff_t *offset) { printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__); int len = (size) < 4? size : 4; wait_event_interruptible(sr501_wq, sr501_data); copy_to_user(buf, &sr501_data, len); sr501_data = 0; return len; } static unsigned int sr501_drv_poll (struct file *fp, poll_table * wait) { return 0; } // file_operations结构体 static struct file_operations sr501_fops = { .owner = THIS_MODULE, .read = sr501_drv_read, .poll = sr501_drv_poll, }; //中断处理函数 static irqreturn_t sr501_isr(int irq, void *dev_id) { printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__); int val = gpiod_get_value(sr501_gpio); sr501_data = 0x80 | val; wake_up(&sr501_wq); return IRQ_HANDLED; } /* 1. 从platform_device获得GPIO * 2. gpio=>irq * 3. request_irq */ static int sr501_probe(struct platform_device *pdev) { //gpio sr501_gpio = gpiod_get(&pdev->dev, NULL, 0); gpiod_direction_input(sr501_gpio); irq = gpiod_to_irq(sr501_gpio); request_irq(irq, sr501_isr, IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, "sr501", NULL); device_create(sr501_class, NULL, MKDEV(major, 0), NULL, "/dev/sr501"); return 0; } //remove释放获得的资源 static int sr501_remove(struct platform_device *pdev) { device_destroy(sr501_class, MKDEV(major, 0)); free_irq(irq, NULL); gpiod_put(sr501_gpio); return 0; } //match tabel static const struct of_device_id ask100_sr501[] = { {.compatible = "100ask,sr501"}, { }, }; // platform_driver结构体 static struct platform_driver sr501s_driver = { .probe = sr501_probe, .remove = sr501_remove, .driver = { .name = "100ask_sr501", .of_match_table = ask100_sr501, }, }; //init中注册file_operation、platform_driver,初始化等待队列用于中断 static int __init sr501_init(void) { int err; printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__); //注册file_operation结构体 major = register_chrdev(0, "sr501", &sr501_fops); sr501_class = class_create(THIS_MODULE, "sr501_class"); if(IS_ERR(sr501_class)) { printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__); unregister_chrdev(major, "sr501"); return PTR_ERR(sr501_class); } //初始化等待队列(用于中断) init_waitqueue_head(&sr501_wq); err = platform_driver_register(&sr501s_driver); return err; } //释放获得的资源 static void __exit sr501_exit(void) { printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__); platform_driver_unregister(&sr501s_driver); class_destroy(sr501_class); unregister_chrdev(major, "sr501"); } module_init(sr501_init); module_exit(sr501_exit); MODULE_LICENSE("GPL");

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询