1
0

fix(MP/daemon): add mutex on gpio

This commit is contained in:
2026-06-07 15:11:13 +02:00
parent ca5dd30872
commit 0f6502bf9b
4 changed files with 24 additions and 1 deletions

View File

@@ -18,6 +18,8 @@
#define MAX_BTN 10 #define MAX_BTN 10
BTN* btn_list[MAX_BTN]; BTN* btn_list[MAX_BTN];
pthread_mutex_t btn_list_mutex = PTHREAD_MUTEX_INITIALIZER;
int epoll_fd; int epoll_fd;
struct epoll_event ev[MAX_BTN]; struct epoll_event ev[MAX_BTN];
atomic_int btn_tail = 0; atomic_int btn_tail = 0;
@@ -30,6 +32,8 @@ static void* epoll_thread(void* arg);
BTN* BTN_init(BTN_type type) { BTN* BTN_init(BTN_type type) {
BTN* btn = malloc(sizeof(BTN)); BTN* btn = malloc(sizeof(BTN));
if (btn == NULL) return NULL; if (btn == NULL) return NULL;
pthread_mutex_init(&btn->mutex, NULL);
btn->callback = NULL;
char gpio_path[32] = GPIO_BTN_BASE; char gpio_path[32] = GPIO_BTN_BASE;
switch (type) { switch (type) {
@@ -87,8 +91,10 @@ BTN* BTN_init(BTN_type type) {
char buf[2]; char buf[2];
pread(btn->fd, buf, sizeof(buf), 0); pread(btn->fd, buf, sizeof(buf), 0);
pthread_mutex_lock(&btn_list_mutex);
int tail = atomic_fetch_add(&btn_tail, 1); int tail = atomic_fetch_add(&btn_tail, 1);
if (tail >= MAX_BTN) { if (tail >= MAX_BTN) {
pthread_mutex_unlock(&btn_list_mutex);
perror("Failed to add epoll event"); perror("Failed to add epoll event");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@@ -98,15 +104,17 @@ BTN* BTN_init(BTN_type type) {
epoll_init(); epoll_init();
} }
BTN_add_epoll_event(btn, tail); BTN_add_epoll_event(btn, tail);
pthread_mutex_unlock(&btn_list_mutex);
return btn; return btn;
} }
void BTN_set_callback(BTN* btn, BTN_callback callback) { void BTN_set_callback(BTN* btn, BTN_callback callback) {
pthread_mutex_lock(&btn->mutex);
btn->callback = callback; btn->callback = callback;
pthread_mutex_unlock(&btn->mutex);
} }
// TODO add mutex to protect this function
void BTN_add_epoll_event(BTN* btn, int tail) { void BTN_add_epoll_event(BTN* btn, int tail) {
// EPOLLIN is working well as EPOLLPRI (which is more used for priority data) // EPOLLIN is working well as EPOLLPRI (which is more used for priority data)

View File

@@ -1,6 +1,8 @@
#ifndef BUTTON_H #ifndef BUTTON_H
#define BUTTON_H #define BUTTON_H
#include <pthread.h>
#define GPIO_BTN_INCREASE "3" #define GPIO_BTN_INCREASE "3"
#define GPIO_BTN_DECREASE "0" #define GPIO_BTN_DECREASE "0"
#define GPIO_BTN_MODE "2" #define GPIO_BTN_MODE "2"
@@ -17,6 +19,7 @@ typedef struct {
int fd; int fd;
char pin[32]; char pin[32];
BTN_callback callback; BTN_callback callback;
pthread_mutex_t mutex;
} BTN; } BTN;
BTN* BTN_init(BTN_type type); BTN* BTN_init(BTN_type type);

View File

@@ -67,6 +67,10 @@ LED* LED_init(LED_type type) {
} }
led->gpio = f; led->gpio = f;
if (pthread_mutex_init(&led->mutex, NULL) != 0) {
close(f);
return NULL;
}
return led; return led;
} }
@@ -74,20 +78,25 @@ void LED_on(LED* led) {
if (led == NULL) { if (led == NULL) {
return; return;
} }
pthread_mutex_lock(&led->mutex);
pwrite(led->gpio, "1", sizeof("1"), 0); pwrite(led->gpio, "1", sizeof("1"), 0);
pthread_mutex_unlock(&led->mutex);
} }
void LED_off(LED* led) { void LED_off(LED* led) {
if (led == NULL) { if (led == NULL) {
return; return;
} }
pthread_mutex_lock(&led->mutex);
pwrite(led->gpio, "0", sizeof("0"), 0); pwrite(led->gpio, "0", sizeof("0"), 0);
pthread_mutex_unlock(&led->mutex);
} }
void LED_toggle(LED* led) { void LED_toggle(LED* led) {
if (led == NULL) { if (led == NULL) {
return; return;
} }
pthread_mutex_lock(&led->mutex);
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') {

View File

@@ -1,6 +1,8 @@
#ifndef LED_H #ifndef LED_H
#define LED_H #define LED_H
#include <pthread.h>
#define GPIO_LED_STATUS "10" #define GPIO_LED_STATUS "10"
#define GPIO_LED_POWER "362" #define GPIO_LED_POWER "362"
@@ -11,6 +13,7 @@ typedef enum {
typedef struct { typedef struct {
int gpio; int gpio;
pthread_mutex_t mutex;
} LED; } LED;
LED* LED_init(LED_type type); LED* LED_init(LED_type type);