Skip to content

Instantly share code, notes, and snippets.

@ymkim92
Forked from jadonk/epolltest.c
Last active May 15, 2023 01:38
Show Gist options
  • Save ymkim92/0af2face4e05ecf65666c71884b3734e to your computer and use it in GitHub Desktop.
Save ymkim92/0af2face4e05ecf65666c71884b3734e to your computer and use it in GitHub Desktop.
Quick test using epoll to wait on GPIO events
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <sys/types.h>
int main(int argc, char** argv) {
int n;
// int epoll_create(int size)
// number of file descriptors a process wants to monitor,
// which helps the kernel to decide the size of the epoll instance
int epfd = epoll_create(1);
int fd = open("/sys/class/gpio/gpio34/value", O_RDWR | O_NONBLOCK);
printf("open returned %d: %s\n", fd, strerror(errno));
if(fd > 0) {
char buf = 0;
struct epoll_event ev;
struct epoll_event events;
ev.events = EPOLLPRI; // used to receive urgent data.
ev.data.fd = fd;
// int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
// epfd: is the file descriptor returned by epoll_create
// op: refers to the operation to be performed on the file descriptor fd.
// In general, three operations are supported:
// - Register fd with the epoll instance (EPOLL_CTL_ADD) and get notified about events that occur on fd
// - Delete/deregister fd from the epoll instance.
// This would mean that the process would no longer get any notifications about events
// on that file descriptor (EPOLL_CTL_DEL).
// If a file descriptor has been added to multiple epoll instances,
// then closing it will remove it from all of the epoll interest lists to which it was added.
// - Modify the events fd is monitoring (EPOLL_CTL_MOD)
// fd: is the file descriptor we want to add to the epoll list/interest list.
// event: is a pointer to a structure called epoll_event which stores the event we actually want to monitor fd for.
n = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
printf("epoll_ctl returned %d: %s\n", n, strerror(errno));
while(1) {
// int epoll_wait(int epfd, struct epoll_event *evlist, int maxevents, int timeout);
// evlist: is an array of epoll_event structures.
// evlist is allocated by the calling process and when epoll_wait returns,
// this array is modified to indicate information about the subset of file descriptors
// in the interest list that are in the ready state (this is called the ready list)
// * when timeout is set to -1, epoll_wait will block “forever”
// * return: -1 if error, 0 if timeout,
// a positive integer which indicates the total number of file descriptors in the evlist array
n = epoll_wait(epfd, &events, 1, -1);
printf("epoll returned %d: %s\n", n, strerror(errno));
if(n > 0) {
n = lseek(fd, 0, SEEK_SET);
printf("seek %d bytes: %s\n", n, strerror(errno));
n = read(fd, &buf, 1);
printf("read %d bytes: %s\n", n, strerror(errno));
printf("buf = 0x%x\n", buf);
}
}
}
return(0);
}
root@beaglebone:/var/lib/cloud9# gcc -o epolltest epolltest.c && ./epolltest
open returned 4: Success
epoll_ctl returned 0: Success
epoll returned 1: Success
seek 0 bytes: Success
read 1 bytes: Success
buf = 0x31
epoll returned 1: Success
seek 0 bytes: Success
read 1 bytes: Success
buf = 0x30
epoll returned 1: Success
seek 0 bytes: Success
read 1 bytes: Success
buf = 0x31
epoll returned 1: Success
seek 0 bytes: Success
read 1 bytes: Success
buf = 0x30
epoll returned 1: Success
seek 0 bytes: Success
read 1 bytes: Success
buf = 0x31
^C
root@beaglebone:/var/lib/cloud9#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment