当前位置: 首页 > news >正文

嵌入式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 

相关文章:

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

嵌入式Linux应用开发-基础知识-第十八章系统对中断的处理③ 第十八章 Linux系统对中断的处理 ③18.5 编写使用中断的按键驱动程序 ③18.5.1 编程思路18.5.1.1 设备树相关18.5.1.2 驱动代码相关 18.5.2 先编写驱动程序18.5.2.1 从设备树获得 GPIO18.5.2.2 从 GPIO获得中断号18.5…...

【Python】返回指定时间对应的时间戳

使用模块datetime&#xff0c;附赠一个没啥用的“时间推算”功能(获取n天后对应的时间 代码&#xff1a; import datetimedef GetTimestamp(year,month,day,hour,minute,second,*,relativeNone,timezoneNone):#返回指定时间戳。指定relative时进行时间推算"""根…...

微服务moleculer03

1. Moleculer 目前支持SQLite&#xff0c;MySQL&#xff0c;MariaDB&#xff0c;PostgreSQL&#xff0c;MSSQL等数据库&#xff0c;这里以mysql为例 2. package.json 增加mysql依赖 "mysql2": "^2.3.3", "sequelize": "^6.21.3", &q…...

[React] react-router-dom的v5和v6

v5 版本既兼容了类组件&#xff08;react v16.8前&#xff09;&#xff0c;又兼容了函数组件&#xff08;react v16.8及以后&#xff0c;即hook&#xff09;。v6 文档把路由组件默认接受的三个属性给移除了&#xff0c;若仍然使用 this.props.history.push()&#xff0c;此时pr…...

Linux命令(91)之mv

linux命令之mv 1.mv介绍 linux命令mv是用来移动文件或目录&#xff0c;并且也可以用来更改文件或目录的名字 2.mv用法 mv [参数] src dest mv常用参数 参数说明-f强制移动&#xff0c;不提示 3.实例 3.1.重命名文件1.txt为ztj.txt 命令&#xff1a; mv 1.txt ztj.txt …...

C++ 强制类型转换(int double)、查看数据类型、自动决定类型、三元表达式、取反、

强制类型转换&#xff08; int 与 double&#xff09; #include <iostream> using namespace std;int main() {// 数据类型转换char c1;short s1;int n 1;long l 1;float f 1;double d 1;int p 0;int cc (int)c;// 注意&#xff1a;字符 转 整形时 是有问题的// “…...

Android自动化测试之MonkeyRunner--从环境构建、参数讲解、脚本制作到实战技巧

monkeyrunner 概述、环境搭建 monkeyrunner环境搭建 (1) JDK的安装不配置 http://www.oracle.com/technetwork/java/javase/downloads/index.html (2) 安装Python编译器 https://www.python.org/download/ (3) 设置环境变量(配置Monkeyrunner工具至path目彔下也可丌配置) (4) …...

Neural Insights for Digital Marketing Content Design 阅读笔记

KDD-2023 很值得读的文章&#xff01; 1 摘要 电商里&#xff0c;营销内容的实验&#xff0c;很重要。 然而&#xff0c;创作营销内容是一个手动和耗时的过程&#xff0c;缺乏明确的指导原则。 本文通过 基于历史数据的AI驱动的可行性洞察&#xff0c;来弥补 营销内容创作 和…...

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

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

中间件中使用到的设计模式

本文记录阅读源码的过程中&#xff0c;了解/学习到中间件使用到的设计模式及具体运用的组件/功能点 1. 策略模式 1. Nacos2.x中grpc处理时通过请求type来进行具体Handler映射&#xff0c;找到对应处理器。 2. 模板模式 1. Nacos配置数据读取&#xff0c;内部数据源、外部数据…...

运用动态内存实现通讯录(增删查改+排序)

目录 前言&#xff1a; 实现通讯录&#xff1a; 1.创建和调用菜单&#xff1a; 2.创建联系人信息和通讯录&#xff1a; 3.初始化通讯录&#xff1a; 4.增加联系人&#xff1a; 5.显示联系人&#xff1a; 6.删除联系人&#xff1a; ​编辑 7.查找联系人&#xff1a; ​…...

基于Cplex的人员排班问题建模求解(JavaAPI)

使用Java调用Cplex实现了阿里mindopt求解器的案例&#xff08;https://opt.aliyun.com/platform/case&#xff09;人员排班问题。 这里写目录标题 人员排班问题问题描述数学建模编程求解&#xff08;CplexJavaAPI&#xff09;求解结果 人员排班问题 随着现在产业的发展&#…...

理解Go中的数据类型

引言 数据类型指定了编写程序时特定变量存储的值的类型。数据类型还决定了可以对数据执行哪些操作。 在本文中&#xff0c;我们将介绍Go的重要数据类型。这不是对数据类型的详尽研究&#xff0c;但将帮助您熟悉Go中可用的选项。理解一些基本的数据类型能让你写出更清晰、性能…...

【人工智能导论】线性回归模型

一、线性回归模型概述 线性回归是利用函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析。简单来说&#xff0c;就是试图找到自变量与因变量之间的关系。 二、线性回归案例&#xff1a;房价预测 1、案例分析 问题&#xff1a;现在要预测140平方的房屋的价格&…...

十大常见排序算法详解(附Java代码实现和代码解析)

文章目录 十大排序算法⛅前言&#x1f331;1、排序概述&#x1f334;2、排序的实现&#x1f335;2.1 插入排序&#x1f433;2.1.1 直接插入排序算法介绍算法实现 &#x1f433;2.1.2 希尔排序算法介绍算法实现 &#x1f335;2.2 选择排序&#x1f433;2.2.1 选择排序算法介绍算…...

在Ubuntu上通过Portainer部署微服务项目

这篇文章主要记录自己在ubuntu上部署自己的微服务应用的过程&#xff0c;文章中使用了docker、docker-compose和portainer&#xff0c;在部署过程中遇到了不少问题&#xff0c;因为博主也是初学docker-compose&#xff0c;通过这次部署实战确实有所收获&#xff0c;在这篇文章一…...

软件测试基础学习

注意&#xff1a; 各位同学们&#xff0c;今年本人求职目前遇到的情况大体是这样了&#xff0c;开发太卷&#xff0c;学历高的话优势非常的大&#xff0c;公司会根据实际情况考虑是否值得培养&#xff08;哪怕技术差一点&#xff09;&#xff1b;学历稍微低一些但是技术熟练的…...

移动手机截图,读取图片尺寸

这个代码的设计初衷是为了解决图片处理过程中的一些痛点。想象一下&#xff0c;我们都曾遇到过这样的情况&#xff1a;相机拍摄出来的照片、网络下载的图片&#xff0c;尺寸五花八门&#xff0c;大小不一。而我们又渴望将它们整理成一套拥有统一尺寸的图片&#xff0c;让它们更…...

服务器应用程序不可用的原因是什么引起的

服务器应用程序不可用的原因是什么引起的 服务器应用程序不可用的原因是什么引起的?其实服务器应用程序不可用可能是由多种原因引起的。主要包括软件故障、网络问题、硬件故障、安全问题、配置错误、容量不足、数据库问题等&#xff0c;具体详细服务器应用程序不可用的原因如下…...

使用SPY++查看窗口信息去排查客户端UI软件问题

目录 1、使用SPY++查看窗口的信息 2、使用SPY++查看某些软件UI窗口用什么UI组件实现的...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...