refactor(MP/daemon): use stack instead of heap for gpio
This commit is contained in:
@@ -29,9 +29,9 @@ void BTN_add_epoll_event(BTN* btn, int tail);
|
|||||||
void epoll_init();
|
void epoll_init();
|
||||||
static void* epoll_thread(void* arg);
|
static void* epoll_thread(void* arg);
|
||||||
|
|
||||||
BTN* BTN_init(BTN_type type) {
|
int BTN_init(BTN* btn, BTN_type type) {
|
||||||
BTN* btn = malloc(sizeof(BTN));
|
if (btn == NULL) return -1;
|
||||||
if (btn == NULL) return NULL;
|
|
||||||
pthread_mutex_init(&btn->mutex, NULL);
|
pthread_mutex_init(&btn->mutex, NULL);
|
||||||
btn->callback = NULL;
|
btn->callback = NULL;
|
||||||
|
|
||||||
@@ -48,15 +48,18 @@ BTN* BTN_init(BTN_type type) {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Invalid button type\n");
|
printf("Invalid button type\n");
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
strcat(gpio_path, btn->pin);
|
strcat(gpio_path, btn->pin);
|
||||||
|
|
||||||
int f = open(GPIO_UNEXPORT, O_WRONLY);
|
int f = open(GPIO_UNEXPORT, O_WRONLY);
|
||||||
|
if (f != -1) {
|
||||||
write(f, btn->pin, strlen(btn->pin));
|
write(f, btn->pin, strlen(btn->pin));
|
||||||
close(f);
|
close(f);
|
||||||
|
}
|
||||||
|
|
||||||
f = open(GPIO_EXPORT, O_WRONLY);
|
f = open(GPIO_EXPORT, O_WRONLY);
|
||||||
|
if (f == -1) return -1;
|
||||||
write(f, btn->pin, strlen(btn->pin));
|
write(f, btn->pin, strlen(btn->pin));
|
||||||
close(f);
|
close(f);
|
||||||
|
|
||||||
@@ -65,6 +68,7 @@ BTN* BTN_init(BTN_type type) {
|
|||||||
strcat(direction_path, "/direction");
|
strcat(direction_path, "/direction");
|
||||||
|
|
||||||
f = open(direction_path, O_WRONLY);
|
f = open(direction_path, O_WRONLY);
|
||||||
|
if (f == -1) return -1;
|
||||||
write(f, "in", 2);
|
write(f, "in", 2);
|
||||||
close(f);
|
close(f);
|
||||||
|
|
||||||
@@ -73,7 +77,8 @@ BTN* BTN_init(BTN_type type) {
|
|||||||
strcat(edge_path, "/edge");
|
strcat(edge_path, "/edge");
|
||||||
|
|
||||||
f = open(edge_path, O_WRONLY);
|
f = open(edge_path, O_WRONLY);
|
||||||
write(f, "both", 4); // "both" means it triggers on press AND release
|
if (f == -1) return -1;
|
||||||
|
write(f, "both", 4);
|
||||||
close(f);
|
close(f);
|
||||||
|
|
||||||
char value_path[100];
|
char value_path[100];
|
||||||
@@ -83,7 +88,7 @@ BTN* BTN_init(BTN_type type) {
|
|||||||
f = open(value_path, O_RDONLY);
|
f = open(value_path, O_RDONLY);
|
||||||
if (f == -1) {
|
if (f == -1) {
|
||||||
printf("Failed to setup button on pin %s\n", btn->pin);
|
printf("Failed to setup button on pin %s\n", btn->pin);
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
btn->fd = f;
|
btn->fd = f;
|
||||||
|
|
||||||
@@ -96,7 +101,8 @@ BTN* BTN_init(BTN_type type) {
|
|||||||
if (tail >= MAX_BTN) {
|
if (tail >= MAX_BTN) {
|
||||||
pthread_mutex_unlock(&btn_list_mutex);
|
pthread_mutex_unlock(&btn_list_mutex);
|
||||||
perror("Failed to add epoll event");
|
perror("Failed to add epoll event");
|
||||||
exit(EXIT_FAILURE);
|
close(btn->fd);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
btn_list[tail] = btn;
|
btn_list[tail] = btn;
|
||||||
@@ -106,7 +112,18 @@ BTN* BTN_init(BTN_type type) {
|
|||||||
BTN_add_epoll_event(btn, tail);
|
BTN_add_epoll_event(btn, tail);
|
||||||
pthread_mutex_unlock(&btn_list_mutex);
|
pthread_mutex_unlock(&btn_list_mutex);
|
||||||
|
|
||||||
return btn;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BTN_deinit(BTN* btn) {
|
||||||
|
if (btn == NULL) return;
|
||||||
|
pthread_mutex_lock(&btn->mutex);
|
||||||
|
if (btn->fd != -1) {
|
||||||
|
close(btn->fd);
|
||||||
|
btn->fd = -1;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&btn->mutex);
|
||||||
|
pthread_mutex_destroy(&btn->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BTN_set_callback(BTN* btn, BTN_callback callback) {
|
void BTN_set_callback(BTN* btn, BTN_callback callback) {
|
||||||
@@ -121,7 +138,7 @@ void BTN_add_epoll_event(BTN* btn, int tail) {
|
|||||||
// EPOLLERR is used to detect if there is an error
|
// EPOLLERR is used to detect if there is an error
|
||||||
// EPOLLET is for edge triggered mode (non-blocking)
|
// EPOLLET is for edge triggered mode (non-blocking)
|
||||||
ev[tail].events = EPOLLIN | EPOLLERR | EPOLLET;
|
ev[tail].events = EPOLLIN | EPOLLERR | EPOLLET;
|
||||||
ev[tail].data.fd = btn->fd;
|
ev[tail].data.ptr = btn;
|
||||||
|
|
||||||
int ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, btn->fd, &ev[tail]);
|
int ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, btn->fd, &ev[tail]);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -154,29 +171,20 @@ static void* epoll_thread(void* arg) {
|
|||||||
}
|
}
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
char buf[2];
|
char buf[2];
|
||||||
int fd = events[i].data.fd;
|
BTN* btn = (BTN*)events[i].data.ptr;
|
||||||
int tail = -1;
|
if (btn == NULL) continue;
|
||||||
BTN* btn = NULL;
|
|
||||||
for (int j = 0; j < MAX_BTN; j++) {
|
pthread_mutex_lock(&btn->mutex);
|
||||||
if (btn_list[j] == NULL) continue;
|
if (btn->fd != -1) {
|
||||||
if (btn_list[j]->fd == fd) {
|
|
||||||
tail = j;
|
|
||||||
btn = btn_list[j];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (tail == -1) {
|
|
||||||
printf("No button found for fd %d\n", fd);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
pread(btn->fd, buf, sizeof(buf), 0);
|
pread(btn->fd, buf, sizeof(buf), 0);
|
||||||
if (buf[0] == '1') {
|
if (buf[0] == '1') {
|
||||||
// printf("Button %s pressed\n", btn->pin);
|
|
||||||
if (btn->callback != NULL) {
|
if (btn->callback != NULL) {
|
||||||
btn->callback();
|
btn->callback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pthread_mutex_unlock(&btn->mutex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ typedef struct {
|
|||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
} BTN;
|
} BTN;
|
||||||
|
|
||||||
BTN* BTN_init(BTN_type type);
|
int BTN_init(BTN* btn, BTN_type type);
|
||||||
|
void BTN_deinit(BTN* btn);
|
||||||
void BTN_set_callback(BTN* btn, BTN_callback callback);
|
void BTN_set_callback(BTN* btn, BTN_callback callback);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -16,9 +16,8 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
LED* LED_init(LED_type type) {
|
int LED_init(LED* led, LED_type type) {
|
||||||
LED* led = malloc(sizeof(LED));
|
if (led == NULL) return -1;
|
||||||
if (led == NULL) return NULL;
|
|
||||||
|
|
||||||
// Concatenate GPIO LED path based on type
|
// Concatenate GPIO LED path based on type
|
||||||
char gpio_path[32] = GPIO_LED_BASE;
|
char gpio_path[32] = GPIO_LED_BASE;
|
||||||
@@ -32,7 +31,7 @@ LED* LED_init(LED_type type) {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Invalid LED type\n");
|
printf("Invalid LED type\n");
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
strcat(gpio_path, pin);
|
strcat(gpio_path, pin);
|
||||||
|
|
||||||
@@ -63,15 +62,15 @@ LED* LED_init(LED_type type) {
|
|||||||
f = open(value_path, O_RDWR);
|
f = open(value_path, O_RDWR);
|
||||||
if (f == -1) {
|
if (f == -1) {
|
||||||
printf("Failed to setup led on pin %s\n", pin);
|
printf("Failed to setup led on pin %s\n", pin);
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
led->gpio = f;
|
led->gpio = f;
|
||||||
if (pthread_mutex_init(&led->mutex, NULL) != 0) {
|
if (pthread_mutex_init(&led->mutex, NULL) != 0) {
|
||||||
close(f);
|
close(f);
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
return led;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LED_on(LED* led) {
|
void LED_on(LED* led) {
|
||||||
@@ -100,8 +99,17 @@ void LED_toggle(LED* led) {
|
|||||||
char value[2];
|
char value[2];
|
||||||
pread(led->gpio, value, sizeof(value), 0);
|
pread(led->gpio, value, sizeof(value), 0);
|
||||||
if (value[0] == '0') {
|
if (value[0] == '0') {
|
||||||
LED_on(led);
|
pwrite(led->gpio, "1", sizeof("1"), 0);
|
||||||
} else {
|
} else {
|
||||||
LED_off(led);
|
pwrite(led->gpio, "0", sizeof("0"), 0);
|
||||||
}
|
}
|
||||||
|
pthread_mutex_unlock(&led->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LED_deinit(LED* led) {
|
||||||
|
if (led == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pthread_mutex_destroy(&led->mutex);
|
||||||
|
close(led->gpio);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,10 @@ typedef struct {
|
|||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
} LED;
|
} LED;
|
||||||
|
|
||||||
LED* LED_init(LED_type type);
|
int LED_init(LED* led, LED_type type);
|
||||||
void LED_on(LED* led);
|
void LED_on(LED* led);
|
||||||
void LED_off(LED* led);
|
void LED_off(LED* led);
|
||||||
void LED_toggle(LED* led);
|
void LED_toggle(LED* led);
|
||||||
|
void LED_deinit(LED* led);
|
||||||
|
|
||||||
#endif //LED_H
|
#endif //LED_H
|
||||||
|
|||||||
@@ -21,17 +21,30 @@
|
|||||||
|
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
BTN btn_inc, btn_dec, btn_mode;
|
||||||
|
|
||||||
|
if (BTN_init(&btn_inc, BTN_INCREASE) != 0) {
|
||||||
|
fprintf(stderr, "Failed to initialize increase button\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (BTN_init(&btn_dec, BTN_DECREASE) != 0) {
|
||||||
|
fprintf(stderr, "Failed to initialize decrease button\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (BTN_init(&btn_mode, BTN_MODE) != 0) {
|
||||||
|
fprintf(stderr, "Failed to initialize mode button\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
BTN* btn_inc = BTN_init(BTN_INCREASE);
|
LED led_power;
|
||||||
BTN* btn_dec = BTN_init(BTN_DECREASE);
|
if (LED_init(&led_power, LED_POWER) != 0) {
|
||||||
BTN* btn_mode = BTN_init(BTN_MODE);
|
fprintf(stderr, "Failed to initialize power LED\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
LED* led_power = LED_init(LED_POWER);
|
BTN_set_callback(&btn_inc, btn_increase_period);
|
||||||
|
BTN_set_callback(&btn_dec, btn_decrease_period);
|
||||||
BTN_set_callback(btn_inc, btn_increase_period);
|
BTN_set_callback(&btn_mode, mode_toggle);
|
||||||
BTN_set_callback(btn_dec, btn_decrease_period);
|
|
||||||
BTN_set_callback(btn_mode, mode_toggle);
|
|
||||||
|
|
||||||
struct ipc_callbacks_t ipc_cbs = {
|
struct ipc_callbacks_t ipc_cbs = {
|
||||||
.on_dec_period = decrease_period,
|
.on_dec_period = decrease_period,
|
||||||
@@ -54,7 +67,7 @@ int main(void) {
|
|||||||
|
|
||||||
init_oled(&oled_cbs);
|
init_oled(&oled_cbs);
|
||||||
|
|
||||||
btn_set_led(led_power);
|
btn_set_led(&led_power);
|
||||||
init_animations();
|
init_animations();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -62,5 +75,9 @@ int main(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stop_ipc_server();
|
stop_ipc_server();
|
||||||
|
LED_deinit(&led_power);
|
||||||
|
BTN_deinit(&btn_inc);
|
||||||
|
BTN_deinit(&btn_dec);
|
||||||
|
BTN_deinit(&btn_mode);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user