首页 > 其他分享 >RK3568外部IO中断示例

RK3568外部IO中断示例

时间:2023-11-03 14:46:07浏览次数:30  
标签:gpio 示例 中断 RK3568 ret int IO irq GPIO

1. 外部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_thandler,  /* 中断服务函数指针 */

                                            unsignedlong flags,

                                            constchar *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中断开启与关闭

       禁止中断:

voiddisable_irq_nosync(unsigned int irq);

voiddisable_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,要使能的中断对应的编号

2. 外部IO中断驱动编写

2.1       IO原理图

1.png

图2.1 GPIO0_D6

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

2.2       驱动示例代码

#include<linux/init.h>

#include<linux/module.h>

#include<linux/gpio.h>

#include<linux/interrupt.h>

#include<linux/timer.h>

 

#defineGPIO_PIN 30  // 替换为你的GPIO引脚

 

staticunsigned int irq_number;

 

//GPIO中断处理函数

staticirqreturn_t gpio_irq_handler(int irq, void *dev_id) {

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

    return IRQ_HANDLED;

}

staticint __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;

}

staticvoid __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("SampleGPIO and Timer Interrupt Kernel Module");

3. 外部IO中断验证

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

 

2.png

图3.1触发IO中断

 

标签:gpio,示例,中断,RK3568,ret,int,IO,irq,GPIO
From: https://www.cnblogs.com/vanxoak/p/17807544.html

相关文章

  • 分布式锁【Redission】
    一、简介    Redission,一个基于Redis实现的分布式工具,为Redis官网分布式解决方案。    Redisson提供了使用Redis的最简单和最便捷的方法。Redisson的宗旨是促进使用者对Redis的关注分离(SeparationofConcern),从而让使用者能够将精力更集中地放在处理业务逻辑......
  • 手把手教你写一个 IOC 容器
    一、介绍1、介绍最近无聊,也没什么事做,没事做总是要给自己找点事情做吧,毕竟人的生活在与折腾。于是,决定自己手动写一个IOC的框架。我们知道在NetCore的版本里面已经内置了IOC容器,它就是ServiceCollection,一般情况下,该容器还是够用的,但是有时候还......
  • ASP.NET Web Optimization Framework
    ASP.NETWebOptimizationFrameworkWecanusepatternswhilesearchingfilesorsubdirectoriesbyusing“*”wildcardcharacterasfollows:Include(“~/Scripts/Common/*.js”)===>thiswillincludealljsfiles.IncludeDirectory(“~/Scripts/Common”,”T*.js......
  • 简谈:NIO三大组件之Channel、Buffer
    NIO释义:non-blockingio的简写,即非阻塞IO1.Channelchannel类似stream,但更加底层,是读写数据的双向通道,可将channel的数据写入buffer,也可将buffer的数据写入channel常见的Channel:FileChannel、DatagramChannel、SocketChannel、ServerSocketChannel2.Bufferbuffer用来缓冲......
  • .Net 5.0 程序在 Linux 环境访问 SqlServer 2008R2 莫名报错:Connection reset by peer
    〇、问题详情同样的代码,在Windows上运行的好好的,拿到CentOS7上运行就出现如下报错:【ex.message】:Aconnectionwassuccessfullyestablishedwiththeserver,butthenanerroroccurredduringtheloginprocess.(provider:TCPProvider,error:35-Aninternal......
  • Soil Erosion
    1.ThedefinitionofsoilerosionInthisprocess,thesoilparticlesareloosenedorwashedawayinthevalleys,oceans,rivers,streamsorfarawaylands.Thishasbeenworseningduetohumanactivitiessuchasagricultureanddeforestation.Soilerosion......
  • uni-swipe-action的使用和样式问题
    <uni-swipe-action>         <viewv-for="(item,index)innoticeList":key="item.id"style="margin-top:30upx;">            <uni-swipe-action-itemclass="swipe-action-item":right-options="o......
  • Insertion Sort
    想象一下,冒泡排序交换的两个数一定是原数组的逆序对(反证容易证明:如果不是逆序对,相遇之后不会交换。两个数只有在相遇的时候才会使得下标相对大小互换,相遇之前一定是左的在左,右的在右。而不是逆序对的话,相遇的时候也不会交换,所以就一直不会交换)。因为有序数组一定没有逆序对,所以逆......
  • rasterization算法(栅格化)
    光栅化,英文:Rasterization,是指把顶点数据转换为片元的过程。光栅化具有将图转化为一个个栅格组成的图象的作用,特点是每个元素对应帧缓冲区中的一像素。光栅化其实是一种将几何图元变为二维图像的过程。该过程包含了两部分的工作。第一部分工作:决定窗口坐标中的哪些整型栅格区域被......
  • 采坑-阿里云 kex_exchange_identification: read: Connection reset by peer
    自己买了台阿里的测试服务器,打开终端,输入命令 sshroot@xxx 等待输入密码。**报错:kex_exchange_identification:read:Connectionresetbypeer******昨天刚用的,今天咋回事,然后试了试公司的服务器是可以的。然后就开始百度找资料,找了一圈,大部分都是让修改配置文件。但是换了......