平台设备驱动之gpio子系统(写驱动实现在/sys/...目录下用echo命令点灯)

ops/2025/2/27 9:15:29/
linux__driver_0">1、 关键函数(include/linux 及 driver目录下)
module_platform_driver(leds_drv);   //平台设备驱动入口//获取匹配成功后设备树节点中的 propertyof_get_named_gpio_flags(node, "led_gpio", 0, &flags);  //在/sys/目录下创建文件供操作,第一个参数相当于设备地址,第二个是待创建的与设备对应的文件名sysfs_create_file(&dev->kobj, &gpio_attr[i].attr);   	// 用于向文件写数据											gpio_direction_output(gpio_dev_pointer->led_gpio, gpio_dev_pointer->led_gpio_output); //用于读取文件数据gpio_get_value(gpio_dev_pointer->smoke_sensor_gpio); 
2、驱动完整代码
#include <linux/init.h>                        
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/err.h>#include <linux/of_gpio.h>
#include <linux/gpio.h>#include <linux/platform_device.h>
#include <asm/io.h>#include <dt-bindings/gpio/gpio.h>#ifdef CONFIG_OF
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#endifstruct gpio_dev{struct platform_device *pdev;int led_gpio;int led_gpio_output;int smoke_sensor_gpio;
};struct gpio_dev * gpio_dev_pointer = NULL;static ssize_t led_store(struct device *dev, struct device_attribute *attr,const char *buf, size_t count) {//写文件,控制 gpio 输出 ( echo 1 >   led_gpio)                if (buf[0] == '0') {gpio_dev_pointer->led_gpio_output = 0;gpio_direction_output(gpio_dev_pointer->led_gpio, gpio_dev_pointer->led_gpio_output);}else if (buf[0] == '1') {gpio_dev_pointer->led_gpio_output = 1;gpio_direction_output(gpio_dev_pointer->led_gpio, gpio_dev_pointer->led_gpio_output);}    printk(KERN_ERR "led_gpio_store %c \n",gpio_dev_pointer->led_gpio_output);   return count;
}static ssize_t smoke_sensor_show(struct device *dev, struct device_attribute *attr,char *buf){  int sensor_value = 0;sensor_value = gpio_get_value(gpio_dev_pointer->smoke_sensor_gpio);//cat smoke_sensor_gpio时会触发return snprintf(buf, PAGE_SIZE, "%d\n",sensor_value);
}static struct device_attribute gpio_attr[] = {  __ATTR(led_gpio, 0664, NULL, led_store), //写:关联属性文件的写回调函数(*store)  echo时触发__ATTR(smoke_sensor_gpio, 0664, smoke_sensor_show,NULL), //读:关联属性文件的读回调函数(*show)  cat 时触发
};static int gpio_init_sysfs(struct device *dev)
{int i, ret;for(i = 0; i < ARRAY_SIZE(gpio_attr); i++){ret = sysfs_create_file(&dev->kobj, &gpio_attr[i].attr);if(ret){dev_err(dev, "create charger node(%s) error\n",gpio_attr[i].attr.name);return -1;}			}return 0;
}static int gpio_remove_sysfs(struct device *dev)
{int i;for(i = 0; i < ARRAY_SIZE(gpio_attr); i++){sysfs_remove_file(&dev->kobj, &gpio_attr[i].attr);}return 0;
}static int get_OF_node_property(struct gpio_dev *pdata){int gpio;int ret;enum of_gpio_flags flags;struct device *dev = &pdata->pdev->dev;struct device_node *node = dev->of_node;gpio = of_get_named_gpio_flags(node, "led_gpio", 0, &flags);if(gpio_is_valid(gpio)){pdata->led_gpio = gpio;pdata->led_gpio_output = (flags == GPIO_ACTIVE_HIGH)?1:0;printk(KERN_ERR"led_gpio: %d\n", pdata->led_gpio);ret = devm_gpio_request(dev,gpio,"led_gpio");if(ret){printk("Failed to get led_gpio gpio.\n");return -1;}}gpio = of_get_named_gpio_flags(node, "smoke_sensor_gpio", 0, &flags);if (gpio_is_valid(gpio)){pdata->smoke_sensor_gpio        = gpio;printk(KERN_ERR"smoke_sensor_gpio: %d\n", pdata->smoke_sensor_gpio);ret = devm_gpio_request(dev,gpio, "smoke_sensor_gpio");if (ret) {printk("Failed to get smoke_sensor_gpio gpio.\n");return -1;}ret = gpio_direction_input(gpio);if (ret) {printk("Failed to set flame_sensor_gpio gpio.\n");return -1;}}return 0;}static void gpio_set_default(struct gpio_dev *pdata) {if (pdata->led_gpio) {gpio_direction_output(pdata->led_gpio, pdata->led_gpio_output);}
}int leds_probe(struct platform_device *pdev)
{int  ret = 0;printk(KERN_ALERT "%s \n",__func__);      gpio_dev_pointer = kmalloc(sizeof(struct gpio_dev), GFP_KERNEL);//为结构体指针申请空间if (gpio_dev_pointer == NULL) {printk(KERN_ERR"kmalloc struct gpio_dev err \n");return -ENOMEM;}memset(gpio_dev_pointer, 0, sizeof(struct gpio_dev)); //初始化结构体gpio_dev_pointer->pdev = pdev;ret = get_OF_node_property(gpio_dev_pointer);if(ret<0){printk(KERN_ERR"gpio_dt err \n");	return -1;}gpio_set_default(gpio_dev_pointer);ret = gpio_init_sysfs(&gpio_dev_pointer->pdev->dev);if(ret<0){printk(KERN_ERR"gpio_init_sysfs  err \n");	return -1;}printk(KERN_ALERT "%s  ok !!\n",__func__);return 0;}int leds_remove(struct platform_device *pdev)
{   gpio_remove_sysfs(&gpio_dev_pointer->pdev->dev);kfree(gpio_dev_pointer);printk("leds_remove ok\n");   return 0;
}static const struct of_device_id of_led_match[] = {{ .compatible = "sys_rw_led_sensor", },{},
};MODULE_DEVICE_TABLE(of, of_led_match);struct platform_driver leds_drv = {.driver = {.owner = THIS_MODULE,.name = "sys_rw_led driver" ,.of_match_table = of_led_match,},.probe = leds_probe,.remove = leds_remove,    
};
module_platform_driver(leds_drv);
MODULE_LICENSE("GPL");
3、测试代码
$ insmod gpio.ko
$ cd /sys/devices/sys_rw_gpio
$ echo 0 > led_gpio  //关灯
$ echo 1 > led_gpio  //亮灯	
$ cat smoke_sensor_gpio  //读管脚输入电平,默认读到0,用杜邦线,把它接到前面亮灯的管脚时,能成功读到1
4、验证结果

在这里插入图片描述


http://www.ppmy.cn/ops/161635.html

相关文章

WebGPU驱动的下一代Web图形引擎:突破浏览器计算性能瓶颈

引言&#xff1a;浏览器图形计算的效能革命 Epic Games首次在浏览器端实现虚幻引擎5核心模块&#xff0c;通过WebGPU将Lumen全局光照的渲染耗时从WebGL的896ms降至47ms。在512核GPU并行测试中&#xff0c;WebGPU的通用计算性能较WebGL Compute Shader提升65倍。基于此技术&…

在Linux桌面上创建Idea启动快捷方式

1、在桌面新建idea.desktop vim idea.desktop [Desktop Entry] EncodingUTF-8 NameIntelliJ IDEA CommentIntelliJ IDEA Exec/home/software/idea-2021/bin/idea.sh Icon/home/software/idea-2021/bin/idea.svg Terminalfalse TypeApplication CategoriesApplication;Developm…

一种结合IR UWB和FMCW雷达的新型毫米精密UWB测距系统

&#xff08;看到北京大学发了一篇结合UWB和FMCW结合的接收机&#xff0c;将PN序列和chirp调制在一起&#xff0c;实现了毫米级测距精度&#xff0c;后面有机会尝试仿真下看看。&#xff09; 摘要 本文提出了一种新型的具有毫米级精度的超宽带&#xff08;UWB&#xff09;测距…

一文读懂 DeepSeek:AI 领域的新力量

在人工智能飞速发展的今天&#xff0c;新的技术和模型不断涌现。DeepSeek 作为其中的佼佼者&#xff0c;备受关注。本文将为你详细介绍 DeepSeek 是什么&#xff0c;以及它有什么用。 DeepSeek 是什么 DeepSeek&#xff08;全称杭州深度求索人工智能基础技术研究有限公司 &am…

Windows系统编程项目(一)进程管理器

本项目将通过MFC实现一个进程管理器&#xff0c;如下图详细信息页所示&#xff1a; 一.首先创建一个基于对话框的MFC项目&#xff0c;在静态库中使用MFC 二.在项目默认的对话框中添加一个列表 三.列表添加变量 四.初始化列表 1.设置列表风格和表头 2.填充列表内容 我们需要在…

跟着AI学vue第十二章

第十二章&#xff1a;技术引领与社区共建 在熟练掌握Vue开发技能&#xff0c;并将其与前沿技术融合应用后&#xff0c; 第十二章是一个更具使命感与影响力的阶段&#xff0c;着重于引领技术发展方向和为社区贡献力量。 1. 推动Vue技术创新与实践 探索前沿技术融合&#xff1…

html css js网页制作成品——HTML+CSS甜品店网页设计(5页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…

关于25考研复试,有哪些需要注意的?

随着2025年考研初试成绩的陆续公布&#xff0c;无数考研人的心情也随之起伏~ 而出分之后&#xff0c;就要开始考虑复试&#xff0c;那么复试考什么&#xff1f;流程如何安排&#xff1f;迎接毕业季后续规划又该如何制定&#xff1f;如何在面试中展现最佳状态&#xff0c;避免不…