驱动框架7——使用gpiolib完成led驱动
以下内容源于朱有鹏《物联网大讲堂》课程的学习整理,如有侵权,请告知删除。
十四、使用gpiolib完成led驱动
1、流程分析
(1)第1步:使用gpio_request申请要使用的一个GPIO;
(2)第2步:gpio_direction_input/gpio_direction_output 设置输入/输出模式;
(3)第3步:设置输出值gpio_set_value 获取IO口值gpio_get_value。
2、代码实践
(1)在led1上编写代码测试通过;
(2)扩展支持led2和led3、led4,可以分开注册,也可以使用gpio_request_array去一次注册;
(3)学习linux中查看gpio使用情况的方法
- 内核中提供了虚拟文件系统debugfs,里面有一个gpio文件,提供了gpio的使用信息(诸如谁被使用了,谁没有被使用)。
- 使用方法:mount -t debugfs debugfs /tmp,然后cat /tmp/gpio即可得到gpio的所有信息,使用完后umount /tmp卸载掉debugfs
(4)代码(驱动申请LED1资源而已)
#include <linux/module.h> // module_init module_exit
#include <linux/init.h> // __init __exit
#include <linux/fs.h>
#include <linux/leds.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-bank.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <mach/gpio.h>#define GPIO_LED1 S5PV210_GPJ0(3)
#define GPIO_LED2 S5PV210_GPJ0(4)
#define GPIO_LED3 S5PV210_GPJ0(5)#define X210_LED_OFF 1 // X210中LED是正极接电源,负极节GPIO
#define X210_LED_ON 0 // 所以1是灭,0是亮static struct led_classdev mydev1; // 定义结构体变量
static struct led_classdev mydev2; // 定义结构体变量
static struct led_classdev mydev3; // 定义结构体变量// 这个函数就是要去完成具体的硬件读写任务的
static void s5pv210_led1_set(struct led_classdev *led_cdev,enum led_brightness value)
{printk(KERN_INFO "s5pv210_led1_set\n");//writel(0x11111111, GPJ0CON);// 在这里根据用户设置的值来操作硬件// 用户设置的值就是valueif (value == LED_OFF){// 用户给了个0,希望LED灭//writel(0x11111111, GPJ0CON);// 读改写三部曲//writel((readl(GPJ0DAT) | (1<<3)), GPJ0DAT);gpio_set_value(GPIO_LED1, X210_LED_OFF);}else{// 用户给的是非0,希望LED亮//writel(0x11111111, GPJ0CON);//writel((readl(GPJ0DAT) & ~(1<<3)), GPJ0DAT);gpio_set_value(GPIO_LED1, X210_LED_ON);}
}static void s5pv210_led2_set(struct led_classdev *led_cdev,enum led_brightness value)
{printk(KERN_INFO "s5pv2102_led_set\n");//writel(0x11111111, GPJ0CON);// 在这里根据用户设置的值来操作硬件// 用户设置的值就是valueif (value == LED_OFF){// 用户给了个0,希望LED灭//writel(0x11111111, GPJ0CON);// 读改写三部曲//writel((readl(GPJ0DAT) | (1<<4)), GPJ0DAT);}else{// 用户给的是非0,希望LED亮//writel(0x11111111, GPJ0CON);//writel((readl(GPJ0DAT) & ~(1<<4)), GPJ0DAT);}
}static void s5pv210_led3_set(struct led_classdev *led_cdev,enum led_brightness value)
{printk(KERN_INFO "s5pv210_led3_set\n");//writel(0x11111111, GPJ0CON);// 在这里根据用户设置的值来操作硬件// 用户设置的值就是valueif (value == LED_OFF){// 用户给了个0,希望LED灭//writel(0x11111111, GPJ0CON);// 读改写三部曲//writel((readl(GPJ0DAT) | (1<<5)), GPJ0DAT);}else{// 用户给的是非0,希望LED亮//writel(0x11111111, GPJ0CON);//writel((readl(GPJ0DAT) & ~(1<<5)), GPJ0DAT);}
}static int __init s5pv210_led_init(void)
{// 用户insmod安装驱动模块时会调用该函数// 该函数的主要任务就是去使用led驱动框架提供的设备注册函数来注册一个设备int ret = -1;// 在这里去申请驱动用到的各种资源,当前驱动中就是GPIO资源if (gpio_request(GPIO_LED1, "led1_gpj0.3")) //这里是申请失败{printk(KERN_ERR "gpio_request failed\n");} else //申请成功后{// 设置为输出模式,并且默认输出1让LED灯灭gpio_direction_output(GPIO_LED1, 1);}// led1mydev1.name = "led1";mydev1.brightness = 0; mydev1.brightness_set = s5pv210_led1_set;ret = led_classdev_register(NULL, &mydev1);if (ret < 0) {printk(KERN_ERR "led_classdev_register failed\n");return ret;}// led2mydev2.name = "led2";mydev2.brightness = 0; mydev2.brightness_set = s5pv210_led2_set;ret = led_classdev_register(NULL, &mydev2);if (ret < 0) {printk(KERN_ERR "led_classdev_register failed\n");return ret;}// led3mydev3.name = "led3";mydev3.brightness = 0; mydev3.brightness_set = s5pv210_led3_set;ret = led_classdev_register(NULL, &mydev3);if (ret < 0) {printk(KERN_ERR "led_classdev_register failed\n");return ret;}return 0;
}static void __exit s5pv210_led_exit(void)
{led_classdev_unregister(&mydev1);led_classdev_unregister(&mydev2);led_classdev_unregister(&mydev3);gpio_free(GPIO_LED1);
}module_init(s5pv210_led_init);
module_exit(s5pv210_led_exit);// MODULE_xxx这种宏作用是用来添加模块描述信息
MODULE_LICENSE("GPL"); // 描述模块的许可证
MODULE_AUTHOR("aston <1264671872@qq.com>"); // 描述模块的作者
MODULE_DESCRIPTION("s5pv210 led driver"); // 描述模块的介绍信息
MODULE_ALIAS("s5pv210_led"); // 描述模块的别名信息
驱动框架7——使用gpiolib完成led驱动相关推荐
- STM32MP157驱动开发——设备树下的LED驱动
STM32MP157驱动开发--设备树下的LED驱动 主要内容:将之前章节中使用新设备设备驱动编写的LED驱动改成设备树形式 文章目录 STM32MP157驱动开发--设备树下的LED驱动 一.主要步 ...
- rmmod无法卸载驱动_从hello world到LED驱动
引言 linux驱动是连接软件和硬件的一个中间介质,实现了对硬件的配置和控制.进一步将硬件抽象化,为软件操作硬件提供了简单的接口.不论硬件的具体形式如何,linux驱动都将其映射到一个文件,软件端对硬 ...
- 从零开始学习linux的I2C设备驱动框架——写一个简单的SHT20驱动
目录 0.测试环境说明 1.设备树的修改 2.设备驱动框架 3.I2C数据传输过程 3.1 struct i2c_msg 3.2 SHT20的数据收发 4.I2C适配器超时等待时间的修改 本文资源 参 ...
- I.MX6ULL ARM驱动开发---设备树下的LED驱动实验
一.什么是设备树? 设备树(Device Tree),将这个词分开就是"设备"和"树",描述设备树的文件叫做 DTS(Device Tree Source) ...
- Linux驱动编程篇(三)——LED驱动(一)简单LED驱动
一.LED驱动程序的实现目标及流程图 1.打开LED 2.关闭LED 二.LED驱动程序的实现部分 1.内核层LED驱动程序 2.应用层LED测试程序 三.内核层LED驱动程序的编程步骤 1.添加头文 ...
- [Android驱动] 高通 Q PNP Flash LED驱动 及上层调用的流程
直白的记录一下,翻译的文件来自kernel: kernel/documentation/devicetree/bindings/leds/leds-qpnp-flash.txt ----------- ...
- 驱动框架入门之LED-linux驱动开发第4部分-朱有鹏-专题视频课程
驱动框架入门之LED-linux驱动开发第4部分-5199人已学习 课程介绍 本课程是linux驱动开发的第4个课程,主要内容是驱动框架的引入.通过led驱动框架和gpiolib的这两 ...
- 4.驱动框架入门之LED
1.何谓驱动框架 1.1.驱动是谁写的 (1)驱动开发工程师 (2)内核维护者 1.2.驱动编程协作要求 (1)接口标准化 (2)尽量降低驱动开发者难度 1.3.到底什么是驱动框架 (1)内核中驱动部 ...
- 驱动学习之LED驱动框架
一:什么是驱动框架 (1)内核中驱动部分维护者针对每个种类的驱动设计一套成熟的.标准的.典型的驱动实现,然后把不同厂家的同类硬件驱动中相同的部分抽出来自己实现好,再把不同部分留出接口给具体的驱动开 ...
最新文章
- redisson的锁的类型_绝对干货:利用redisson完成分布式锁功能
- 《大话数据结构》读书笔记-线性表
- oracle夜未眠之一增删改查
- 使用C#快速生成二维码 | 真正跨平台方案
- 京东软件测试有复试没,【京东测试工程师面试】正常,不是特别的难-看准网...
- 判断手机机型和浏览器内核
- 95-230-026-源码-WordCount走读-本地运行SubmitJob的过程
- QThread的用法:开启与退出
- 【POJ2155】Matrix(二维区间修改+单点查询---二维树状数组)
- c语言编程创意表白,C语言和图形界面编程打造——浪漫的表白程序
- 如何将CAD格式转成可以编辑的矢量图
- 【每周论文阅读-第四周】proposal-level 特征聚合视频目标检测方法01
- python xlsxwriter 画图_python xlsxwriter创建excel图表的方法
- [已迁移]pwn-buu-VMpwn-[OGeek2019 Final]OVM
- script type=text/JavaScript是什么
- 卢克的HTML与CSS基础
- 秦刚推荐:做流量的本质就是做用户
- 【手把手教安装】VM16 Pro安装Win10!!!
- iOS weak和assign修饰OC对象的区别
- MongoDB副本集的部署与操作
热门文章
- Silverlight Blend动画设计系列八:拖放(Drag-Drop)操作与拖放行为(DragBehavior)
- end to end testing
- ASP.NET MVC中controller和view相互传值的方式
- 台北到淡水版Firefox无法播放视频
- HDU 1217 Arbitrage (Floyd + SPFA判环)
- 实验 使用 vivado zedboard GPIO 开关 开控制 LED
- 设计模式之开放封闭原则
- hadoop-09-安装资源上传
- Java Map 怎样实现Key 的唯一性?
- linux下安装oracle 11g R2