diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl index fbdcb7b9893873..e89a611626ce36 100644 --- a/arch/arm/tools/syscall.tbl +++ b/arch/arm/tools/syscall.tbl @@ -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 diff --git a/gpio_irq/gpio_irq_handler.c b/gpio_irq/gpio_irq_handler.c new file mode 100644 index 00000000000000..193316391e0165 --- /dev/null +++ b/gpio_irq/gpio_irq_handler.c @@ -0,0 +1,18 @@ +#include +#include +#include +#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. +} diff --git a/gpio_irq/gpio_irq_handler.h b/gpio_irq/gpio_irq_handler.h new file mode 100644 index 00000000000000..4eb247a6e1e1fd --- /dev/null +++ b/gpio_irq/gpio_irq_handler.h @@ -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 + +// 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 + diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 1b2536d6656b25..7f863e91ed2e1a 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -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); diff --git a/syscall/Makefile b/syscall/Makefile index 5493000b06404a..f1dbd4095482d3 100644 --- a/syscall/Makefile +++ b/syscall/Makefile @@ -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 diff --git a/syscall/set_gpio_irq.c b/syscall/set_gpio_irq.c new file mode 100644 index 00000000000000..dae7d2e65f744a --- /dev/null +++ b/syscall/set_gpio_irq.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#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; +} + diff --git a/syscall/set_gpio_irq.h b/syscall/set_gpio_irq.h new file mode 100644 index 00000000000000..53fa8a1aa21f4e --- /dev/null +++ b/syscall/set_gpio_irq.h @@ -0,0 +1,6 @@ +#ifndef _SET_GPIO_IRQ_ +#define _SET_GPIO_IRQ_ + +asmlinkage long sys_set_gpio_irq(int gpio, bool enable=1); + +#endif