背景:Qt应用程序需要对底层IO端口的中断做出响应。
.h
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/poll.h>
#include <QThread>
class PowerButtonControl:public QThread
{
Q_OBJECT
signals:
void powerButtonInterrupt();
public:
explicit PowerButtonControl(QObject *parent = nullptr);
void run();
//void signal_handler(void);
static void set_power_button_led_yellow_gpio(bool val);
private:
int fd_gpio139;
char value_gpio139;
struct pollfd poll_gpio139;
};
.cpp
#include"powerbuttoninterruptset.h"
#include"gpioset.h"
#include"pwmset.h"
#include<signal.h>
#define GPIOPOWERLEDYELLOW 142
#define GPIOPOWERINTERRUPT 139
#define POLL_TIMEOUT (3 * 1000) /* 3 seconds */
a7PowerButtonControl::a7PowerButtonControl(QObject *parent):QThread(parent)
{
}
void a7PowerButtonControl::run()
{
int value = 0;
int nfds = 2;
int gpio_fd, timeout, pollstatus;
struct pollfd fdset[2];
char buf[MAX_BUF];
int len;
int cnt = 0;
unsigned int valueback = 0;
// signal(SIGINT, signal_handler);
GpioControl::gpio_export(GPIOPOWERLEDYELLOW);
GpioControl::gpio_set_dir(GPIOPOWERLEDYELLOW, "out");
GpioControl::gpio_set_value(GPIOPOWERLEDYELLOW, value);
//printf("\n Sucessfully Configure GPIO-%d value as %d\n", GPIOPOWERLEDYELLOW, value);
GpioControl::gpio_export(GPIOPOWERINTERRUPT);
GpioControl::gpio_set_dir(GPIOPOWERINTERRUPT, "in");
GpioControl::gpio_set_edge(GPIOPOWERINTERRUPT, "rising");
// printf("\n Sucessfully Configure GPIO-%d as input\n", GPIOPOWERINTERRUPT);
gpio_fd = a7GpioControl::gpio_fd_open(GPIOPOWERINTERRUPT, O_RDONLY);
timeout = POLL_TIMEOUT;
while(true){
memset((void*)fdset, 0, sizeof(fdset));
fdset[0].fd = STDIN_FILENO;
fdset[0].events = POLLIN;
fdset[1].fd = gpio_fd;
fdset[1].events = POLLPRI;
pollstatus = poll(fdset, nfds, timeout);
if(pollstatus < 0){
// printf("\npoll() failed!\n");
}
if(pollstatus == 0){
// printf(".");
}
if(fdset[1].revents & POLLPRI){
lseek(fdset[1].fd, 0, SEEK_SET);
len = read(fdset[1].fd, buf, MAX_BUF);
if(cnt > 0){
usleep(20000);
a7GpioControl::gpio_get_value(GPIOPOWERINTERRUPT, &valueback);
if(valueback == 1){
//printf("\nButton pressed times X%d\n", cnt);
value = !value;
emit powerButtonInterrupt();
PwmContrl::enable_or_disable_led_pwm(!value);
PowerButtonControl::set_power_button_led_yellow_gpio(value);
if(value == 0){
// printf("\nLED turns off\n");
}else{
//printf("\nLED truns on\n");
}
}
}
cnt++;
}
if(fdset[0].revents & POLLIN){
(void)read(fdset[0].fd, buf, 1);
//printf("\npoll() stdin read 0x%2.2X\n",(unsigned int)buf[0]);
}
fflush(stdout);
}
GpioControl::gpio_fd_close(gpio_fd);
}
// void PowerButtonControl::signal_handler()
// {
// }
void PowerButtonControl::set_power_button_led_yellow_gpio(bool val)
{
if(val)
GpioControl::gpio_ctrl(142,"out", GpioControl::HIGH);
else
GpioControl::gpio_ctrl(142,"out", GpioControl::LOW);
}