用于多线程环境中GPIO控制的epoll

时间:2018-06-12 11:18:15

标签: linux gpio epoll epollet

我需要监控linux嵌入式计算机上的许多GPIO引脚。 由于我关心这些针的边缘(下降),我决定使用epoll。 这是我写的代码(部分在互联网上找到):

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <time.h>

using namespace std;

void gpio_init(void); //exporting gpio, set direction and edge
void openAndAddToPoll(int epfd, int key, int &fd, epoll_event& eventToAdd);

const int MAX_FDS = 6; //number of keys to monitor
int fds[MAX_FDS]; //array of file descriptors
epoll_event eventToAdd[MAX_FDS]; //array of epoll events

void* gpio_start (void*) //start routine for gpio thread
{
gpio_init();
//creating the epoll
int epfd = epoll_create(MAX_FDS);
//opening each file descriptor and assigning events
openAndAddToPoll(epfd, KEY_UP, fds[0], eventToAdd[0]);
openAndAddToPoll(epfd, KEY_DOWN, fds[1], eventToAdd[1]);
openAndAddToPoll(epfd, KEY_LEFT, fds[2], eventToAdd[2]);
openAndAddToPoll(epfd, KEY_RIGHT, fds[3], eventToAdd[3]);
openAndAddToPoll(epfd, KEY_CANCEL, fds[4], eventToAdd[4]);
openAndAddToPoll(epfd, KEY_OK, fds[5], eventToAdd[5]);

//creating the struct
struct epoll_event events[MAX_FDS];

while (1)
{
    pthread_mutex_lock(&threads[1].mutex);

    int edges_detected = epoll_wait(epfd, events, MAX_FDS, -1);
    for (int i = 0; i < edges_detected; i++)
    {
       if (events[i].events & EPOLLHUP)
       {
          //this is the error case
          close (events[i].data.fd);
          continue;
       }
       //assuming gpio only listed in events due to falling edge
       switch (events[i].data.u32)
       {
         case 10: {//GPIO10 activated 
                   break;}
         case 120: {//GPIO120 activated
                   break;}
         case 117: {//GPIO117 activated
                   break;}
         case 118: {//GPIO118 activated
                   break;}
         case 8: {//GPIO8 activated
                 break;}
         case 137: {//GPIO137 activated
                   break;}
        }
    }

        pthread_mutex_unlock(&threads[1].mutex);
}
pthread_exit(NULL);
}


void openAndAddToPoll(int epfd, int key, int &fd, epoll_event& eventToAdd)
{
   //opening a fd for the key
   fd = gpio_fd_open(key);
   //assigning falling edge event to that specific key
   eventToAdd.events = EPOLLET;
   eventToAdd.data.u32 = key;

   if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &eventToAdd) == -1)
   {
       perror("epoll_ctl failed: ");
       exit(-1);
   }
}

物理信号是理想的(无反弹),并且对于每个GPIO输入都是相同的。 问题是按一个键(说&#34; OK&#34;)我有一个事件通知其他键(说&#34; DOWN&#34;)我有通知多个事件(4个实例而不是1个)。 请注意,epoll不用于任何其他线程,但轮询是(管理串行接口)。 由于它确实是一个软件问题,如何通过多个(和不均匀的)事件通知来解决此问题?这可能是原因?

0 个答案:

没有答案