-
Notifications
You must be signed in to change notification settings - Fork 2
/
gpio-dev-mem-test.c
103 lines (89 loc) · 2.15 KB
/
gpio-dev-mem-test.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
* This test application is to read/write data directly from/to the device
* from userspace.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#define IN 0
#define OUT 1
void usage(void)
{
printf("*argv[0] -g <GPIO_ADDRESS> -i|-o <VALUE>\n");
printf(" -g <GPIO_ADDR> GPIO physical address\n");
printf(" -i Input from GPIO\n");
printf(" -o <VALUE> Output to GPIO\n");
return;
}
int main(int argc, char *argv[])
{
int c;
int fd;
int direction=IN;
unsigned long long gpio_addr = 0;
int value = 0;
unsigned long long page_addr, page_offset;
void *ptr;
unsigned long long page_size=sysconf(_SC_PAGESIZE);
printf("GPIO access through /dev/mem.\n");
/* Parse command line arguements */
while((c = getopt(argc, argv, "g:io:h")) != -1) {
switch(c) {
case 'g':
gpio_addr=strtoul(optarg,NULL, 0);
break;
case 'i':
direction=IN;
break;
case 'o':
direction=OUT;
value=atoi(optarg);
break;
case 'h':
usage();
return 0;
default:
printf("invalid option: %c\n", (char)c);
usage();
return -1;
}
}
if (gpio_addr == 0) {
printf("GPIO physical address is required.\n");
usage();
return -1;
}
/* Open /dev/mem file */
fd = open ("/dev/mem", O_RDWR);
if (fd < 1) {
perror(argv[0]);
return -1;
}
/* mmap the device into memory */
page_addr = (gpio_addr & (~(page_size-1)));
page_offset = gpio_addr - page_addr;
ptr = mmap(NULL, page_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, page_addr);
if(ptr < 0){
printf("mmap failed. see errno for reason.\n");
close(fd);
return -1;
}
if (direction == IN) {
/* Read value from the device register */
// value = (int)(*((unsigned long long*)(ptr + page_offset)));
value = *((int*)(ptr + page_offset));
// int value2 = (int)(*((unsigned long long*)(ptr + page_offset + 4)));
printf("gpio dev-mem test: input: %08x\n",value);
// printf("value after: %08x\n", value2);
} else {
/* Write value to the device register */
*((int*)(ptr + page_offset)) = value;
// *((unsigned *)(ptr + page_offset + 8)) = value;
}
munmap(ptr, page_size);
close(fd);
return 0;
}