Skip to content

Commit

Permalink
add system call gpio to irq
Browse files Browse the repository at this point in the history
  • Loading branch information
OtnaelRochaSilva committed Dec 14, 2024
1 parent f2dd55c commit 66be854
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 1 deletion.
1 change: 1 addition & 0 deletions arch/arm/tools/syscall.tbl
Original file line number Diff line number Diff line change
Expand Up @@ -467,3 +467,4 @@
451 common cachestat sys_cachestat
452 common fchmodat2 sys_fchmodat2
453 common listProcessInfo sys_listProcessInfo
454 common set_gpio_irq sys_set_gpio_irq
18 changes: 18 additions & 0 deletions gpio_irq/gpio_irq_handler.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/workqueue.h>
#include "gpio_irq_handler.h"

static DECLARE_WORK(gpio_t, gpio_irq_task);
int gpio_irq_id;

static irqreturn_t gpio_irq_handler(int irq, void *dev_id){
schedule_work(&gpio_t);
return IRQ_HANDLED;
}

static void gpio_irq_task( struct work_struct *work){
printk(KERN_INFO "Interrupção no Gpio %d detectada!\n", gpio_irq_id);
//aqui vamos colocar o restante do código para tratar a interrupção como por exemplo
//iniciar a comunicação i2c, ou gravar um registro no mariadb e printar na tela para o usuário.
}
14 changes: 14 additions & 0 deletions gpio_irq/gpio_irq_handler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef _GPIO_INTERRUPT_HANDLER_H_
#define _GPIO_INTERRUPT_HANDLER_H_

// include para usarmos os recursos preexistentes
// no kernel para tratamento de interrupções
#include <linux/interrupt.h>

// Vai possibilitar a mudança dinâmica de pinos de interrupção
extern int gpio_irq_id;

irqreturn_t gpio_irq_handler(int irq, void *dev_id);

#endif

1 change: 1 addition & 0 deletions include/linux/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -1279,3 +1279,4 @@ int __sys_setsockopt(int fd, int level, int optname, char __user *optval,
int optlen);
#endif
asmlinkage long sys_listProcessInfo(long pid, const char __user *buf, int size);
asmlinkage long sys_set_gpio_irq(int gpio, bool enable=1);
5 changes: 4 additions & 1 deletion syscall/Makefile
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
obj-y:=processInfo.o
# Lista de arquivos objetos a serem compilados
obj-y:= \
processInfo.o # obtem detalhes de um determinado processo em execução
set_gpio_irq.o #habilita/desabilita para um gpio uma irq
43 changes: 43 additions & 0 deletions syscall/set_gpio_irq.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/interrupt.h>
#include "set_gpio_irq.h"
#include "gpio_irq/gpio_irq_handler.h"

//armazenará o último gpio vinculado a irq,
//posteriormente podemos pensar nisto como uma lista
static int gpio_irq_id = -1;

asmlinkage long sys_set_gpio_irq(int gpio, bool enable=1){

if (gpio < 0){
printk(KERN_WARNING "Gpio inválido '%d' digite um valor >= 0!\n", gpio)
return -EINVAL
}

if (enable){

if(gpio_irq_id != -1){
//libera os recursos,
//antes de habilitar novamente o irq para gpio
free_irq(gpio_irq_id, NULL)
}

int result_req_irq = request_irq(gpio, gpio_irq_handler, IRQF_TRIGGER_RISING, "Telemetria_Gpio_IRQ", NULL);
if (result_req_irq){
printk(KERN_ERR "Falha ao requisitar irq: %d\n", result_req_irq);
return -EIO;
}
gpio_irq_id = gpio

} else {
if (gpio_irq_id != -1){
free_irq(gpio_irq_id, NULL);
gpio_irq_id = -1;
}
}

return 0;
}

6 changes: 6 additions & 0 deletions syscall/set_gpio_irq.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef _SET_GPIO_IRQ_
#define _SET_GPIO_IRQ_

asmlinkage long sys_set_gpio_irq(int gpio, bool enable=1);

#endif

0 comments on commit 66be854

Please sign in to comment.