嵌入式Linux应用开发-基础知识-第十八章系统对中断的处理③

嵌入式Linux应用开发-基础知识-第十八章系统对中断的处理③

  • 第十八章 Linux系统对中断的处理 ③
    • 18.5 编写使用中断的按键驱动程序 ③
      • 18.5.1 编程思路
        • 18.5.1.1 设备树相关
        • 18.5.1.2 驱动代码相关
      • 18.5.2 先编写驱动程序
        • 18.5.2.1 从设备树获得 GPIO
        • 18.5.2.2 从 GPIO获得中断号
        • 18.5.2.3 申请中断
        • 18.5.2.4 中断函数
    • 18.6 IMX6ULL设备树修改及上机实验
      • 18.6.1 查看原理图确定按键引脚
      • 18.6.2 修改设备树
      • 18.6.3 上机实验

第十八章 Linux系统对中断的处理 ③

在这里插入图片描述

18.5 编写使用中断的按键驱动程序 ③

写在前面的话:对于 GPIO按键,我们并不需要去写驱动程序,使用内核自带的驱动程序drivers/input/keyboard/gpio_keys.c就可以,然后你需要做的只是修改设备树指定引脚及键值。
但是我还是要教你怎么从头写按键驱动,特别是如何使用中断。因为中断是引入其他基础知识的前提,后面要讲的这些内容都离不开中断:休眠-唤醒、POLL机制、异步通知、定时器、中断的线程化处理。
这些基础知识是更复杂的驱动程序的基础要素,以后的复杂驱动也就是对硬件操作的封装彼此不同,但是用到的基础编程知识是一样的。

18.5.1 编程思路

18.5.1.1 设备树相关

查看原理图确定按键使用的引脚,再在设备树中添加节点,在节点里指定中断信息。
例子:

gpio_keys_xxxxxx { compatible = "xxxxxx,gpio_key"; gpios = <&gpio5 1 GPIO_ACTIVE_HIGH &gpio4 14 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&key1_pinctrl &key2_pinctrl>; 
}; 
18.5.1.2 驱动代码相关

首先要获得中断号,参考上面《18.4.3 在代码中获得中断》;
然后编写中断处理函数;
最后 request_irq。

18.5.2 先编写驱动程序

参考:内核源码 drivers/input/keyboard/gpio_keys.c
使用 GIT命令载后,源码 gpio_key_drv.c位于这个目录下: 01_all_series_quickstart\
05_嵌入式 Linux驱动开发基础知识\source\
06_gpio_irq\
01_simple\

18.5.2.1 从设备树获得 GPIO
count = of_gpio_count(node); 
for (i = 0; i < count; i++) gpio_keys_xxxxxx[i].gpio = of_get_gpio_flags(node, i, &flag); 
18.5.2.2 从 GPIO获得中断号
gpio_keys_xxxxxx[i].irq  = gpio_to_irq(gpio_keys_xxxxxx[i].gpio); 
18.5.2.3 申请中断
err = request_irq(gpio_keys_xxxxxx[i].irq, gpio_key_isr, \  
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "xxxxxx_gpio_key", &gpio_keys_xxxxxx[i]); 
18.5.2.4 中断函数
static irqreturn_t gpio_key_isr(int irq, void *dev_id) 
{ struct gpio_key *gpio_key = dev_id; int val; val = gpiod_get_value(gpio_key->gpiod); } 
printk("key %d %d\n", gpio_key->gpio, val); return IRQ_HANDLED; 

18.6 IMX6ULL设备树修改及上机实验

本实验的内核版本:

https://e.coding.net/weidongshan/imx-linux4.9.88 commit 6020a20c1277c6b511e5673eecd8523e376031c8 

18.6.1 查看原理图确定按键引脚

在这里插入图片描述

18.6.2 修改设备树

对于一个引脚要用作中断时,
a. 要通过 PinCtrl把它设置为 GPIO功能;
b. 表明自身:是哪一个 GPIO模块里的哪一个引脚
运行 NXP提供的图形化设备树配置工具“i.MX Pins Tool v6”,点击左侧选中 GPIO5_IO01、GPIO4_IO14,如下图所示:
在这里插入图片描述

按上图右侧去修改设备树 arch/arm/boot/dts/xxxxxx_imx6ull-14x14.dts,修改结果放 GIT中。

使用 GIT命令载后,源码“修改后 xxxxxx_imx6ull-14x14.dts” 位于这个目录下(使用之前要改名为
“xxxxxx_imx6ull-14x14.dts”并上传到内核的 arch/arm/boot/dts目录):

01_all_series_quickstart\ 
05_嵌入式 Linux驱动开发基础知识\source\ 
06_gpio_irq\ 01_simple\ device_tree\ 

主要内容摘录如下:
GPIO5_IO01的 pinctrl定义:

&iomuxc_snvs { pinctrl-names = "default_snvs"; pinctrl-0 = <&pinctrl_hog_2>; imx6ul-evk { key1_xxxxxx: key1_xxxxxx{    /*!< Function assigned for the core: Cortex-A7[ca7] */             fsl,pins = < MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01        0x000110A0 >; }; 
GPIO4_IO14的 pinctrl定义: 
&iomuxc { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hog_1>; imx6ul-evk { key2_xxxxxx: key2_xxxxxx{  /*!< Function assigned for the core: Cortex-A7[ca7] */             fsl,pins = < MX6UL_PAD_NAND_CE1_B__GPIO4_IO14           0x000010B0 >; }; 
定义这 2个按键的节点: 
gpio_keys_xxxxxx { compatible = "xxxxxx,gpio_key"; gpios = <&gpio5 1 GPIO_ACTIVE_HIGH &gpio4 14 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&key1_xxxxxx &key2_xxxxxx>; }; 

把原来的 GPIO按键节点禁止掉:

gpio-keys { compatible = "gpio-keys"; pinctrl-names = "default"; status = "disabled";    // 这句是新加的 

18.6.3 上机实验

实验步骤如下:

  1. 编译设备树,把 xxxxxx_imx6ull-14x14.dtb放到板子的/boot目录,重启开发板。
  2. 编译驱动程序,安装驱动程序,操作按键。
    大概命令列出如下:
// 1. 在电脑上设置工具链 
export ARCH=arm 
export CROSS_COMPILE=arm-linux-gnueabihf- 
export PATH=$PATH:/home/book/xxxxxx_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin 
// 2. 进入内核目录后执行: 
make dtbs   // 生成 arch/arm/boot/dts/xxxxxx_imx6ull-14x14.dtb,请把它放到板子的/boot目录 
// 3. 编译驱动: 先进入驱动程序目录,执行 make即可,把生成的 gpio_key_drv.ko放到开发板上 
// 4. 重启开发板后,在板子上执行: 
echo "7 4 1 7" > /proc/sys/kernel/printk insmod gpio_key_drv.ko 
// 5. 按下、松开按键,可以看到输出信息: [   48.396584] key 110 0 
[   48.569403] key 110 1 
[   49.321805] key 129 0 
[   49.498734] key 129 1 

参考资料
中断处理不能嵌套:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e58aa3d2d0cc
genirq: add threaded interrupt handler support
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3aa551c9b4c40018f0e261a178e3d25478dc04a9
Linux RT(2)-硬实时 Linux(RT-Preempt Patch)的中断线程化 https://www.veryarm.com/110619.html
Linux中断管理 (1)Linux中断管理机制
https://www.cnblogs.com/arnoldlu/p/8659981.html

Breakpoint 1, gpio_keys_gpio_isr (irq=200, dev_id=0x863e6930) at drivers/input/keyboard/gpio_keys.c:393 
393 { 
(gdb) bt 
#0  gpio_keys_gpio_isr (irq=200, dev_id=0x863e6930) at drivers/input/keyboard/gpio_keys.c:393 
#1  0x80270528 in __handle_irq_event_percpu (desc=0x8616e300, flags=0x86517edc) at kernel/irq/handle.c:145 
#2  0x802705cc in handle_irq_event_percpu (desc=0x8616e300) at kernel/irq/handle.c:185 
#3  0x80270640 in handle_irq_event (desc=0x8616e300) at kernel/irq/handle.c:202 
#4  0x802738e8 in handle_level_irq (desc=0x8616e300) at kernel/irq/chip.c:518 
#5  0x8026f7f8 in generic_handle_irq_desc (desc=<optimized out>) at ./include/linux/irqdesc.h:150 
#6  generic_handle_irq (irq=<optimized out>) at kernel/irq/irqdesc.c:590 
#7  0x805005e0 in mxc_gpio_irq_handler (port=0xc8, irq_stat=2252237104) at drivers/gpio/gpio-mxc.c:274 
#8  0x805006fc in mx3_gpio_irq_handler (desc=<optimized out>) at drivers/gpio/gpio-mxc.c:291 
#9  0x8026f7f8 in generic_handle_irq_desc (desc=<optimized out>) at ./include/linux/irqdesc.h:150 
#10 generic_handle_irq (irq=<optimized out>) at kernel/irq/irqdesc.c:590 
#11 0x8026fd0c in __handle_domain_irq (domain=0x86006000, hwirq=32, lookup=true, regs=0x86517fb0) at kernel/irq/irqdesc.c:627 
#12 0x80201484 in handle_domain_irq (regs=<optimized out>, hwirq=<optimized out>, domain=<optimized out>) at ./include/linux/irqdesc.h:168 
#13 gic_handle_irq (regs=0xc8) at drivers/irqchip/irq-gic.c:364 
#14 0x8020b704 in __irq_usr () at arch/arm/kernel/entry-armv.S:464 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/146158.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis Cluster集群运维与核心原理剖析

文章目录 Redis集群方案比较哨兵模式高可用集群模式 Redis高可用集群搭建Java操作redis集群Redis集群原理分析槽位定位算法跳转重定位Redis集群节点间的通信机制集中式gossipgossip通信的10000端口 网络抖动Redis集群选举原理分析集群脑裂数据丢失问题集群是否完整才能对外提供…

Node18.x基础使用总结(二)

Node18.x基础使用总结 1、Node.js模块化1.1、模块暴露数据1.2、引入模块 2、包管理工具2.1、npm2.2、npm的安装2.3、npm基本使用2.4、搜索包2.5、下载安装包2.6、生产环境与开发环境2.7、生产依赖与开发依赖2.8、全局安装2.9、修改windows执行策略2.10、安装包依赖2.11、安装指…

深入了解 Linux 中的 AWK 命令:文本处理的瑞士军刀

简介 在Linux和Unix操作系统中&#xff0c;文本处理是一个常见的任务。AWK命令是一个强大的文本处理工具&#xff0c;专门进行文本截取和分析&#xff0c;它允许你在文本文件中查找、过滤、处理和格式化数据。本文将深入介绍Linux中的AWK命令&#xff0c;让你了解其基本用法和…

【多线程进阶】常见的锁策略

文章目录 前言1. 乐观锁 vs 悲观锁2. 轻量级锁 vs 重量级锁3. 自旋锁 vs 挂起等待锁4. 读写锁 vs 互斥锁5. 公平锁 vs 非公平锁6. 可重入锁 vs 不可重入锁总结 前言 本章节所讲解的锁策略不仅仅是局限于 Java . 任何和 “锁” 相关的话题, 都可能会涉及到以下内容. 这些特性主…

如何初始化一个vue项目

如何初始化一个vue项目 安装 vue-cli 后 ,终端执行 vue ui npm install vue-cli --save-devCLI 服务 | Vue CLI (vuejs.org) 等一段时间后 。。。 进入项目仪表盘 设置其他模块 项目构建后目录 vue.config.js 文件相关配置 官方vue.config.js 参考文档 https://cli.vuejs.o…

Linux基础指令(六)

目录 前言1. man 指令2. date 指令3. cal 指令4. bc 指令5. uname 指令结语&#xff1a; 前言 欢迎各位伙伴来到学习 Linux 指令的 第六天&#xff01;&#xff01;&#xff01; 在上一篇文章 Linux基本指令(五) 中&#xff0c;我们通过一段故事线&#xff0c;带大家感性的了…

BI神器Power Query(26)-- 使用PQ实现表格多列转换(2/3)

实例需求&#xff1a;原始表格包含多列属性数据,现在需要将不同属性分列展示在不同的行中&#xff0c;att1、att3、att5为一组&#xff0c;att2、att3、att6为另一组&#xff0c;数据如下所示。 更新表格数据 原始数据表&#xff1a; Col1Col2Att1Att2Att3Att4Att5Att6AAADD…

通过containerd部署k8s集群环境及初始化时部分报错解决

目录 一.基础环境配置&#xff08;每个节点都做&#xff09; 1.hosts解析 2.防火墙和selinux 3.安装基本软件并配置时间同步 4.禁用swap分区 5.更改内核参数 6.配置ipvs 7.k8s下载 &#xff08;1&#xff09;配置镜像下载相关软件 &#xff08;2&#xff09;配置kube…

8.3Jmeter使用json提取器提取数组值并循环(循环控制器)遍历使用

Jmeter使用json提取器提取数组值并循环遍历使用 响应返回值例如&#xff1a; {"code":0,"data":{"totalCount":11,"pageSize":100,"totalPage":1,"currPage":1,"list":[{"structuredId":&q…

nodejs+vue健身服务应用elementui

第三章 系统分析 10 3.1需求分析 10 3.2可行性分析 10 3.2.1技术可行性&#xff1a;技术背景 10 3.2.2经济可行性 11 3.2.3操作可行性&#xff1a; 11 3.3性能分析 11 3.4系统操作流程 12 3.4.1管理员登录流程 12 3.4.2信息添加流程 12 3.4.3信息删除流程 13 第四章 系统设计与…

使用docker完成minio服务部署扩容备份迁移生产实践文档

一、minio服务扩容方案 当服务器存储空间不足的时候&#xff0c;需要进行扩容&#xff0c;扩容过程中需要短暂停机时间&#xff0c;预计在一小时内能够完成和恢复 统一注意事项 强烈建议为部署中的所有节点选择基本相似的硬件配置。确保硬件&#xff08;CPU、内存、主板、存…

什么是物联网智慧公厕?

在当今科技快速发展的背景下&#xff0c;具备全感知、可靠传输、智能处理三大特点的物联网技术&#xff0c;正逐渐渗透到各个领域。而智慧公厕作为其中的一个创新应用&#xff0c;正逐渐受到市场的关注和重视。 什么是物联网智慧公厕&#xff1f;物联网智慧公厕是指通过物联网…

SmartX 边缘计算解决方案:简单稳定,支持各类应用负载

在《一文了解近端边缘 IT 基础架构技术需求》文章中&#xff0c;我们为大家分析了边缘应用对 IT 基础架构的技术要求&#xff0c;以及为什么超融合架构是支持边缘场景的最佳选择。值得一提的是&#xff0c;IDC 近日发布的《中国软件定义存储&#xff08;SDS&#xff09;及超融合…

Eclipse 主网即将上线迎空投预期,Zepoch 节点或成受益者?

目前&#xff0c;Zepoch节点空投页面中&#xff0c;模块化Layer2 Rollup项目Eclipse出现在其空投列表中。 配合近期Eclipse宣布了其将由SVM提供支持的Layer2主网架构&#xff0c;并将在今年年底上线主网的消息后&#xff0c;不免引发两点猜测&#xff1a;一个是Eclipse或将在不…

【数据代理+事件处理+计算属性与监视+绑定样式+条件渲染】

数据代理事件处理计算属性与监视绑定样式条件渲染 1 数据代理1.1 回顾Object.defineProperty方法1.2 数据代理 2 事件处理2.1 绑定监听2.2 事件修饰符2.3 键盘事件 3 计算属性与监视3.1 计算属性3.2 监视属性(侦视属性)3.3 watch对比computed 4 绑定样式4.1 绑定class样式4.2 绑…

[尚硅谷React笔记]——第2章 React面向组件编程

目录&#xff1a; 基本理解和使用&#xff1a; 使用React开发者工具调试函数式组件复习类的基本知识类式组件组件三大核心属性1: state 复习类中方法this指向&#xff1a; 复习bind函数&#xff1a;解决changeWeather中this指向问题&#xff1a;一般写法&#xff1a;state.htm…

进程之间的通信方式(共享存储,消息传递,管道通信)

进程通信 进程间通信&#xff08;Inter-Process Communication&#xff0c;IPC&#xff09;是指两个进程之间产生数据交互。进程是分配系统资源的单位(包括内存地址空间)&#xff0c;因此各进程拥有的内存地址空间相互独立。为了保证安全&#xff0c;一个进程不能直接访问另一…

前端开发和后端开发的一些建议

前端开发和后端开发是Web开发的两个方向 前端开发主要负责实现用户在浏览器上看到的界面和交互体验&#xff0c;包括HTML、CSS和JavaScript等技术。后端开发主要负责处理服务器端的逻辑和数据&#xff0c;包括数据库操作、服务器配置和接口开发等技术。 前端开发 前端开发需…

Python-Flask:编写自动化连接demo脚本:v1.0.0

主函数&#xff1a; # _*_ Coding : UTF-8 _*_ # Time : 13:14 # Author : YYZ # File : Flask # Project : Python_Project_爬虫 import jsonfrom flask import Flask,request,jsonify import sshapi Flask(__name__)# methods: 指定请求方式 接口解析参数host host_info[…

产品经理如何科学的进行需求调研?

导语&#xff1a;作为产品经理&#xff0c;需求调研是开展工作的重要环节之一。科学、有效地进行需求调研不仅可以帮助产品经理更好地了解用户需求&#xff0c;还能指导产品设计和功能开发&#xff0c;提升产品的竞争力。本文将介绍几种科学的方法和技巧&#xff0c;帮助产品经…