mirror of
https://github.com/vsergeev/c-periphery.git
synced 2026-10-06 04:59:26 +08:00
gpio: add gpio_new()/gpio_free() for handle memory management
This commit is contained in:
+36
-11
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user