PX4 Firmware
PX4 Autopilot Software http://px4.io
linux_gpio.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2016 - 2017 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 #include "linux_gpio.h"
35 
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <fcntl.h>
39 #include <errno.h>
40 #include <string.h>
41 #include <stdlib.h>
42 
43 #include <px4_platform_common/posix.h>
44 
45 #define PIN_INDEX_BUFFER_MAX (16)
46 #define PIN_DIRECTION_BUFFER_MAX (30 + PIN_INDEX_BUFFER_MAX)
47 #define PIN_VALUE_BUFFER_MAX (26 + PIN_INDEX_BUFFER_MAX)
48 
49 LinuxGPIO::LinuxGPIO(unsigned int pin)
50  : _pin(pin)
51  , _fd(-1)
52 {
53 }
54 
56 {
57  if (_fd != -1) {
58  close(_fd);
59  }
60 }
61 
63 {
64  int ret;
65  char pinIndex[PIN_INDEX_BUFFER_MAX];
66  char valuePath[PIN_VALUE_BUFFER_MAX];
67  int fd = -1;
68  int bytes_to_write;
69 
70  struct stat statbuf;
71 
72  /* If GPIO was already opened, close it */
73  if (_fd != -1) {
74  close(_fd);
75  _fd = -1;
76  }
77 
78  /* Check if GPIO is already exported */
79  snprintf(valuePath, PIN_VALUE_BUFFER_MAX, "/sys/class/gpio/gpio%d/value", _pin);
80  ret = stat(valuePath, &statbuf);
81 
82  if (ret == -1) {
83  /* GPIO is not exported */
84  fd = open("/sys/class/gpio/export", O_WRONLY);
85 
86  if (fd == -1) {
87  int err = errno;
88  PX4_ERR("export %u: open: %s (%d)", _pin, strerror(err), err);
89  return -1;
90  }
91 
92  bytes_to_write = snprintf(pinIndex, PIN_INDEX_BUFFER_MAX, "%u", _pin);
93  ret = write(fd, pinIndex, bytes_to_write);
94 
95  if (ret == -1) {
96  int err = errno;
97  PX4_ERR("export %u: write: %s (%d)", _pin, strerror(err), err);
98  goto cleanup;
99 
100  } else if (ret != bytes_to_write) {
101  PX4_ERR("export %u: write incomplete %d != %d", _pin, ret, bytes_to_write);
102  goto cleanup;
103  }
104  }
105 
106  _fd = open(valuePath, O_RDWR);
107 
108  if (_fd == -1) {
109  int err = errno;
110  ret = -1;
111  PX4_ERR("export %u: open: %s (%d)", _pin, strerror(err), err);
112  goto cleanup;
113  }
114 
115  ret = 0;
116 
117 cleanup:
118 
119  if (fd != -1) {
120  close(fd);
121  }
122 
123  return ret;
124 }
125 
127 {
128  char pinIndex[PIN_INDEX_BUFFER_MAX];
129  int fd;
130  int ret;
131  int bytes_to_write;
132 
133  if (_fd != -1) {
134  close(_fd);
135  _fd = -1;
136  }
137 
138  fd = open("/sys/class/gpio/unexport", O_WRONLY);
139 
140  if (fd == -1) {
141  int err = errno;
142  PX4_ERR("unexport %u: open: %s (%d)", _pin, strerror(err), err);
143  return -1;
144  }
145 
146  bytes_to_write = snprintf(pinIndex, PIN_INDEX_BUFFER_MAX, "%u", _pin);
147  ret = write(fd, pinIndex, bytes_to_write);
148 
149  if (ret == -1) {
150  int err = errno;
151  PX4_ERR("unexport %u: write: %s (%d)", _pin, strerror(err), err);
152  goto cleanup;
153 
154  } else if (ret != bytes_to_write) {
155  PX4_ERR("unexport %u: write incomplete %d != %d", _pin, ret, bytes_to_write);
156  goto cleanup;
157  }
158 
159  ret = 0;
160 
161 cleanup:
162  close(fd);
163 
164  return ret;
165 }
166 
168 {
169  char path[PIN_DIRECTION_BUFFER_MAX];
170  int fd;
171  int ret;
172 
173  snprintf(path, PIN_DIRECTION_BUFFER_MAX, "/sys/class/gpio/gpio%d/direction", _pin);
174  fd = open(path, O_WRONLY);
175 
176  if (fd == -1) {
177  int err = errno;
178  PX4_ERR("dir %u: open: %s (%d)", _pin, strerror(err), err);
179  return -1;
180  }
181 
182  if (dir == Direction::IN) {
183  ret = write(fd, "in", 2);
184 
185  } else {
186  ret = write(fd, "out", 3);
187  }
188 
189  if (ret == -1) {
190  int err = errno;
191  PX4_ERR("dir %u: write: %s (%d)", _pin, strerror(err), err);
192  goto cleanup;
193  }
194 
195  ret = 0;
196 
197 cleanup:
198  close(fd);
199 
200  return ret;
201 }
202 
204 {
205  char buf[2];
206  int ret;
207 
208  ret = ::read(_fd, buf, sizeof(buf));
209 
210  if (ret == -1) {
211  int err = errno;
212  PX4_ERR("readValue %u: read: %s (%d)", _pin, strerror(err), err);
213  return ret;
214  }
215 
216  ret = strtol(buf, nullptr, 10);
217 
218  return ret;
219 }
220 
222 {
223  char buf[2];
224  int ret;
225 
226  if (value != Value::LOW && value != Value::HIGH) {
227  return -EINVAL;
228  }
229 
230  int buflen = snprintf(buf, sizeof(buf), "%u", (unsigned int)value);
231 
232  ret = ::write(_fd, buf, buflen);
233 
234  if (ret == -1) {
235  int err = errno;
236  PX4_ERR("writeValue %u: write: %s (%d)", _pin, strerror(err), err);
237  return ret;
238  }
239 
240  return 0;
241 }
int exportPin()
Definition: linux_gpio.cpp:62
int setDirection(LinuxGPIO::Direction dir)
Definition: linux_gpio.cpp:167
LinuxGPIO(unsigned int pin)
Definition: linux_gpio.cpp:49
#define PIN_INDEX_BUFFER_MAX
Definition: linux_gpio.cpp:45
Linux sysfs GPIO Interface.
static void read(bootloader_app_shared_t *pshared)
int _pin
Definition: linux_gpio.h:69
#define PIN_VALUE_BUFFER_MAX
Definition: linux_gpio.cpp:47
int readValue()
Definition: linux_gpio.cpp:203
int writeValue(LinuxGPIO::Value value)
Definition: linux_gpio.cpp:221
int fd
Definition: dataman.cpp:146
int unexportPin()
Definition: linux_gpio.cpp:126
#define err(eval,...)
Definition: err.h:83
static void write(bootloader_app_shared_t *pshared)
#define PIN_DIRECTION_BUFFER_MAX
Definition: linux_gpio.cpp:46