ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

给驱动添加sysfs设备模型(基于中断的按键程序)

2021-05-12 15:03:17  阅读:201  来源: 互联网

标签:__ struct sysfs platform 添加 myled gpiod 按键 include


linux kernel version:4.4.38

硬件平台:exynos4412-tiny4412

参考链接:https://www.cnblogs.com/ethandlwang/p/14759735.html

基于上一篇按键点灯程序,我给设备驱动添加了sysfs设备模型,demo级程序

添加了myled_status文件在用户空间获取灯的状态~

  1 #include <linux/err.h>
  2 #include <linux/gpio.h>
  3 #include <linux/fs.h>
  4 #include <linux/gpio/consumer.h>
  5 #include <linux/kernel.h>
  6 #include <linux/leds.h>
  7 #include <linux/module.h>
  8 #include <linux/of.h>
  9 #include <linux/of_gpio.h>
 10 #include <linux/of_irq.h>
 11 #include <linux/platform_device.h>
 12 #include <linux/property.h>
 13 #include <linux/slab.h>
 14 #include <linux/workqueue.h>
 15 #include <linux/interrupt.h>
 16 #include <linux/acpi.h>
 17 
 18 static struct gpio_desc    *gpiod;
 19 
 20 static ssize_t myled_status_show(struct device *dev,
 21                      struct device_attribute *attr, char *buf)
 22 {
 23     int level = gpiod_get_value(gpiod);
 24     printk(KERN_ALERT "%s %d level=%d\n", __FUNCTION__, __LINE__, level);
 25     return 0;
 26 
 27 }
 28 
 29 static ssize_t myled_status_store(struct device *dev,
 30                    struct device_attribute *attr,
 31                    const char *buf, size_t len)
 32 {
 33     printk(KERN_ALERT "%s %d buf=%s len=%d\n", __FUNCTION__, __LINE__, buf, len);
 34     int level = 1;
 35 
 36     if(len >= 2){
 37         if(buf[0] == '0'){
 38             level = 0;
 39         } 
 40     }
 41     gpiod_set_value(gpiod, level);
 42     return len;
 43 }
 44 
 45 static DEVICE_ATTR_RW(myled_status);
 46 
 47 static struct attribute* myled_status_attrs[] = {
 48     &dev_attr_myled_status.attr,
 49     NULL
 50 };
 51 
 52 static const struct attribute_group myled_group = {
 53     .attrs        = myled_status_attrs,
 54 };
 55 
 56 static irqreturn_t my_irq(int irqno, void *dev_id)
 57 {
 58     int level = gpiod_get_value(gpiod);
 59     printk(KERN_ALERT "%s %d irqno=%d level=%d\n", __FUNCTION__, __LINE__, irqno, level);
 60     gpiod_set_value(gpiod, !level);
 61     return IRQ_HANDLED;
 62 }
 63 
 64 static int hello_probe(struct platform_device *pdev)
 65 {
 66     int error = 0;
 67     struct fwnode_handle *fwhandle;
 68     const char *str;
 69     u32 val[3];
 70     u32 interrupts_val[2];
 71     unsigned int irq;
 72     int ret;
 73 
 74     struct device_node* np = pdev->dev.of_node;
 75     if(np == NULL)
 76     {
 77         printk(KERN_ALERT "%s %d of_node is NULL\n", __FUNCTION__, __LINE__);
 78         return 0;
 79     }
 80 
 81 
 82     irq = platform_get_irq(pdev, 0);
 83     printk(KERN_ALERT "%s %d irq = %d\n", __FUNCTION__, __LINE__, irq);
 84     ret = devm_request_irq(&pdev->dev, irq, my_irq, 0, dev_name(&pdev->dev), NULL);
 85     printk(KERN_ALERT "%s %d ret = %d\n", __FUNCTION__, __LINE__, ret);
 86 
 87     gpiod = devm_gpiod_get_optional(&pdev->dev, "key1", GPIOD_OUT_LOW);
 88     if(gpiod == NULL){
 89         printk(KERN_ALERT "%s %d devm_gpiod_get_optional fail!!!\n", __FUNCTION__, __LINE__);
 90     }
 91  
 92     ret = sysfs_create_group(&pdev->dev.kobj, &myled_group);
 93     if(ret)
 94     {
 95         printk(KERN_ALERT "%s %d sysfs_create_group fail!!!\n", __FUNCTION__, __LINE__);
 96         return 1;
 97     }
 98 
 99     printk(KERN_ALERT "%s %d success===\n", __FUNCTION__, __LINE__);
100     return error;
101 }
102 
103 static int hello_remove(struct platform_device *pdev)
104 {
105     sysfs_remove_group(&pdev->dev.kobj,&myled_group);
106 
107     printk(KERN_ALERT "%s %d success===\n", __FUNCTION__, __LINE__);
108 
109     return 0;
110 
111 }
112 
113 static void hello_shutdown(struct platform_device *pdev)
114 {
115     printk(KERN_ALERT "%s %d success===\n", __FUNCTION__, __LINE__);
116 
117 }
118 
119 static struct of_device_id of_platform_hello_match[] = {
120     { .compatible = "interrupt-keys",},
121     { },
122 };
123 MODULE_DEVICE_TABLE(of, of_platform_hello_match);
124 
125 static struct platform_driver platform_hello_driver = {
126     .probe        = hello_probe,
127     .remove        = hello_remove,
128     .shutdown    = hello_shutdown,
129     .driver        = {
130         .name    = "my_keys",
131         //.owner  = THIS_MODULE,
132         .of_match_table = of_platform_hello_match,
133     },
134 };
135 
136 module_platform_driver(platform_hello_driver);
137 
138 MODULE_AUTHOR("EthanDL");
139 MODULE_DESCRIPTION("platform hello");
140 MODULE_LICENSE("GPL");

92行:向sysfs添加myled_status文件,所在目录/sys/devices/platform/my_keys/,因为my_keys是platform device,所以my_keys就会在/sys/devices/platform/下,sysfs_create_group的第一个参数kobj对应的正好是my_keys,所以myled_status是在my_keys下

20&29行:myled_status_show和myled_status_store,对应myled_status的读写,实现查看和控制led的亮灭~

标签:__,struct,sysfs,platform,添加,myled,gpiod,按键,include
来源: https://www.cnblogs.com/ethandlwang/p/14759724.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有