gpio: add gpio_new()/gpio_free() for handle memory management

This commit is contained in:
Vanya A. Sergeev
2019-09-28 23:01:39 -05:00
parent 06d52157ab
commit e412d5cc3f
4 changed files with 152 additions and 84 deletions
+36 -11
View File
@@ -8,11 +8,13 @@ GPIO wrapper functions for Linux userspace sysfs GPIOs.
#include <periphery/gpio.md>
/* Primary Functions */
gpio_t *gpio_new(void);
int gpio_open(gpio_t *gpio, unsigned int pin, gpio_direction_t direction);
int gpio_read(gpio_t *gpio, bool *value);
int gpio_write(gpio_t *gpio, bool value);
int gpio_poll(gpio_t *gpio, int timeout_ms);
int gpio_close(gpio_t *gpio);
void gpio_free(gpio_t *gpio);
/* Getters */
int gpio_supports_interrupts(gpio_t *gpio, bool *supported);
@@ -50,6 +52,15 @@ const char *gpio_errmsg(gpio_t *gpio);
### DESCRIPTION
``` c
gpio_t *gpio_new(void);
```
Allocate a GPIO handle.
Returns a valid handle on success, or NULL on failure.
------
``` c
int gpio_open(gpio_t *gpio, unsigned int pin, gpio_direction_t direction);
```
@@ -105,6 +116,13 @@ Returns 0 on success, or a negative [GPIO error code](#return-value) on failure.
------
``` c
void gpio_free(gpio_t *gpio);
```
Free a GPIO handle.
------
```c
int gpio_supports_interrupts(gpio_t *gpio, bool *supported);
```
@@ -221,35 +239,42 @@ The libc errno of the failure in an underlying libc library call can be obtained
#include "gpio.h"
int main(void) {
gpio_t gpio_in, gpio_out;
gpio_t *gpio_in, *gpio_out;
bool value;
gpio_in = gpio_new();
gpio_out = gpio_new();
/* Open GPIO 10 with input direction */
if (gpio_open(&gpio_in, 10, GPIO_DIR_IN) < 0) {
fprintf(stderr, "gpio_open(): %s\n", gpio_errmsg(&gpio_in));
if (gpio_open(gpio_in, 10, GPIO_DIR_IN) < 0) {
fprintf(stderr, "gpio_open(): %s\n", gpio_errmsg(gpio_in));
exit(1);
}
/* Open GPIO 12 with output direction */
if (gpio_open(&gpio_out, 12, GPIO_DIR_OUT) < 0) {
fprintf(stderr, "gpio_open(): %s\n", gpio_errmsg(&gpio_out));
if (gpio_open(gpio_out, 12, GPIO_DIR_OUT) < 0) {
fprintf(stderr, "gpio_open(): %s\n", gpio_errmsg(gpio_out));
exit(1);
}
/* Read input GPIO into value */
if (gpio_read(&gpio_in, &value) < 0) {
fprintf(stderr, "gpio_read(): %s\n", gpio_errmsg(&gpio_in));
if (gpio_read(gpio_in, &value) < 0) {
fprintf(stderr, "gpio_read(): %s\n", gpio_errmsg(gpio_in));
exit(1);
}
/* Write output GPIO with !value */
if (gpio_write(&gpio_out, !value) < 0) {
fprintf(stderr, "gpio_write(): %s\n", gpio_errmsg(&gpio_out));
if (gpio_write(gpio_out, !value) < 0) {
fprintf(stderr, "gpio_write(): %s\n", gpio_errmsg(gpio_out));
exit(1);
}
gpio_close(&gpio_in);
gpio_close(&gpio_out);
gpio_close(gpio_in);
gpio_close(gpio_out);
gpio_free(gpio_in);
gpio_free(gpio_out);
return 0;
}
```
+20 -2
View File
@@ -39,7 +39,17 @@ static const char *gpio_edge_to_string[] = {
[GPIO_EDGE_BOTH] = "both",
};
static int _gpio_error(struct gpio_handle *gpio, int code, int c_errno, const char *fmt, ...) {
struct gpio_handle {
unsigned int pin;
int fd;
struct {
int c_errno;
char errmsg[96];
} error;
};
static int _gpio_error(gpio_t *gpio, int code, int c_errno, const char *fmt, ...) {
va_list ap;
gpio->error.c_errno = c_errno;
@@ -58,6 +68,14 @@ static int _gpio_error(struct gpio_handle *gpio, int code, int c_errno, const ch
return code;
}
gpio_t *gpio_new(void) {
return malloc(sizeof(gpio_t));
}
void gpio_free(gpio_t *gpio) {
free(gpio);
}
int gpio_open(gpio_t *gpio, unsigned int pin, gpio_direction_t direction) {
char gpio_path[P_PATH_MAX];
struct stat stat_buf;
@@ -113,7 +131,7 @@ int gpio_open(gpio_t *gpio, unsigned int pin, gpio_direction_t direction) {
return _gpio_error(gpio, GPIO_ERROR_SET_DIRECTION, errno, "Configuring GPIO: closing 'direction'");
}
memset(gpio, 0, sizeof(struct gpio_handle));
memset(gpio, 0, sizeof(gpio_t));
gpio->pin = pin;
/* Open value */
+4 -10
View File
@@ -26,16 +26,6 @@ enum gpio_error_code {
GPIO_ERROR_GET_EDGE = -9, /* Getting GPIO interrupt edge */
};
typedef struct gpio_handle {
unsigned int pin;
int fd;
struct {
int c_errno;
char errmsg[96];
} error;
} gpio_t;
typedef enum gpio_direction {
GPIO_DIR_IN, /* Input */
GPIO_DIR_OUT, /* Output, initialized to low */
@@ -51,12 +41,16 @@ typedef enum gpio_edge {
GPIO_EDGE_BOTH /* Both edges X -> !X */
} gpio_edge_t;
typedef struct gpio_handle gpio_t;
/* Primary Functions */
gpio_t *gpio_new(void);
int gpio_open(gpio_t *gpio, unsigned int pin, gpio_direction_t direction);
int gpio_read(gpio_t *gpio, bool *value);
int gpio_write(gpio_t *gpio, bool value);
int gpio_poll(gpio_t *gpio, int timeout_ms);
int gpio_close(gpio_t *gpio);
void gpio_free(gpio_t *gpio);
/* Getters */
int gpio_supports_interrupts(gpio_t *gpio, bool *supported);
+92 -61
View File
File diff suppressed because it is too large Load Diff