-
Notifications
You must be signed in to change notification settings - Fork 1
/
uio_app.c
79 lines (67 loc) · 1.64 KB
/
uio_app.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*
* This application is part of a UIO driver demonstration
* It opens the /dev/uio0 device and waits for events.
*
*/
#include <stdlib.h> // EXIT codes
#include <stdio.h> // printf
#include <unistd.h> // sysconf
#include <fcntl.h> // open file
#include <errno.h> // errno
#include <sys/time.h> // timeval
#include <string.h> // memcpy
#include <sys/mman.h> // mmap
int main()
{
int uiofd;
int err = 0;
unsigned int i;
fd_set uiofd_set;
struct timeval tv;
int interrupt_count;
char* mem;
// open uio0
uiofd = open("/dev/uio0", O_RDONLY);
if (uiofd < 0) {
perror("uio open:");
return errno;
}
// create mmap on uio0 / map0
mem = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ, MAP_SHARED, uiofd , 0);
if (mem == MAP_FAILED){
perror("mmap failed");
close(uiofd);
exit(EXIT_FAILURE);
}
// prepare a set of FD for select with uiofd only
FD_ZERO(&uiofd_set);
FD_SET(uiofd, &uiofd_set);
for(i = 0;i < 10; ++i) {
// five second timeout (reset each time)
tv.tv_sec = 5;
tv.tv_usec = 0;
// select waits for a group of file descriptor
// uiofd + 1 is the max_fd(uiofd_set) +1
err = select(uiofd+1, &uiofd_set, NULL, NULL, &tv);
if (err < 0){
perror("select()");
break;
}else if(err == 0){
printf("Timeout, exiting\n");
break;
}
// actually read, consumes the interrupt in uio driver.
char buf[4];
err = read(uiofd, buf, 4);
if (err !=4){
perror("Read error.");
break;
}
// read interrupt count from memory mapping
memcpy(&interrupt_count, mem, sizeof(interrupt_count));
printf("Read interrupt count : %d \n", interrupt_count);
}
munmap(mem, sysconf(_SC_PAGE_SIZE));
close(uiofd);
exit(err);
}