itop-3568开发板驱动学习笔记(17)内核中断

news2024/12/27 12:40:27

《【北京迅为】itop-3568开发板驱动开发指南.pdf》 学习笔记

文章目录

  • 中断基础
    • 中断
    • 中断上下文
    • 中断号
    • 中断源类型
  • 内核中断 API
    • 获取中断号
    • 中断申请
    • 释放中断
    • 禁止中断
    • 使能中断
  • 实验程序

中断基础

中断

CPU 在正常运行期间,由外部或者内部引起的事件,让 CPU 停下当前正在运行的程序,转而去执行触发他中断的对应程序,处理完中断对应程序后再回来继续运行。这就是中断。

中断上下文

虽然中断可以提高 CPU 的运行效率,但中断会打断内核进程的正常调度和运行,所以为了保证系统的实时性,中断服务程序必须足够短。但实际应用中,我们可能需要在中断后执行一些比较耗时的任务,为此,内核提出了中断上下文的概念,即把中断服务程序分为两部分,中断上文和中断下文。

中断上文用来完成比较紧急且耗时短的任务,中断下文用来处理比较耗时的任务。

中断号

中断号(IRQ number)也叫软中断号,在 Linux 系统中是唯一的,也是我们在中断编程中需要用到的中断号。

中断源类型

  • SGI(Software-generated interrupt):范围0 - 15,软件触发的中断,一般用于核间通讯
  • PPI(Private peripheral interrupt ): 范围16 - 31,私有外设中断,只对指定的core有效
  • SPI(Shared peripheral interrupt):范围32 - 1019,共享中断,不限定特定的core

内核中断 API

获取中断号

操作内核中断,我们需要使用到中断号,gpio_to_irq() 可以将 GPIO 编号转换为中断号,该函数原型如下:

int gpio_to_irq(unsigned gpio);

中断申请

内核中 request_irq() 函数被用来申请中断,该函数原型如下:

#include <linux/interrupt.h>
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
const char *name, void *dev);

函数功能:向内核注册一个中断服务函数(当 irq 对应的中断发生时,会执行 handler 指向的中断服务函数)。

中断服务函数原型为:typedef irqreturn_t (*irq_handler_t)(int, void *)

函数参数

  • irq 中断号(在内核中是唯一的)
  • handler 中断服务函数指针
  • flags 中断标志,具体内容由中断源决定,如果中断源为外部中断,则存在上升沿和下降沿两种标志
  • name 中断名(会在 /proc/interrupts 下体现)
  • dev 中断服务函数的参数

flags 可取值可以在 linux/interrupt.h 头文件查看,本文将用到标志有 IRQF_TRIGGER_RISING 和 IRQF_TRIGGER_FALLING。

当 flags 指定为共享中断(IRQF_SHARED)时,dev 参数不能为 NULL,并且不同的共享中断 dev 参数不能相同,因为共享中断可以注册多个中断函数,中断号相同,所以需要根据 dev 来区分不同的中断函数。


返回值
返回 0 表示申请成功,失败返回负值。

释放中断

free_irq() 用来注销中断,函数原型为 :

void free_irq(unsigned int irq, void *dev_id);

参数与 request_irq() 的部分参数意义相同,这里不再赘述。

【注意】在调用 free_irq() 时,为了防止此时中断被触发,需要先禁止中断。

禁止中断

禁止内核中断的函数包括:

void disable_irq_nosync(unsigned int irq);
void disable_irq(unsigned int irq);

disable_irq() 在调用后不会立刻返回,需要等待中断程序执行完才返回,所以在中断服务函数中不能调用该函数。

disable_irq_nosync() 则会在调用后立刻返回。

使能中断

函数原型:

void enable_irq(unsigned int irq);

实验程序

迅为教学视频里用触摸屏所用的中断 IO 作为外部中断实验的 IO,在实验之前,需要将触摸屏驱动关闭。具体操作步骤为:进入内核根目录,输入 make ARCH=arm64 menucofig,关闭 Device Driver -> Input device support -> Touchscreens 下的 FT5x06 触摸屏驱动:

在这里插入图片描述

修改完成后,用 .config 替换平台默认的配置文件(参考 rk3568 相关文档),然后编译内核,最后将内核烧录到开发板上。

我们要操作触摸屏中断脚,首先要知道中断脚的 IO,根据原理图得知其 IO 为 GPIO3_A5,

在这里插入图片描述

在驱动中,gpio 都是通过编号表示的,那么 GPIO3_A5 的编号是多少呢?这个问题在之前的点灯实验中已经提及:

到网上找资料发现,RK3568 的 GPIO 编号很好计算,以 GPIO0_B7 为例,其 bank 为 0,group 为 1(A 为 0,以此类推),X 为 7,那么它的 pin 编号为 bank * 32 + group * 8 + X = 15,直白点讲,GPIO 的编号就是它在所有 IO 中所属序号

根据上面的公式, GPIO3_A5 的编号为 3 * 32 + 0 * 8 + 5 = 101

实验源码

下面是一个简单的中断驱动代码(参考原文/视频):

#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>

int irq;

//中断服务函数
irqreturn_t my_interrupt(int irq, void *args)
{
	printk("my interrupt handler.\n");	
	return IRQ_RETVAL(IRQ_HANDLED);
}

static int interrupt_irq_init(void)
{
	int ret = 0;
	
	// 获取中断号
	irq = gpio_to_irq(101);
	printk("irq is %d\n", irq);

	// 申请中断
	ret = request_irq(irq, my_interrupt, IRQF_TRIGGER_RISING, "inttrupt_test", NULL);
	if(ret < 0)
	{
		printk("request irq error.\n");
		return 0;
	}

	return 0;	
}

static void interrupt_irq_exit(void)
{
	printk("interrupt irq exit.\n");
	// 注销中断
	free_irq(irq, NULL);
}

module_init(interrupt_irq_init);
module_exit(interrupt_irq_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("xiaohui");

Makefile 文件:

#目标文件,与驱动源文件同名,编译成模块
obj-m := interrupt.o

#架构平台选择
export ARCH=arm64

#编译器选择
export CROSS_COMPILE=aarch64-linux-gnu-

#内核目录
KDIR := /home/topeet/Linux/rk356x_linux/kernel/

#编译模块
all:
	make -C $(KDIR) M=$(shell pwd) modules
	
#清除编译文件
clean:
	make -C $(KDIR) M=$(shell pwd) clean

实验结果

触碰触摸屏时,中断触发,运行中断服务函数(打印数据到串口终端)。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

研报精选230411

目录 【行业230411华安证券】智能家居行业深度&#xff1a;ChatGPT等大模型催化智能家居行业进一步发展【行业230411信达证券】食品饮料行业2023年第12周周报&#xff1a;从当前时间点看今年液奶的投资机会【行业230411东方财富证券】食品饮料行业专题研究&#xff1a;BC两端需…

2023年信息安全推荐证书

随着网络安全行业的不断升温&#xff0c;相关的认证数量也不断增加&#xff0c;对于在网络安全行业发展的人才来说&#xff0c;提升职业竞争力最有效的办法之一&#xff0c;就是取得权威认证。 那么如何从繁多的适合网络安全从业者的证书中选择含金量高、发展潜力大的证书&…

Java分布式事务(七)

文章目录 🔥Seata提供XA模式实现分布式事务_业务说明🔥Seata提供XA模式实现分布式事务_下载启动Seata服务🔥Seata提供XA模式实现分布式事务_搭建聚合父工程构建🔥Seata提供XA模式实现分布式事务_转账功能实现上🔥Seata提供XA模式实现分布式事务_转账功能实现下🔥Se…

什么是车规级芯片?

目录 1、AEC-Q系列标准 2、ISO26262功能安全标准 芯片按照应用场景&#xff0c;通常可以分为消费级、工业级、车规级和军工级四个等级&#xff0c;其要求依次为&#xff1a;军工>车规>工业>消费。 车规级芯片&#xff0c;顾名思义&#xff0c;是应用到汽车中的芯片…

GMP调度

目录 A1 基础 协程 映射关系 N:1关系 1:1关系 M:N关系 概念 G M P go协程 GM模型 GMP模型 设计策略 复用线程 并行利用 抢占 全局G队列 "go func()"调度过程 ​编辑 特殊的M0和G0 M0 G0 Go调度器执行过程全解析 场景1 场景2 场景3 场景…

栈实现学生信息管理(C语言)

文章目录Stack.hmain.cStack.c用栈实现学生信息管理。这里放一下有哪些文件。Stack.h #pragma once防止库函数的重复引用&#xff0c;因为库函数会在预编译的时候在程序中展开&#xff0c;会增大程序的体积。   通过typedef对数据重命名&#xff0c;之后需要修改数据就十分方…

C/C++|物联网开发入门+项目实战|C语言基础|玩转c代码---从输入输出开始-学习笔记(6)

文章目录玩转c代码---从输入输出开始参考教程&#xff1a;C语言编程:一本全面的C语言入门教程&#xff08;第3版)第16章需要掌握的内容需要了解的内容常见的人机交互接口串口的输入输出PC常用的几个输入输出函数示例代码3 printf函数使用难点分析A.格式控制字符串的基本形式:示…

【毕业论文】| 基于Unity3D引擎的冒险游戏的设计与实现

&#x1f4e2;博客主页&#xff1a;肩匣与橘 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由肩匣与橘编写&#xff0c;首发于CSDN&#x1f649; &#x1f4e2;生活依旧是美好而又温柔的&#xff0c;你也…

NVIDIA CUDA核函数编写注意事项之In-place

CUDA系列文章目录 文章目录CUDA系列文章目录前言总结参考资料前言 CUDA&#xff08;Compute Unified Device Architecture&#xff0c;统一计算架构&#xff09;是由NVIDIA所推出的一种集成技术&#xff0c;是其对于GPGPU&#xff08;A General-Purpose Graphics Processing U…

【源码解析】JDK 动态代理实现

基本流程 主方法 在该方法中&#xff0c;我们呈现了在日常使用 JDK 动态代理机制的方法。 public class VehicleDynamicProxy { /** * 被代理对象 */ public Vehicle targetVehicle; public VehicleDynamicProxy(Vehicle targetVehicle) { this.targetVehicle target…

注册中心要集成 SpringCloud实现负载均衡,需要哪些接口和规范?

前几天有个大兄弟问了我一个问题&#xff0c;注册中心要集成SpringCloud&#xff0c;想实现SpringCloud的负载均衡&#xff0c;需要实现哪些接口和规范。 既然这个兄弟问到我了&#xff0c;而我又刚好知道&#xff0c;这不得好好写一篇文章来回答这个问题&#xff0c;虽然在后面…

Omniverse Extensions Command 写在其他.py 文件内 导致找不到Command 无法运行 不生效 的解决方案

提要&#xff1a; Command扩展不在extension.py内 例如我的Command&#xff1a;ScatterCreatePointInstancerCommandLJ 在 commands.py 内 然后使用时报错&#xff1a; 2023-04-10 18:16:11 [Error] [omni.kit.commands.command] Cant execute command: "ScatterCreat…

基于springboot和ajax的简单项目 05 日志界面的查找功能

01.这个是基于input标签的查找功能。 02.修改更新table标签的函数&#xff0c;把username这个参数&#xff0c;加到getjson函数的params中&#xff0c;实现依靠username来查询数据。 var username$("#searchNameId").val();//如下语句的含义是什么&#xff1f;动态在…

STM32F4_PWM输出详解

目录 1. PWM简介 2. PWM原理 3. 定时器PWM输出比较 4. 定时器PWM捕获/比较通道 5. PWM输出相关寄存器 5.1 捕获/比较模式寄存器 TIMx_CCMR1 5.2 捕获/比较使能寄存器 TIMx_CCER 5.3 捕获/比较寄存器 TIMx_CCR1~4 5.4 刹车(断路)和死区寄存器 TIMx_BDTR 6. 库函数配置…

【Python_Scrapy学习笔记(一)】Scrapy框架简介

Scrapy框架简介 前言 Scrapy 框架是一个用 python 实现的为了爬取网站数据、提取数据的应用框架&#xff0c;使用 Twisted 异步网络库来处理网络通讯&#xff0c;可以高效的完成数据爬取。本文主要介绍 Scrapy 框架的构成与工作原理。 正文 1、Scrapy安装 Windows安装&…

【Unity UPR】造个获取深度法线纹理的轮子

描边需要深度法线纹理的加持&#xff0c;效果才能达到最好&#xff0c;但URP下很多版本不支持直接获取_CameraNormalsTexture&#xff0c;而我本人也尝试了一下在12.1.7下偷懒直接拿SSAO里的Depth Normal图&#xff0c; 虽然也能实现吧&#xff0c;但是需要打开SSAO的同时&…

商务接待广州考斯特商务租车详解!

进入四月份以来&#xff0c;全国各个地区都有很多商务活动举办&#xff0c;广州也不例外&#xff0c;广州很多地区都有商务活动的需求。因此不少主办方都需要商务租车来接待客户&#xff0c;而丰田考斯特是市面上常见的一款高端中巴车&#xff0c;主要是因为考斯特的可靠性、安…

【软件设计师13】数据库设计

数据库设计 1. 数据库设计过程 2. E-R模型 3. E-R图向关系模型的转换 例如一对一联系&#xff0c;可以将联系单独做为关系模式&#xff0c;也可以存放到任意一个实体中 而一对多要合并只能合并到多这边&#xff0c;不能存放到1 多对多则联系必须单独转成一个关系模式 4. 案…

赛狐ERP | 亚马逊选品方法与策略详解:如何挑选最优质的产品?

亚马逊作为全球电商巨头&#xff0c;其产品种类之丰富也是无人能及。然而&#xff0c;在如此繁杂的商品体系下&#xff0c;如何选品成为了摆在商家面前的一道难题。本文将从亚马逊选品的目标、方法、策略三个方面进行详细介绍。 一、选品的目标 在进行选择之前&#xff0c;必…

【C语言】位运算 {位运算的应用 :关闭位,判断位,打开位,转置位;位域}

一、基础 参与位运算的对象只能是整型数据(int, unsigned, char)&#xff0c;不能为实型 移位操作符 按位左移n位表示&#xff1a;原数*2^n按位右移n位表示&#xff1a;原数/2^n&#xff08;整除&#xff09;上述运算只适用于左右移位时被溢出舍弃的位不包含1的情况 二、位运…