天道酬勤,学无止境

Handle GPIO Button event with C++

Hi guys I need some help. I am making a c++ embedded application in an ARM. I need to get a push button event, I was looking for in internet and I find that the best way to do it is with interruptions. I know that I can set one pin through terminal like this "echo raise > /sys/.../gpio/gpio81/edge". But I need to know how can I get the interrupt from my C++ application when it happend, I just need some example, because I do not know if I have to use some special library.

Thank you guys I hope someone can help me.

标签

评论

Manual 'mechanical' pushbuttons require debouncing. That, and the fact that pushing buttons does not require high I/O performance, means that a GPIO interrupt is an awkward overkill. It can' of course, be done, but it's easier and safer to poll the GPIO port with a timer interrupt, storing the state of the inputs and comparing with the previous state/s. If a GPIO line has changed state for a sufficient number of samples, you have your button event and can act on it.

If you are using a tasking OS, you could hook the existing timer interrupt - it's only a few instructions to handle the GPIO poll so you should not see any noticeable performace hit. If is is decided that the button/s have been pressed/released, you can signal a semaphore so that a waiting thread can quickly process the event.

Hi guys I find the solution what I just wanted is here:

https://developer.ridgerun.com/wiki/index.php/Gpio-int-test.c

Thank you anyways

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • ESP32 开发笔记(三)源码示例 5_KEY_Short_Long 使用IO中断和系统时间来检测按键时长实现长按短按
    开发板购买链接 https://item.taobao.com/item.htm?spm=a2oq0.12575281.0.0.50111deb2Ij1As&ft=t&id=626366733674 开发板简介开发环境搭建 windows ESP32例程为C语言开发,并非Python/Arduino/AT指令开发,基于ESP-IDF_V4.2框架库,采用纯C语言开发,开发工具为Visual Studio Code Android(安卓)例程全部为原生Android开发,例程全部支持到SDK版本29 Android 10.0(Q) 开发工具为Andirod Studio 4.0 PC源码例程为Visual Studio 2013开发,C++语言,基于MFC 送的MQTT账号,仅用于同学们开发测试,大家不要用到实际产品上,不定期更换密码,会在QQ群公布 以下列出的例程源码均编写完成(不断增加中),开发教程正在编写基础例程: 0_Hello Bug (ESP_LOGX与printf) 工程模板/打印调试输出 1_LED LED亮灭控制 2_LED_Task 使用任务方式控制LED 3_LEDC_PWM 使用LEDC来控制LED实现呼吸灯效果 4_ADC_LightR 使用ADC读取光敏电阻实现光照传感 5_KEY_Short_Long 按钮长按短按实现 6_TouchPad
  • ESP32 开发笔记(三)源码示例 19_WIFI_STA  创建STA站模式连接路由器
    开发板购买链接 https://item.taobao.com/item.htm?spm=a2oq0.12575281.0.0.50111deb2Ij1As&ft=t&id=626366733674 开发板简介开发环境搭建 windows ESP32例程为C语言开发,并非Python/Arduino/AT指令开发,基于ESP-IDF_V4.2框架库,采用纯C语言开发,开发工具为Visual Studio Code Android(安卓)例程全部为原生Android开发,例程全部支持到SDK版本29 Android 10.0(Q) 开发工具为Andirod Studio 4.0 PC源码例程为Visual Studio 2013开发,C++语言,基于MFC 送的MQTT账号,仅用于同学们开发测试,大家不要用到实际产品上,不定期更换密码,会在QQ群公布 以下列出的例程源码均编写完成(不断增加中),开发教程正在编写基础例程: 0_Hello Bug (ESP_LOGX与printf) 工程模板/打印调试输出 1_LED LED亮灭控制 2_LED_Task 使用任务方式控制LED 3_LEDC_PWM 使用LEDC来控制LED实现呼吸灯效果 4_ADC_LightR 使用ADC读取光敏电阻实现光照传感 5_KEY_Short_Long 按钮长按短按实现 6_TouchPad
  • 10.输入子系统
    在内核写好一些程序的基础上修改!input_init分析:drivers/input/input.c: input_init > err = register_chrdev(INPUT_MAJOR, "input", &input_fops);static const struct file_operations input_fops = {.owner = THIS_MODULE,.open = input_open_file,};问:怎么读按键? input_open_file struct input_handler *handler = input_table[iminor(inode) >> 5]; new_fops = fops_get(handler->fops) // =>&evdev_fops file->f_op = new_fops; err = new_fops->open(inode, file);app: read > ... > file->f_op->read input_table数组由谁构造? input_register_handler 注册input_handler: input_register_handler // 放入数组 input_table[handler->minor >> 5] = handler;// 放入链表list
  • 28335通过错误联防模块实现软件保护,禁止PWM信号输出,然后通过按键复位恢复PWM信号输出
    一开始程序只有一个产生PWM信号输出的中断,可以通过错误联防模块设置当采集到Fault信号时使PWM输出变为高阻态,但没有办法在异常出现后通过按键恢复PWM信号的输出,于是在程序里加上了错误联防模块的中断,用于实现此功能,关键代码如下: 程序开始前需要声明中断函数: interrupt void PMW_TZ_ISR(void); 指定PWM_TZ_ISR()函数作为EPWM1_TZINT中断的响应函数: PieVectTable.EPWM1_TZINT = &PMW_TZ_ISR; 通过查询中断向量表可知EPWM1_TZINT中断为PIE组2的第一个向量,故激活PIE组2的第一个中断向量,即ePWM_TZINT中断向量: PieCtrlRegs.PIEIER2.all = M_INT1; 同样有上面的表格可以得出,由于PIE组2的中断向量复用的是CPU的INT2中断,所以还要使能CPU的INT2用来处理EPWM1_TZINT中断: IER |= M_INT2; 准备工作完成后,即可在中断函数里实现上述的内容,具体为: 首先判断ONE-SHORT标志位EPwm1Regs.TZFLG.bit.OST是否为1,如果为一直为1,则说明故障还没有去除,系统不能继续工作,所以程序就一直在while循环里: while(EPwm1Regs.TZFLG.bit.OST == 1) { ... }
  • 给树莓派添加开关机键
    给树莓派添加开、关机键 声明 本文由u013062709原创,禁止二次修改发布。转载及引用内容请注明出处,并标明本站网址。文中程序仅供学习使用,本人不承担任何由使用文中代码产生的法律责任。 作为一个硬件爱好者、嵌入式系统工程师、技术宅,树莓派肯定是要玩一玩的,但是用的时间长了总会发现它有一些不完美的地方,比如:没有电源键! 常用的关机方法有两种(外接屏幕和键盘的就不说了): 远程登录然后敲命令(这是最合适的关机方法,但是太麻烦,如果没有电脑在身边就没法关机了)拔电源(简单粗暴,但很容易导致文件损坏) 所以为了愉快的使用树莓派,最好还是给它添加一个像电脑一样的电源键,百度了一大圈发现国内(没错,我就是针对国内,来来回回就那么几篇文章,还反反复复互相抄)只有一种添加电源键的方法,那就是写个python脚本、或者其他脚本、或者编译一个程序,反正原理都是一样的,让这个脚本(或程序)开机启动,程序中一直检测设置为电源键的GPIO,如果被触发则关机。这个方法虽然能解决问题,但真的low爆了!!!而且只能关机,不能开机。 在这里跟大家分享一个非常优雅,能关机也能开机的方法: 打开并仔细阅读 /boot/overlays/README 好了今天的分享到此结束,谢谢大家。 其实 /boot/overlays/README 里面已经说的很详细了,为了造福广大人民群众,我就整理一下。
  • rk3288 poll机制学习使用
    适用场景 使用休眠-唤醒的方式等待某个事件发生时,有一个缺点:等待的时间可能很久。我们可以加上一个超时时间,这时就可以使用 poll 机制。 APP 不知道驱动程序中是否有数据,可以先调用 poll 函数查询一下,poll 函数可以传入***超时时间***;APP 进入内核态,调用到驱动程序的 poll 函数,如果有数据的话立刻返回;如果发现没有数据时就***休眠一段时间***;当有数据时,比如当按下按键时,驱动程序的中断服务程序被调用,它会记录数据、唤醒 APP;当超时时间到了之后,内核也会唤醒 APP;APP 根据 poll 函数的返回值就可以知道是否有数据,如果有数据就调用 read 得到数据 使用流程 app里调用open函数 驱动层调用drv_open函数 app调用poll函数 驱动层调用drv_poll函数, drv_poll把自己的线程挂入等待队列wq中,drv_poll同时判断是否有数据,返回一个状态。 假设没有数据,则会休眠一段时间。 如果在休眠期间,发生了按键中断。则在中断服务程序中记录按键值,并且从wq中把线程唤醒。 线程唤醒后,继续执行for循环,再次调用poll,drv_poll返回数据状态。 如果有数据,内核态返回到用户态。 App调用read函数读数据。 当调用app调用poll后,进入内核态。 导致驱动程序的drv_poll被调用 假设当前没有数据
  • nodejs中的异步树莓派gpio事件(Async raspberry pi gpio events in nodejs)
    问题 我将一个按钮连接到 Raspberry Pi GPIO 端口: pi-gpio 节点 js 模块只允许拉取当前状态而不等待状态更改: gpio.read(16, function(err, value) { if(err) throw err; console.log(value); // The current state of the pin }); 有没有异步绑定事件的解决方案? 在此示例中,这将是每当按下按钮时。 回答1 我建议使用名为 onoff 的模块。 它能够观察值文件,同时不通过间隔轮询来增加 CPU 的负担。 我用 node.js 做了一个小的测试应用程序来试用它的 LED 和按钮,你可以在这里查看。 回答2 不幸的是,使用硬件 GPIO 时没有生成事件。 您可以通过使用发射器和setInterval创建一个事件来创建一个计时器,该计时器每setInterval检查一次状态,然后向您的应用程序发出一个事件。 var ee = new process.EventEmitter(), buttonState; ee.on('stateChange', function(previousValue, value){ console.log('button state changed from', previousValue, 'to', value); })
  • ESP32 ESP-IDF UART使用模式检测中断报告事件实现 收发数据
    官网esp-idf参考代码:D:\esp-idf\examples\peripherals\uart\uart_events 开发环境:Source Insight + esp-idf esp32模块:ESP32-WROOM-32 实现功能:使用ESP32的3个UART全部实现收发,要求3个UART同时接收每条数据长度25间隔时间为100ms。 初期看了一下官网的uart例程代码,官网推荐使用模式检测。自己也可以使用直接在ISR中处理中断。 #include <stdio.h> #include <string.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/uart.h" #include "freertos/queue.h" #include "driver/gpio.h" #define BUF_SIZE (1024) #define RD_BUF_SIZE (BUF_SIZE) uart_event_t uart0_event, uart1_event, uart2_event; QueueHandle_t uart0_queue, uart1_queue, uart2_queue; void uart_event_handle(uart_port_t uart
  • 树莓派小车python操作流程--龙邱科技
    ▌第一部分 环境解决 1.1 软件版本 发货前已经配置好软件环境: Linux raspberrypi 5.4.51Python 3.7OpenCV-python 3.4.6.27 1.2 TF卡克隆软件 ⊙ 软件包准备 ⊙ 解压缩到文件夹,并打开 ▲ Win32DiskImage解压缩之后目录 ⊙ 打开软件 ⊙ 建立img文件 当前需要备份的文件夹下面,新建一个*.img文件,比如:lqpios.img。 ⊙ 打开文件 ⊙ 写入TF卡 TF卡插入读卡器,并插到电脑USB口。 识别到TF卡后,可以进行读写操作: 点击read,需要几分钟完成备份;如果系统损坏可以从备份文件恢复,类似电脑ghost系统。 ▌第二部分 树莓派硬件 2.1 树莓派硬件连接 ▲ 树莓派的主要硬件配置 2.2 装配顺序 先贴上各个散热片 树莓派放入盒子 如果有插TF卡到卡槽,务必先拔掉TF卡(操作不当易碎) 插TF卡到背面卡槽(先装PCB板,再插卡) 插USB键盘到树莓派USB口 插USB鼠标到树莓派USB口 插USB摄像头到树莓派USB口 插触摸屏HDMI口到TYPE-C电源口右侧的USB口 插触摸屏的电源USB口到树莓派USB口 插触摸屏的触摸USB口到树莓派USB口(树莓派只有4个USB口,根据需要看插哪个设备) 最后插电源到树莓派TYPE-C电源口 关于硬件的装配过程,可以详见博文:
  • NXP iMX8 嵌入式Linux下Libgpiod 应用示例
    By Toradex秦海 1). 简介 NXP iMX8是NXP去年底发布的基于Cortex-A72/A53和Coretex-M4异构多核架构的ARM处理器,本文就基于嵌入式Linux演示GPIO相关应用示例。 本文所演示的ARM平台来自于Toradex 基于NXP iMX8QM ARM处理器的Apalis iMX8QM ARM嵌入式平台。 2). 准备 a). Apalis iMX8QM ARM核心版配合Apalis Evaluation Board载板,连接调试串口UART1(载板X29)到开发主机方便调试。 b). Apalis iMX8 Cortex-A核心安装Toradex Ycoto Linux Console image V3.04版本,详细信息请参考这里。 d). Apalis Evaluation Board GPIO相关硬件连接 X2 MXM_3 <-> X34 LED1 X2 MXM_5 <-> X34 SW5 X2 MXM_11 <-> X34 SW1 3). GPIO 命令行测试 a). 嵌入式Linux系统下之前呗广泛应用的GPIO工具为sysfs GPIO接口(/sys/class/gpio),但是目前这个项目已经处于deprecated状态,经Linux Kernel Community确定其替代者就是GPIO字符设备API Libgpiod。因此
  • ESPIDF开发ESP32学习笔记【基本内容】
    学校老师留了个作业,让用剩下一半的寒假学学ESP32,做蓝牙透传+STA&AP模式下工作的http服务器,但是不准用Arduino 当场就傻了:ESP32我刚刚好就会一手Arduino;乐鑫那套ESPIDF太难啃,之前点了个灯就去快乐stm32了;micropython…刷完固件发现蓝牙支持跟【数据删除】一样,还不如用c写——一咬牙一跺脚,回头肝ESPIDF吧 总体思路:资源少,跟着官方走准没错,硬啃就完事了 这个系列笔记可以供只接触过单片机开发(STM32、51基础)和硬件相关知识但没有接触过网络相关知识的同学翻阅学习 项目文件夹构建 ESP-IDF项目由各种“组件”构成,你需要什么功能就要往里扔进去什么组件 如果你的代码里用了一堆WiFi的库函数,但是没把WiFi组件加入进去,你是没办法用WiFi功能的 项目保存在项目文件夹下,它的根目录如下所示: ├── CMakeLists.txt Cmake使用的文件 ├── other_documents 其他文件 ├── main 存储主程序 │ ├── CMakeLists.txt │ ├── component.mk 组件的make file │ └── main.c └── Makefile 由传统的GNU make程序使用的Makefile 需要注意的是:ESP-IDF并不是项目文件夹的一部分,它更像是一个自助编译器
  • ESP32 开发笔记(三)源码示例 6_TouchPad_Interrupt 电容触摸中断实现触摸按钮
    开发板购买链接 https://item.taobao.com/item.htm?spm=a2oq0.12575281.0.0.50111deb2Ij1As&ft=t&id=626366733674 开发板简介开发环境搭建 windows ESP32例程为C语言开发,并非Python/Arduino/AT指令开发,基于ESP-IDF_V4.2框架库,采用纯C语言开发,开发工具为Visual Studio Code Android(安卓)例程全部为原生Android开发,例程全部支持到SDK版本29 Android 10.0(Q) 开发工具为Andirod Studio 4.0 PC源码例程为Visual Studio 2013开发,C++语言,基于MFC 送的MQTT账号,仅用于同学们开发测试,大家不要用到实际产品上,不定期更换密码,会在QQ群公布 以下列出的例程源码均编写完成(不断增加中),开发教程正在编写基础例程: 0_Hello Bug (ESP_LOGX与printf) 工程模板/打印调试输出 1_LED LED亮灭控制 2_LED_Task 使用任务方式控制LED 3_LEDC_PWM 使用LEDC来控制LED实现呼吸灯效果 4_ADC_LightR 使用ADC读取光敏电阻实现光照传感 5_KEY_Short_Long 按钮长按短按实现 6_TouchPad
  • Raspberry Pi RuntimeError: Conflicting edge detection already enabled for this GPIO channel
    I was following a tutorial found here: https://www.linkedin.com/pulse/prepare-your-raspberry-pi-work-aws-iot-kay-lerch I have not even begun the internet part of it as I was having issues with the circuit. I wired my circuit just like it is shown in this diagram below using my raspberry pi 3. I then wrote the following python script as shown in the tutorial. import RPi.GPIO as gpio gpio.setmode(gpio.BOARD) gpio.setup(7, gpio.IN, pull_up_down=gpio.PUD_DOWN) def on_pushdown(channel): print "Button Pushed." while(True): gpio.add_event_detect(7, gpio.RISING, callback=on_pushdown, bouncetime=200)
  • 树莓派-5-GPIO的应用实验
    【树莓派4B学习】一、环境搭建、开机及登录树莓派4B 【树莓派4B学习】二、树莓派4B介绍与一些必要的软件安装配置 【树莓派4B学习】三、接入USB摄像头,搭建Python2.7.16+OpenCV3.2.0开发环境 【树莓派4B学习】四、使用USB摄像头和motion实现监控 【树莓派4B学习】五、树莓派4B的OpenCV基本操作 【树莓派4B学习】六、树莓派4BOpenCV的视频/摄像头基本操作 【树莓派4B学习】七、树莓派4B的GPIO基础操作 1 wiringPi和BCM和BOARD编码 1.1 管脚信息 树莓派上提供了一组GPIO(General Purpose Input Output,即通用输入/输出)接口,这些接口可以用于做一些电子相关的实验:控制一些硬件设备,如最常见的发光二极管、电机等,或者读取一些信号的状态,如开关、传感器等。这里需要注意的是,树莓派中的GPIO只支持数字输入输出,即1和0对应高电平3.3V和低电平0V,因此必要的时候可能需要数模转换。 树莓派中执行: $gpio readall得到关于树莓派管脚的信息 RXD是Receive Data接收数据的引脚 TXD是Transmit Data发送数据的引脚 比如,BOARD编码中的37号引脚 在wiringPi 中的编码就是25号引脚 在BCM 中的编码就是26号引脚 它们的功能都是GPIO.25
  • rk3288 阻塞和非阻塞
    适用场景 阻塞:就是等待某件事情发生。比如调用read时,如果没有按键数据则read不会返回,会让进程休眠等待。 其中poll中,如果传入超时事件不是0, 也是会阻塞的。使用poll时,设置超时时间0,没有数据也立即返回。 但是不能让read函数及工作于阻塞方式,又工作于非阻塞方式: App调用open函数传入O_NONBLOCK,表示使用非阻塞模式,默认是使用阻塞方式。 当open是O_NONBLOCK后,可以使用fcntl修改为阻塞或非阻塞。 应用编程 //open时设置 int fd = open("/dev/xxx", O_RDWR | O_NONBLOCK); /* 非阻塞方式 */ int fd = open("/dev/xxx", O_RDWR ); /* 阻塞方式 */ //open之后设置 int flags = fcntl(fd, F_GETFL); fcntl(fd, F_SETFL, flags | O_NONBLOCK); /* 非阻塞方式 */ fcntl(fd, F_SETFL, flags & ~O_ONOBLOCK); /* 阻塞方式 */ 驱动编程 在drv_read中,添加判断是否NON_BLOCK static ssize_t drv_read(struct file *fp, char __user *buf, size_t count
  • poll()返回POLLPRI和POLLERR(poll() returns both, POLLPRI & POLLERR)
    问题 我开始使用Linux和嵌入式系统(路由器硬件和openwrt)进行C编程。 我已经使用轮询工作启用了GPIO上的中断...几乎。 我可以使用poll(),如果我按下按钮触发中断,则poll()返回的值>0。到目前为止,一切都很好。 现在,我尝试同时在多个GPIO上使用poll(),因此想分析每个潜在中断源的情况。 尽管该中断似乎有效,但我又收到了POLLPRI和POLLERR的通知,但我不明白为什么。 将pollfd结构减少为1个条目不会更改任何内容。 char value; int fd_btn1 = open("/sys/class/gpio/gpio14/value", O_RDONLY); int fd_left = open("/sys/class/gpio/gpio12/value", O_RDONLY); int fd_right = open("/sys/class/gpio/gpio13/value", O_RDONLY); struct pollfd fds[3]; fds[0].fd = fd_btn1; fds[1].fd = fd_left; fds[2].fd = fd_right; fds[0].events = POLLPRI; fds[1].events = POLLPRI; fds[2].events = POLLPRI; read(fd
  • Allocating an object for C / FFI library calls
    I have a C library, which has gpio implementation. There's gpio_type which is target specific, each MCU has different definition for gpio_type. One of the functions in the library: void gpio_init(gpio_type *object, int32_t pin); I want to write abstraction of Gpio object in Rust, using C library functions. Therefore need something like opaque pointer type (in C++ I would just create a member variable with type: gpio_type). I figured I would create an empty enum (or struct), allocate a space needed for the object and transmute it to match the type in C layer. pub enum gpio_type {} #[link(name =
  • Async raspberry pi gpio events in nodejs
    I connected a button to the Raspberry Pi GPIO ports: The pi-gpio node js module allows only to pull the current status but not waiting for a state change: gpio.read(16, function(err, value) { if(err) throw err; console.log(value); // The current state of the pin }); Is there any solution to bind events asynchronously? In this example this would be whenever the button is pressed.
  • STM32CubeMX_环境搭建_GPIO_外部中断
    文章目录 前言环境配置STM32CubeMXKeilST-LINK/V2-1GPIO硬件连接 新建STM32CubeMX工程GPIO外部中断工程代码微信公众号 前言 上上周写了S32K148的 GPIO, 定时器, 串口, CAN, 以太网的系列博客: https://blog.csdn.net/weifengdq/article/category/9369425 上周写了RISC-V之GD32VF103的 GPIO, 定时器, 串口, DAC, CAN发送 系列博客: https://blog.csdn.net/weifengdq/article/category/9465635 本周工作任务稍重, 就整理点STM32的系列博客, 节省时间. 相信不少人是从微雪课堂的 STM32CubeMX系列教程 入坑的, 这套教程写的不错, 基于STM32CubeMX 4.x都可以用, 不过最新的STM32CubeMX已经走到了5.4.0版本(2019年11月), 界面稍微不一样, 有些接口也稍微变动. 这里以STM32CubeMX5.4.0为例, 片子就不分STM32L/F/G/H之类的, 基本通用, 手头有什么板子就用什么吧, 刚好手边有块NUCLEO-F767ZI. 至于IDE, 还用Keil 5.x, 毕竟人多坑少. 众所周知, STM32编程方式经历了寄存器, 标准库, HAL
  • poll() returns both, POLLPRI & POLLERR
    I started to get in C programming with Linux and embedded systems (router hardware and openwrt). I have got interupts on GPIOs enabled, using poll works ... nearly. I can use poll() and if i press the button to trigger the interrupt, poll() returns with a value > 0. So far so good. Now i try to use poll() on several GPIOs simultaniosly and therefor want to analyze the revents of every potential interrupt source. Allthough the interrupt seems to work, i get POLLPRI & POLLERR back and i do not understand why. Reducing the pollfd structure to 1 entry does not change anything. char value; int fd