RK3568外部IO中断示例

外部IO中断介绍

本篇文章以万象奥科HD-RK3568-IOT评估板中GPIO30为例,介绍Linux内核中断的注册方法,使用中断的方式检测GPIO30是否出现上升沿信号。中断在linux、设备驱动开发里使用的都非常多,可以更加实时的检测GPIO30的状态。

Linux 内核提供了中断的注册接口:

  1. 注册中断

头文件 include\linux\interrupt.h

定义文件 include\linux\interrupt.h

函数原型 int request_irq(unsigned int irq, /* 做实参传递给中断服务函数第1个参数 */

Irq_handler_t handler, /* 中断服务函数指针 */

unsigned long flags,

const char *name,

void *dev_id); /* 做实参传递给中断服务函数第2个参数 */

函数功能: 向内核注册一个中断服务函数;

当发生中断号为irq的中断时,会执行handler指针函数。

函数参数:

irq: 中断编号(每个中断有唯一的编号)。

handler: 中断服务函数指针。

原型 typedef irqreturn_t(*irq_handler_t)(int, void *)。

flag: 中断的标志,用来描述本中断的基本特征的。

有固定的值,由中断源的特征决定;

比如外中断有: 上升沿,下降沿触发中断这类标志。

name: 中断名字,注册后会出现cat /proc/interrupts

dev_id: 这个参数是传递给中断服务函数。

对共享中断来说,这个参数一定有要;

当注销共享中断中的其中一个时,用这个标识要注销哪一个。

对于有唯一入口的中断,可以传递NULL;

但是一般来说都会传递一个有意义指针,在中断程序中使用,以方便编程。

返回值 0 标识成功

-EINVAL (无效参数22) 表示中断号无效。

-EBUSY (设备或者资源忙16) 表示中断已经被占用。

2) 注销中断

void free_irq(unsigned int irq, void *dev_id)

irq: 要注销的中断号

dev_id: 其实就是注册时需要使用的dev参数,在共享中断必不可少,不能传递NULL。

注意:为防止在注销时同时发生中断,调用时候,先禁掉中断。

3 中断开启与关闭

禁止中断:

void disable_irq_nosync(unsigned int irq);

void disable_irq(unsigned int irq);

参数: irq,要禁止的中断对应的编号。

注意:在中断服务程序中不能使用disable_irq这个函数,否则内核崩溃,可以使用disable_irq_nosync,

disable_irq: 函数调用后,函数不会马上返回,而等待中断程序执行完成才返回,在中断调用会导致死锁。

使能中断:

void enable_irq(unsigned int irq);

参数: irq, 要使能的中断对应的编号。

4) 获取irq 中断号

Int gpio_to_irq(unsigned int irq);

参数: irq,要使能的中断对应的编号

外部IO中断驱动编写

  1. IO原理图

图 2.1 GPIO0_D6

GPIO0_D6=0*32+(4-1)-8+6=30

    1. 驱动示例代码

#include <linux/init.h>

#include <linux/module.h>

#include <linux/gpio.h>

#include <linux/interrupt.h>

#include <linux/timer.h>

#define GPIO_PIN 30 // 替换为你的GPIO引脚

static unsigned int irq_number;

// GPIO中断处理函数

static irqreturn_t gpio_irq_handler(int irq, void *dev_id) {

printk("GPIO中断触发!\n");

return IRQ_HANDLED;

}

static int __init mymodule_init(void) {

int ret;

// 请求GPIO

ret = gpio_request(GPIO_PIN, "my_gpio");

if (ret) {

printk("无法请求GPIO %d\n", GPIO_PIN);

return ret;

}

// 配置GPIO引脚为输入

ret = gpio_direction_input(GPIO_PIN);

if (ret) {

printk("无法配置GPIO %d 为输入\n", GPIO_PIN);

gpio_free(GPIO_PIN);

return ret;

}

// 请求GPIO中断

irq_number = gpio_to_irq(GPIO_PIN);

ret = request_irq(irq_number, gpio_irq_handler, IRQF_TRIGGER_RISING, "my_gpio_irq", NULL);

/* IRQF_TRIGGER_RISING 上升沿有效 */

if (ret) {

printk("无法请求GPIO中断 %d\n", irq_number);

gpio_free(GPIO_PIN);

return ret;

}

printk("模块加载成功\n");

return 0;

}

static void __exit mymodule_exit(void) {

// 释放GPIO中断

free_irq(irq_number, NULL);

// 释放GPIO

gpio_free(GPIO_PIN);

printk("模块卸载成功\n");

}

module_init(mymodule_init);

module_exit(mymodule_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("zou");

MODULE_DESCRIPTION("Sample GPIO and Timer Interrupt Kernel Module");

外部IO中断验证

将驱动编译成模块,insmod加载模块后。 由于驱动检测GPIO0_D6上升沿有效,当给该引脚提供高电平时,会触发中断执行中断处理函数。

图3.1 触发IO中断

相关推荐
森G3 小时前
2一、u-boot下载编译
linux·arm开发
GilgameshJSS8 小时前
STM32H743-ARM例程23-USB_HID
arm开发·stm32·嵌入式硬件
半夏微凉半夏殇10 小时前
除了arm 还有那些开源的芯片架构
arm开发·架构·开源
XINVRY-FPGA11 小时前
XC7A100T-2FGG484I Xilinx Artix-7 FPGA
arm开发·嵌入式硬件·fpga开发·硬件工程·信息与通信·信号处理·fpga
文火冰糖的硅基工坊1 天前
[嵌入式系统-123]:中高端图形处理器RM Mali-G610 MP4 GPU 是 ARM 公司推出的基于 Valhall 架构 的移动 GPU
arm开发·ai·架构·嵌入式·gpu
武文斌772 天前
项目学习总结:CAN总线、摄像头、STM32概述
linux·arm开发·stm32·单片机·嵌入式硬件·学习·c#
roshy3 天前
x86、arm、rsc-v指令集架构,指令集、OS、应用3者的关系
java·arm开发·架构
szxinmai主板定制专家3 天前
基于ARM+FPGA的无人机数据采集卡,6通道24bit采集
arm开发·嵌入式硬件·fpga开发·无人机·能源
czhaii4 天前
KEIL 同时安装C51 C251 ARM &Link D USB 2UART
arm开发
ShiMetaPi4 天前
操作【GM3568JHF】FPGA+ARM异构开发板 使用指南:音频接口
arm开发·嵌入式硬件·fpga开发·rk3568