rpi_gpio 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  Original code by Ben Croston modified for Ruby by Nick Lowery
3
3
  (github.com/clockvapor)
4
- Copyright (c) 2014-2016 Nick Lowery
4
+ Copyright (c) 2014-2020 Nick Lowery
5
5
 
6
6
  Copyright (c) 2013-2015 Ben Croston
7
7
 
@@ -36,10 +36,10 @@ void set_low_event(int gpio, int enable);
36
36
  int eventdetected(int gpio);
37
37
  void cleanup(void);
38
38
 
39
- #define SETUP_OK 0
40
- #define SETUP_DEVMEM_FAIL 1
41
- #define SETUP_MALLOC_FAIL 2
42
- #define SETUP_MMAP_FAIL 3
39
+ #define SETUP_OK 0
40
+ #define SETUP_DEVMEM_FAIL 1
41
+ #define SETUP_MALLOC_FAIL 2
42
+ #define SETUP_MMAP_FAIL 3
43
43
  #define SETUP_CPUINFO_FAIL 4
44
44
  #define SETUP_NOT_RPI_FAIL 5
45
45
 
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  Original code by Ben Croston modified for Ruby by Nick Lowery
3
3
  (github.com/clockvapor)
4
- Copyright (c) 2014-2016 Nick Lowery
4
+ Copyright (c) 2014-2020 Nick Lowery
5
5
 
6
6
  Copyright (c) 2013-2014 Ben Croston
7
7
 
@@ -47,8 +47,7 @@ int check_gpio_priv(void)
47
47
  // check mmap setup has worked
48
48
  if (!module_setup)
49
49
  {
50
- rb_raise(rb_eRuntimeError, "no access to /dev/mem. Try "
51
- "running as root!");
50
+ rb_raise(rb_eRuntimeError, "no access to /dev/mem. Try running as root!");
52
51
  return 2;
53
52
  }
54
53
  return 0;
@@ -67,10 +66,8 @@ int get_gpio_number(int channel, unsigned int *gpio)
67
66
 
68
67
  // check channel number is in range
69
68
  if ( (gpio_mode == BCM && (channel < 0 || channel > 53))
70
- || (gpio_mode == BOARD && (channel < 1 || channel > 26) &&
71
- rpiinfo.p1_revision != 3)
72
- || (gpio_mode == BOARD && (channel < 1 || channel > 40) &&
73
- rpiinfo.p1_revision == 3))
69
+ || (gpio_mode == BOARD && (channel < 1 || channel > 26) && rpiinfo.p1_revision != 3)
70
+ || (gpio_mode == BOARD && (channel < 1 || channel > 40) && rpiinfo.p1_revision == 3) )
74
71
  {
75
72
  rb_raise(rb_eArgError, "the channel sent is invalid on a Raspberry Pi");
76
73
  return 4;
@@ -81,8 +78,7 @@ int get_gpio_number(int channel, unsigned int *gpio)
81
78
  {
82
79
  if (*(*pin_to_gpio+channel) == -1)
83
80
  {
84
- rb_raise(rb_eArgError, "the channel sent is invalid on a Raspberry "
85
- "Pi");
81
+ rb_raise(rb_eArgError, "the channel sent is invalid on a Raspberry Pi");
86
82
  return 5;
87
83
  } else {
88
84
  *gpio = *(*pin_to_gpio+channel);
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  Original code by Ben Croston modified for Ruby by Nick Lowery
3
3
  (github.com/clockvapor)
4
- Copyright (c) 2014-2016 Nick Lowery
4
+ Copyright (c) 2014-2020 Nick Lowery
5
5
 
6
6
  Copyright (c) 2013-2015 Ben Croston
7
7
 
@@ -1,9 +1,9 @@
1
1
  /*
2
2
  Original code by Ben Croston modified for Ruby by Nick Lowery
3
3
  (github.com/clockvapor)
4
- Copyright (c) 2014-2016 Nick Lowery
4
+ Copyright (c) 2014-2020 Nick Lowery
5
5
 
6
- Copyright (c) 2013-2016 Ben Croston
6
+ Copyright (c) 2012-2019 Ben Croston
7
7
 
8
8
  Permission is hereby granted, free of charge, to any person obtaining a copy of
9
9
  this software and associated documentation files (the "Software"), to deal in
@@ -24,9 +24,15 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  SOFTWARE.
25
25
  */
26
26
 
27
+ /* See the following for up to date information:
28
+ * https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
29
+ */
30
+
27
31
  #include <stdio.h>
32
+ #include <stdint.h>
28
33
  #include <stdlib.h>
29
34
  #include <string.h>
35
+ #include <arpa/inet.h>
30
36
  #include "cpuinfo.h"
31
37
 
32
38
  int get_rpi_info(rpi_info *info)
@@ -35,24 +41,33 @@ int get_rpi_info(rpi_info *info)
35
41
  char buffer[1024];
36
42
  char hardware[1024];
37
43
  char revision[1024];
38
- char *rev;
39
44
  int found = 0;
40
45
  int len;
41
46
 
42
- if ((fp = fopen("/proc/cpuinfo", "r")) == NULL)
43
- return -1;
44
- while(!feof(fp)) {
45
- fgets(buffer, sizeof(buffer), fp);
46
- sscanf(buffer, "Hardware : %s", hardware);
47
- if (strcmp(hardware, "BCM2708") == 0 ||
48
- strcmp(hardware, "BCM2709") == 0 ||
49
- strcmp(hardware, "BCM2835") == 0 ||
50
- strcmp(hardware, "BCM2836") == 0 ||
51
- strcmp(hardware, "BCM2837") == 0 ) {
52
- found = 1;
47
+ if ((fp = fopen("/proc/device-tree/system/linux,revision", "r"))) {
48
+ uint32_t n;
49
+ if (fread(&n, sizeof(n), 1, fp) != 1) {
50
+ fclose(fp);
51
+ return -1;
53
52
  }
54
- sscanf(buffer, "Revision : %s", revision);
53
+ sprintf(revision, "%x", ntohl(n));
54
+ found = 1;
55
55
  }
56
+ else if ((fp = fopen("/proc/cpuinfo", "r"))) {
57
+ while(!feof(fp) && fgets(buffer, sizeof(buffer), fp)) {
58
+ sscanf(buffer, "Hardware : %s", hardware);
59
+ if (strcmp(hardware, "BCM2708") == 0 ||
60
+ strcmp(hardware, "BCM2709") == 0 ||
61
+ strcmp(hardware, "BCM2835") == 0 ||
62
+ strcmp(hardware, "BCM2836") == 0 ||
63
+ strcmp(hardware, "BCM2837") == 0 ) {
64
+ found = 1;
65
+ }
66
+ sscanf(buffer, "Revision : %s", revision);
67
+ }
68
+ }
69
+ else
70
+ return -1;
56
71
  fclose(fp);
57
72
 
58
73
  if (!found)
@@ -65,36 +80,56 @@ int get_rpi_info(rpi_info *info)
65
80
  // new scheme
66
81
  //info->rev = revision[len-1]-'0';
67
82
  strcpy(info->revision, revision);
68
- switch (revision[len-2]) {
69
- case '0': info->type = "Model A"; info->p1_revision = 2; break;
70
- case '1': info->type = "Model B"; info->p1_revision = 2; break;
71
- case '2': info->type = "Model A+"; info->p1_revision = 3; break;
72
- case '3': info->type = "Model B+"; info->p1_revision = 3; break;
73
- case '4': info->type = "Pi 2 Model B"; info->p1_revision = 3; break;
74
- case '5': info->type = "Alpha"; info->p1_revision = 3; break;
75
- case '6': info->type = "Compute"; info->p1_revision = 0; break;
76
- case '8': info->type = "Pi 3 Model B"; info->p1_revision = 3; break;
77
- case '9': info->type = "Zero"; info->p1_revision = 3; break;
78
- default : info->type = "Unknown"; info->p1_revision = 3; break;
79
- }
80
- switch (revision[len-4]) {
81
- case '0': info->processor = "BCM2835"; break;
82
- case '1': info->processor = "BCM2836"; break;
83
- case '2': info->processor = "BCM2837"; break;
84
- default : info->processor = "Unknown"; break;
85
- }
86
- switch (revision[len-5]) {
87
- case '0': info->manufacturer = "Sony"; break;
88
- case '1': info->manufacturer = "Egoman"; break;
89
- case '2': info->manufacturer = "Embest"; break;
90
- case '4': info->manufacturer = "Embest"; break;
91
- default : info->manufacturer = "Unknown"; break;
92
- }
93
- switch (strtol((char[]){revision[len-6],0}, NULL, 16) & 7) {
94
- case 0: info->ram = "256M"; break;
95
- case 1: info->ram = "512M"; break;
96
- case 2: info->ram = "1024M"; break;
97
- default: info->ram = "Unknown"; break;
83
+ switch (revision[len-3]) {
84
+ case '0' :
85
+ switch (revision[len-2]) {
86
+ case '0': info->type = "Model A"; info->p1_revision = 2; break;
87
+ case '1': info->type = "Model B"; info->p1_revision = 2; break;
88
+ case '2': info->type = "Model A+"; info->p1_revision = 3; break;
89
+ case '3': info->type = "Model B+"; info->p1_revision = 3; break;
90
+ case '4': info->type = "Pi 2 Model B"; info->p1_revision = 3; break;
91
+ case '5': info->type = "Alpha"; info->p1_revision = 3; break;
92
+ case '6': info->type = "Compute Module 1"; info->p1_revision = 0; break;
93
+ case '8': info->type = "Pi 3 Model B"; info->p1_revision = 3; break;
94
+ case '9': info->type = "Zero"; info->p1_revision = 3; break;
95
+ case 'a': info->type = "Compute Module 3"; info->p1_revision = 0; break;
96
+ case 'c': info->type = "Zero W"; info->p1_revision = 3; break;
97
+ case 'd': info->type = "Pi 3 Model B+"; info->p1_revision = 3; break;
98
+ case 'e': info->type = "Pi 3 Model A+"; info->p1_revision = 3; break;
99
+ default : info->type = "Unknown"; info->p1_revision = 3; break;
100
+ } break;
101
+ case '1':
102
+ switch (revision[len-2]) {
103
+ case '0': info->type = "Compute Module 3+"; info->p1_revision = 0; break;
104
+ case '1': info->type = "Pi 4 Model B"; info->p1_revision = 3; break;
105
+ default : info->type = "Unknown"; info->p1_revision = 3; break;
106
+ } break;
107
+ default: info->type = "Unknown"; info->p1_revision = 3; break;
108
+ }
109
+
110
+ switch (revision[len-4]) {
111
+ case '0': info->processor = "BCM2835"; break;
112
+ case '1': info->processor = "BCM2836"; break;
113
+ case '2': info->processor = "BCM2837"; break;
114
+ case '3': info->processor = "BCM2711"; break;
115
+ default : info->processor = "Unknown"; break;
116
+ }
117
+ switch (revision[len-5]) {
118
+ case '0': info->manufacturer = "Sony"; break;
119
+ case '1': info->manufacturer = "Egoman"; break;
120
+ case '2': info->manufacturer = "Embest"; break;
121
+ case '3': info->manufacturer = "Sony Japan"; break;
122
+ case '4': info->manufacturer = "Embest"; break;
123
+ case '5': info->manufacturer = "Stadium"; break;
124
+ default : info->manufacturer = "Unknown"; break;
125
+ }
126
+ switch (strtol((char[]){revision[len-6],0}, NULL, 16) & 7) {
127
+ case 0: info->ram = "256M"; break;
128
+ case 1: info->ram = "512M"; break;
129
+ case 2: info->ram = "1G"; break;
130
+ case 3: info->ram = "2G"; break;
131
+ case 4: info->ram = "4G"; break;
132
+ default: info->ram = "Unknown"; break;
98
133
  }
99
134
  } else {
100
135
  // old scheme
@@ -104,88 +139,105 @@ int get_rpi_info(rpi_info *info)
104
139
  info->type = "Unknown";
105
140
  strcpy(info->revision, revision);
106
141
 
107
- // get last four characters (ignore preceeding 1000 for overvolt)
108
- if (len > 4)
109
- rev = (char *)&revision+len-4;
110
- else
111
- rev = revision;
142
+ uint64_t rev;
143
+ sscanf(revision, "%llx", &rev);
144
+ rev = rev & 0xefffffff; // ignore preceeding 1000 for overvolt
112
145
 
113
- if ((strcmp(rev, "0002") == 0) ||
114
- (strcmp(rev, "0003") == 0)) {
146
+ if (rev == 0x0002 || rev == 0x0003) {
115
147
  info->type = "Model B";
116
148
  info->p1_revision = 1;
117
149
  info->ram = "256M";
150
+ info->manufacturer = "Egoman";
118
151
  info->processor = "BCM2835";
119
- } else if (strcmp(rev, "0004") == 0) {
152
+ } else if (rev == 0x0004) {
120
153
  info->type = "Model B";
121
154
  info->p1_revision = 2;
122
155
  info->ram = "256M";
123
- info->manufacturer = "Sony";
156
+ info->manufacturer = "Sony UK";
124
157
  info->processor = "BCM2835";
125
- } else if (strcmp(rev, "0005") == 0) {
158
+ } else if (rev == 0x0005) {
126
159
  info->type = "Model B";
127
160
  info->p1_revision = 2;
128
161
  info->ram = "256M";
129
162
  info->manufacturer = "Qisda";
130
163
  info->processor = "BCM2835";
131
- } else if (strcmp(rev, "0006") == 0) {
164
+ } else if (rev == 0x0006) {
132
165
  info->type = "Model B";
133
166
  info->p1_revision = 2;
134
167
  info->ram = "256M";
135
168
  info->manufacturer = "Egoman";
136
169
  info->processor = "BCM2835";
137
- } else if (strcmp(rev, "0007") == 0) {
170
+ } else if (rev == 0x0007) {
138
171
  info->type = "Model A";
139
172
  info->p1_revision = 2;
140
173
  info->ram = "256M";
141
174
  info->manufacturer = "Egoman";
142
175
  info->processor = "BCM2835";
143
- } else if (strcmp(rev, "0008") == 0) {
176
+ } else if (rev == 0x0008) {
144
177
  info->type = "Model A";
145
178
  info->p1_revision = 2;
146
179
  info->ram = "256M";
147
- info->manufacturer = "Sony";
180
+ info->manufacturer = "Sony UK";
148
181
  info->processor = "BCM2835";
149
- } else if (strcmp(rev, "0009") == 0) {
182
+ } else if (rev == 0x0009) {
150
183
  info->type = "Model A";
151
184
  info->p1_revision = 2;
152
185
  info->ram = "256M";
153
186
  info->manufacturer = "Qisda";
154
187
  info->processor = "BCM2835";
155
- } else if (strcmp(rev, "000d") == 0) {
188
+ } else if (rev == 0x000d) {
156
189
  info->type = "Model B";
157
190
  info->p1_revision = 2;
158
191
  info->ram = "512M";
159
192
  info->manufacturer = "Egoman";
160
193
  info->processor = "BCM2835";
161
- } else if (strcmp(rev, "000e") == 0) {
194
+ } else if (rev == 0x000e) {
162
195
  info->type = "Model B";
163
196
  info->p1_revision = 2;
164
197
  info->ram = "512M";
165
- info->manufacturer = "Sony";
198
+ info->manufacturer = "Sony UK";
166
199
  info->processor = "BCM2835";
167
- } else if (strcmp(rev, "000f") == 0) {
200
+ } else if (rev == 0x000f) {
168
201
  info->type = "Model B";
169
202
  info->p1_revision = 2;
170
203
  info->ram = "512M";
171
204
  info->manufacturer = "Qisda";
172
205
  info->processor = "BCM2835";
173
- } else if ((strcmp(rev, "0011") == 0) ||
174
- (strcmp(rev, "0014") == 0)) {
175
- info->type = "Compute Module";
206
+ } else if (rev == 0x0010) {
207
+ info->type = "Model B+";
208
+ info->p1_revision = 3;
209
+ info->ram = "512M";
210
+ info->manufacturer = "Sony UK";
211
+ info->processor = "BCM2835";
212
+ } else if (rev == 0x0011) {
213
+ info->type = "Compute Module 1";
176
214
  info->p1_revision = 0;
177
215
  info->ram = "512M";
216
+ info->manufacturer = "Sony UK";
178
217
  info->processor = "BCM2835";
179
- } else if (strcmp(rev, "0012") == 0) {
218
+ } else if (rev == 0x0012) {
180
219
  info->type = "Model A+";
181
220
  info->p1_revision = 3;
182
221
  info->ram = "256M";
222
+ info->manufacturer = "Sony UK";
183
223
  info->processor = "BCM2835";
184
- } else if ((strcmp(rev, "0010") == 0) ||
185
- (strcmp(rev, "0013") == 0)) {
224
+ } else if (rev == 0x0013) {
186
225
  info->type = "Model B+";
187
226
  info->p1_revision = 3;
188
227
  info->ram = "512M";
228
+ info->manufacturer = "Embest";
229
+ info->processor = "BCM2835";
230
+ } else if (rev == 0x0014) {
231
+ info->type = "Compute Module 1";
232
+ info->p1_revision = 0;
233
+ info->ram = "512M";
234
+ info->manufacturer = "Embest";
235
+ info->processor = "BCM2835";
236
+ } else if (rev == 0x0015) {
237
+ info->type = "Model A+";
238
+ info->p1_revision = 3;
239
+ info->ram = "Unknown";
240
+ info->manufacturer = "Embest";
189
241
  info->processor = "BCM2835";
190
242
  } else { // don't know - assume revision 3 p1 connector
191
243
  info->p1_revision = 3;
@@ -3,7 +3,7 @@ Original code by Ben Croston modified for Ruby by Nick Lowery
3
3
  (github.com/clockvapor)
4
4
  Copyright (c) 2014-2016 Nick Lowery
5
5
 
6
- Copyright (c) 2013-2016 Ben Croston
6
+ Copyright (c) 2012-2015 Ben Croston
7
7
 
8
8
  Permission is hereby granted, free of charge, to any person obtaining a copy of
9
9
  this software and associated documentation files (the "Software"), to deal in
@@ -1,9 +1,9 @@
1
1
  /*
2
2
  Original code by Ben Croston modified for Ruby by Nick Lowery
3
3
  (github.com/clockvapor)
4
- Copyright (c) 2014-2016 Nick Lowery
4
+ Copyright (c) 2014-2020 Nick Lowery
5
5
 
6
- Copyright (c) 2013-2016 Ben Croston
6
+ Copyright (c) 2013-2018 Ben Croston
7
7
 
8
8
  Permission is hereby granted, free of charge, to any person obtaining a copy of
9
9
  this software and associated documentation files (the "Software"), to deal in
@@ -28,6 +28,7 @@ SOFTWARE.
28
28
  #include <sys/epoll.h>
29
29
  #include <stdio.h>
30
30
  #include <stdlib.h>
31
+ #include <errno.h>
31
32
  #include <fcntl.h>
32
33
  #include <unistd.h>
33
34
  #include <string.h>
@@ -67,16 +68,34 @@ int epfd_thread = -1;
67
68
  int epfd_blocking = -1;
68
69
 
69
70
  /************* /sys/class/gpio functions ************/
71
+ #define x_write(fd, buf, len) do { \
72
+ size_t x_write_len = (len); \
73
+ \
74
+ if ((size_t)write((fd), (buf), x_write_len) != x_write_len) { \
75
+ close(fd); \
76
+ return (-1); \
77
+ } \
78
+ } while (/* CONSTCOND */ 0)
79
+
70
80
  int gpio_export(unsigned int gpio)
71
81
  {
72
82
  int fd, len;
73
83
  char str_gpio[3];
84
+ char filename[33];
74
85
 
75
- if ((fd = open("/sys/class/gpio/export", O_WRONLY)) < 0)
86
+ snprintf(filename, sizeof(filename), "/sys/class/gpio/gpio%d", gpio);
87
+
88
+ /* return if gpio already exported */
89
+ if (access(filename, F_OK) != -1) {
90
+ return 0;
91
+ }
92
+
93
+ if ((fd = open("/sys/class/gpio/export", O_WRONLY)) < 0) {
76
94
  return -1;
95
+ }
77
96
 
78
97
  len = snprintf(str_gpio, sizeof(str_gpio), "%d", gpio);
79
- write(fd, str_gpio, len);
98
+ x_write(fd, str_gpio, len);
80
99
  close(fd);
81
100
 
82
101
  return 0;
@@ -91,7 +110,7 @@ int gpio_unexport(unsigned int gpio)
91
110
  return -1;
92
111
 
93
112
  len = snprintf(str_gpio, sizeof(str_gpio), "%d", gpio);
94
- write(fd, str_gpio, len);
113
+ x_write(fd, str_gpio, len);
95
114
  close(fd);
96
115
 
97
116
  return 0;
@@ -114,15 +133,13 @@ int gpio_set_direction(unsigned int gpio, unsigned int in_flag)
114
133
  break;
115
134
  nanosleep(&delay, NULL);
116
135
  }
117
- if (retry >= 100) {
136
+ if (retry >= 100)
118
137
  return -1;
119
- }
120
138
 
121
- if (in_flag) {
122
- write(fd, "in", 3);
123
- } else {
124
- write(fd, "out", 4);
125
- }
139
+ if (in_flag)
140
+ x_write(fd, "in", 3);
141
+ else
142
+ x_write(fd, "out", 4);
126
143
 
127
144
  close(fd);
128
145
  return 0;
@@ -138,7 +155,7 @@ int gpio_set_edge(unsigned int gpio, unsigned int edge)
138
155
  if ((fd = open(filename, O_WRONLY)) < 0)
139
156
  return -1;
140
157
 
141
- write(fd, stredge[edge], strlen(stredge[edge]) + 1);
158
+ x_write(fd, stredge[edge], strlen(stredge[edge]) + 1);
142
159
  close(fd);
143
160
  return 0;
144
161
  }
@@ -223,7 +240,6 @@ struct gpios *new_gpio(unsigned int gpio)
223
240
  void delete_gpio(unsigned int gpio)
224
241
  {
225
242
  struct gpios *g = gpio_list;
226
- struct gpios *temp;
227
243
  struct gpios *prev = NULL;
228
244
 
229
245
  while (g != NULL) {
@@ -232,9 +248,7 @@ void delete_gpio(unsigned int gpio)
232
248
  gpio_list = g->next;
233
249
  else
234
250
  prev->next = g->next;
235
- temp = g;
236
- g = g->next;
237
- free(temp);
251
+ free(g);
238
252
  return;
239
253
  } else {
240
254
  prev = g;
@@ -337,10 +351,7 @@ void *poll_thread(void *threadarg)
337
351
 
338
352
  thread_running = 1;
339
353
  while (thread_running) {
340
- if ((n = epoll_wait(epfd_thread, &events, 1, -1)) == -1) {
341
- thread_running = 0;
342
- pthread_exit(NULL);
343
- }
354
+ n = epoll_wait(epfd_thread, &events, 1, -1);
344
355
  if (n > 0) {
345
356
  lseek(events.data.fd, 0, SEEK_SET);
346
357
  if (read(events.data.fd, &buf, 1) != 1) {
@@ -353,12 +364,21 @@ void *poll_thread(void *threadarg)
353
364
  } else {
354
365
  gettimeofday(&tv_timenow, NULL);
355
366
  timenow = tv_timenow.tv_sec*1E6 + tv_timenow.tv_usec;
356
- if (g->bouncetime == -666 || timenow - g->lastcall > g->bouncetime*1000 || g->lastcall == 0 || g->lastcall > timenow) {
367
+ if (g->bouncetime == -666 || timenow - g->lastcall > (unsigned int)g->bouncetime*1000 || g->lastcall == 0 || g->lastcall > timenow) {
357
368
  g->lastcall = timenow;
358
369
  event_occurred[g->gpio] = 1;
359
370
  run_callbacks(g->gpio);
360
371
  }
361
372
  }
373
+ } else if (n == -1) {
374
+ /* If a signal is received while we are waiting,
375
+ epoll_wait will return with an EINTR error.
376
+ Just try again in that case. */
377
+ if (errno == EINTR) {
378
+ continue;
379
+ }
380
+ thread_running = 0;
381
+ pthread_exit(NULL);
362
382
  }
363
383
  }
364
384
  thread_running = 0;
@@ -406,26 +426,29 @@ int event_detected(unsigned int gpio)
406
426
  }
407
427
  }
408
428
 
409
- void event_cleanup(unsigned int gpio)
429
+ void event_cleanup(int gpio)
410
430
  // gpio of -666 means clean every channel used
411
431
  {
412
432
  struct gpios *g = gpio_list;
413
- struct gpios *temp = NULL;
433
+ struct gpios *next_gpio = NULL;
414
434
 
415
435
  while (g != NULL) {
416
- if ((gpio == -666) || (g->gpio == gpio))
417
- temp = g->next;
436
+ next_gpio = g->next;
437
+ if ((gpio == -666) || ((int)g->gpio == gpio))
418
438
  remove_edge_detect(g->gpio);
419
- g = temp;
439
+ g = next_gpio;
420
440
  }
421
- if (gpio_list == NULL)
422
- if (epfd_blocking != -1)
441
+ if (gpio_list == NULL) {
442
+ if (epfd_blocking != -1) {
423
443
  close(epfd_blocking);
424
444
  epfd_blocking = -1;
425
- if (epfd_thread != -1)
445
+ }
446
+ if (epfd_thread != -1) {
426
447
  close(epfd_thread);
427
448
  epfd_thread = -1;
449
+ }
428
450
  thread_running = 0;
451
+ }
429
452
  }
430
453
 
431
454
  void event_cleanup_all(void)
@@ -447,13 +470,14 @@ int add_edge_detect(unsigned int gpio, unsigned int edge, int bouncetime)
447
470
 
448
471
  i = gpio_event_added(gpio);
449
472
  if (i == 0) { // event not already added
450
- if ((g = new_gpio(gpio)) == NULL)
473
+ if ((g = new_gpio(gpio)) == NULL) {
451
474
  return 2;
475
+ }
452
476
 
453
477
  gpio_set_edge(gpio, edge);
454
478
  g->edge = edge;
455
479
  g->bouncetime = bouncetime;
456
- } else if (i == edge) { // get existing event
480
+ } else if (i == (int)edge) { // get existing event
457
481
  g = get_gpio(gpio);
458
482
  if ((bouncetime != -666 && g->bouncetime != bouncetime) || // different event bouncetime used
459
483
  (g->thread_added)) // event already added
@@ -501,13 +525,12 @@ int blocking_wait_for_edge(unsigned int gpio, unsigned int edge, int bouncetime,
501
525
  int finished = 0;
502
526
  int initial_edge = 1;
503
527
 
504
- if (callback_exists(gpio)) {
528
+ if (callback_exists(gpio))
505
529
  return -1;
506
- }
507
530
 
508
531
  // add gpio if it has not been added already
509
532
  ed = gpio_event_added(gpio);
510
- if (ed == edge) { // get existing record
533
+ if (ed == (int)edge) { // get existing record
511
534
  g = get_gpio(gpio);
512
535
  if (g->bouncetime != -666 && g->bouncetime != bouncetime) {
513
536
  return -1;
@@ -541,16 +564,23 @@ int blocking_wait_for_edge(unsigned int gpio, unsigned int edge, int bouncetime,
541
564
 
542
565
  // wait for edge
543
566
  while (!finished) {
544
- if ((n = epoll_wait(epfd_blocking, &events, 1, timeout)) == -1) {
567
+ n = epoll_wait(epfd_blocking, &events, 1, timeout);
568
+ if (n == -1) {
569
+ /* If a signal is received while we are waiting,
570
+ epoll_wait will return with an EINTR error.
571
+ Just try again in that case. */
572
+ if (errno == EINTR) {
573
+ continue;
574
+ }
545
575
  epoll_ctl(epfd_blocking, EPOLL_CTL_DEL, g->value_fd, &ev);
546
576
  return -2;
547
577
  }
548
- if (initial_edge) { // first time triggers with current state, so ignore
578
+ if (initial_edge) { // first time triggers with current state, so ignore
549
579
  initial_edge = 0;
550
580
  } else {
551
581
  gettimeofday(&tv_timenow, NULL);
552
582
  timenow = tv_timenow.tv_sec*1E6 + tv_timenow.tv_usec;
553
- if (g->bouncetime == -666 || timenow - g->lastcall > g->bouncetime*1000 || g->lastcall == 0 || g->lastcall > timenow) {
583
+ if (g->bouncetime == -666 || timenow - g->lastcall > (unsigned int)g->bouncetime*1000 || g->lastcall == 0 || g->lastcall > timenow) {
554
584
  g->lastcall = timenow;
555
585
  finished = 1;
556
586
  }