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